Refactoring: Made NbtList and NbtCompound into generic interfaces.
Dieser Commit ist enthalten in:
Ursprung
749f006621
Commit
c2ea92ab37
@ -1,23 +1,5 @@
|
||||
/*
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2012 Kristian S. Stangeland
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
package com.comphenix.protocol.wrappers.nbt;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
@ -30,126 +12,26 @@ import java.util.Set;
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterable<NbtBase<?>> {
|
||||
// A list container
|
||||
private NbtElement<Map<String, Object>> container;
|
||||
|
||||
// Saved wrapper map
|
||||
private ConvertedMap<String, Object, NbtBase<?>> savedMap;
|
||||
|
||||
/**
|
||||
* Construct a new NBT compound wrapper.
|
||||
* @param name - the name of the wrapper.
|
||||
* @return The wrapped NBT compound.
|
||||
*/
|
||||
public static NbtCompound fromName(String name) {
|
||||
// Simplify things for the caller
|
||||
return (NbtCompound) NbtFactory.<Map<String, NbtBase<?>>>ofType(NbtType.TAG_COMPOUND, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new NBT compound wrapper initialized with a given list of NBT values.
|
||||
* @param name - the name of the compound wrapper.
|
||||
* @param list - the list of elements to add.
|
||||
* @return The new wrapped NBT compound.
|
||||
*/
|
||||
public static NbtCompound fromList(String name, Collection<? extends NbtBase<?>> list) {
|
||||
NbtCompound copy = fromName(name);
|
||||
|
||||
for (NbtBase<?> base : list)
|
||||
copy.getValue().put(base.getName(), base);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a wrapped compound from a given NMS handle.
|
||||
* @param handle - the NMS handle.
|
||||
*/
|
||||
NbtCompound(Object handle) {
|
||||
this.container = new NbtElement<Map<String,Object>>(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return container.getHandle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NbtType getType() {
|
||||
return NbtType.TAG_COMPOUND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return container.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
container.setName(name);
|
||||
}
|
||||
|
||||
public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<NbtBase<?>> {
|
||||
/**
|
||||
* Determine if an entry with the given key exists or not.
|
||||
* @param key - the key to lookup.
|
||||
* @return TRUE if an entry with the given key exists, FALSE otherwise.
|
||||
*/
|
||||
public boolean containsKey(String key) {
|
||||
return getValue().containsKey(key);
|
||||
}
|
||||
public abstract boolean containsKey(String key);
|
||||
|
||||
/**
|
||||
* Retrieve a Set view of the keys of each entry in this compound.
|
||||
* @return The keys of each entry.
|
||||
*/
|
||||
public Set<String> getKeys() {
|
||||
return getValue().keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, NbtBase<?>> getValue() {
|
||||
// Return a wrapper map
|
||||
if (savedMap == null) {
|
||||
savedMap = new ConvertedMap<String, Object, NbtBase<?>>(container.getValue()) {
|
||||
@Override
|
||||
protected Object toInner(NbtBase<?> outer) {
|
||||
if (outer == null)
|
||||
return null;
|
||||
return NbtFactory.fromBase(outer).getHandle();
|
||||
}
|
||||
|
||||
protected NbtBase<?> toOuter(Object inner) {
|
||||
if (inner == null)
|
||||
return null;
|
||||
return NbtFactory.fromNMS(inner);
|
||||
};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return NbtCompound.this.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
return savedMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Map<String, NbtBase<?>> newValue) {
|
||||
// Write all the entries
|
||||
for (Map.Entry<String, NbtBase<?>> entry : newValue.entrySet()) {
|
||||
put(entry.getValue());
|
||||
}
|
||||
}
|
||||
public abstract Set<String> getKeys();
|
||||
|
||||
/**
|
||||
* Retrieve the value of a given entry.
|
||||
* @param key - key of the entry to retrieve.
|
||||
* @return The value of this entry, or NULL if not found.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> NbtBase<T> getValue(String key) {
|
||||
return (NbtBase<T>) getValue().get(key);
|
||||
}
|
||||
public abstract <T> NbtBase<T> getValue(String key);
|
||||
|
||||
/**
|
||||
* Retrieve a value by its key, or assign and return a new NBT element if it doesn't exist.
|
||||
@ -157,48 +39,14 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @param type - the NBT element we will create if not found.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
public NbtBase<?> getValueOrDefault(String key, NbtType type) {
|
||||
NbtBase<?> nbt = getValue(key);
|
||||
|
||||
// Create or get a compound
|
||||
if (nbt == null)
|
||||
put(nbt = NbtFactory.ofType(type, key));
|
||||
else if (nbt.getType() != type)
|
||||
throw new IllegalArgumentException("Cannot get tag " + nbt + ": Not a " + type);
|
||||
|
||||
return nbt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value, or throw an exception.
|
||||
* @param key - the key to retrieve.
|
||||
* @return The value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
private <T> NbtBase<T> getValueExact(String key) {
|
||||
NbtBase<T> value = getValue(key);
|
||||
|
||||
// Only return a legal key
|
||||
if (value != null)
|
||||
return value;
|
||||
else
|
||||
throw new IllegalArgumentException("Cannot find key " + key);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public NbtBase<Map<String, NbtBase<?>>> deepClone() {
|
||||
return (NbtBase) container.deepClone();
|
||||
}
|
||||
public abstract NbtBase<?> getValueOrDefault(String key, NbtType type);
|
||||
|
||||
/**
|
||||
* Set a entry based on its name.
|
||||
* @param entry - entry with a name and value.
|
||||
* @return This compound, for chaining.
|
||||
*/
|
||||
public <T> NbtCompound put(NbtBase<T> entry) {
|
||||
getValue().put(entry.getName(), entry);
|
||||
return this;
|
||||
}
|
||||
public abstract <T> NbtCompound put(NbtBase<T> entry);
|
||||
|
||||
/**
|
||||
* Retrieve the string value of an entry identified by a given key.
|
||||
@ -206,18 +54,14 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @return The string value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
public String getString(String key) {
|
||||
return (String) getValueExact(key).getValue();
|
||||
}
|
||||
public abstract String getString(String key);
|
||||
|
||||
/**
|
||||
* Retrieve the string value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
public String getStringOrDefault(String key) {
|
||||
return (String) getValueOrDefault(key, NbtType.TAG_STRING).getValue();
|
||||
}
|
||||
public abstract String getStringOrDefault(String key);
|
||||
|
||||
/**
|
||||
* Associate a NBT string value with the given key.
|
||||
@ -225,10 +69,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public NbtCompound put(String key, String value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
public abstract NbtCompound put(String key, String value);
|
||||
|
||||
/**
|
||||
* Retrieve the byte value of an entry identified by a given key.
|
||||
@ -236,18 +77,14 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @return The byte value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
public byte getByte(String key) {
|
||||
return (Byte) getValueExact(key).getValue();
|
||||
}
|
||||
public abstract byte getByte(String key);
|
||||
|
||||
/**
|
||||
* Retrieve the byte value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
public byte getByteOrDefault(String key) {
|
||||
return (Byte) getValueOrDefault(key, NbtType.TAG_BYTE).getValue();
|
||||
}
|
||||
public abstract byte getByteOrDefault(String key);
|
||||
|
||||
/**
|
||||
* Associate a NBT byte value with the given key.
|
||||
@ -255,10 +92,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public NbtCompound put(String key, byte value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
public abstract NbtCompound put(String key, byte value);
|
||||
|
||||
/**
|
||||
* Retrieve the short value of an entry identified by a given key.
|
||||
@ -266,18 +100,14 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @return The short value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
public Short getShort(String key) {
|
||||
return (Short) getValueExact(key).getValue();
|
||||
}
|
||||
public abstract Short getShort(String key);
|
||||
|
||||
/**
|
||||
* Retrieve the short value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
public short getShortOrDefault(String key) {
|
||||
return (Short) getValueOrDefault(key, NbtType.TAG_SHORT).getValue();
|
||||
}
|
||||
public abstract short getShortOrDefault(String key);
|
||||
|
||||
/**
|
||||
* Associate a NBT short value with the given key.
|
||||
@ -285,10 +115,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public NbtCompound put(String key, short value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
public abstract NbtCompound put(String key, short value);
|
||||
|
||||
/**
|
||||
* Retrieve the integer value of an entry identified by a given key.
|
||||
@ -296,18 +123,14 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @return The integer value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
public int getInteger(String key) {
|
||||
return (Integer) getValueExact(key).getValue();
|
||||
}
|
||||
public abstract int getInteger(String key);
|
||||
|
||||
/**
|
||||
* Retrieve the integer value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
public int getIntegerOrDefault(String key) {
|
||||
return (Integer) getValueOrDefault(key, NbtType.TAG_INT).getValue();
|
||||
}
|
||||
public abstract int getIntegerOrDefault(String key);
|
||||
|
||||
/**
|
||||
* Associate a NBT integer value with the given key.
|
||||
@ -315,10 +138,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public NbtCompound put(String key, int value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
public abstract NbtCompound put(String key, int value);
|
||||
|
||||
/**
|
||||
* Retrieve the long value of an entry identified by a given key.
|
||||
@ -326,18 +146,14 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @return The long value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
public long getLong(String key) {
|
||||
return (Long) getValueExact(key).getValue();
|
||||
}
|
||||
public abstract long getLong(String key);
|
||||
|
||||
/**
|
||||
* Retrieve the long value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
public long getLongOrDefault(String key) {
|
||||
return (Long) getValueOrDefault(key, NbtType.TAG_LONG).getValue();
|
||||
}
|
||||
public abstract long getLongOrDefault(String key);
|
||||
|
||||
/**
|
||||
* Associate a NBT long value with the given key.
|
||||
@ -345,10 +161,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public NbtCompound put(String key, long value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
public abstract NbtCompound put(String key, long value);
|
||||
|
||||
/**
|
||||
* Retrieve the float value of an entry identified by a given key.
|
||||
@ -356,18 +169,14 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @return The float value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
public float getFloat(String key) {
|
||||
return (Float) getValueExact(key).getValue();
|
||||
}
|
||||
public abstract float getFloat(String key);
|
||||
|
||||
/**
|
||||
* Retrieve the float value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
public float getFloatOrDefault(String key) {
|
||||
return (Float) getValueOrDefault(key, NbtType.TAG_FLOAT).getValue();
|
||||
}
|
||||
public abstract float getFloatOrDefault(String key);
|
||||
|
||||
/**
|
||||
* Associate a NBT float value with the given key.
|
||||
@ -375,10 +184,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public NbtCompound put(String key, float value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
public abstract NbtCompound put(String key, float value);
|
||||
|
||||
/**
|
||||
* Retrieve the double value of an entry identified by a given key.
|
||||
@ -386,18 +192,14 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @return The double value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
public double getDouble(String key) {
|
||||
return (Double) getValueExact(key).getValue();
|
||||
}
|
||||
public abstract double getDouble(String key);
|
||||
|
||||
/**
|
||||
* Retrieve the double value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
public double getDoubleOrDefault(String key) {
|
||||
return (Double) getValueOrDefault(key, NbtType.TAG_DOUBlE).getValue();
|
||||
}
|
||||
public abstract double getDoubleOrDefault(String key);
|
||||
|
||||
/**
|
||||
* Associate a NBT double value with the given key.
|
||||
@ -405,10 +207,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public NbtCompound put(String key, double value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
public abstract NbtCompound put(String key, double value);
|
||||
|
||||
/**
|
||||
* Retrieve the byte array value of an entry identified by a given key.
|
||||
@ -416,9 +215,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @return The byte array value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
public byte[] getByteArray(String key) {
|
||||
return (byte[]) getValueExact(key).getValue();
|
||||
}
|
||||
public abstract byte[] getByteArray(String key);
|
||||
|
||||
/**
|
||||
* Associate a NBT byte array value with the given key.
|
||||
@ -426,10 +223,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public NbtCompound put(String key, byte[] value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
public abstract NbtCompound put(String key, byte[] value);
|
||||
|
||||
/**
|
||||
* Retrieve the integer array value of an entry identified by a given key.
|
||||
@ -437,9 +231,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @return The integer array value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
public int[] getIntegerArray(String key) {
|
||||
return (int[]) getValueExact(key).getValue();
|
||||
}
|
||||
public abstract int[] getIntegerArray(String key);
|
||||
|
||||
/**
|
||||
* Associate a NBT integer array value with the given key.
|
||||
@ -447,10 +239,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public NbtCompound put(String key, int[] value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
public abstract NbtCompound put(String key, int[] value);
|
||||
|
||||
/**
|
||||
* Retrieve the compound (map) value of an entry identified by a given key.
|
||||
@ -458,29 +247,21 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @return The compound value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public NbtCompound getCompound(String key) {
|
||||
return (NbtCompound) ((NbtBase) getValueExact(key));
|
||||
}
|
||||
public abstract NbtCompound getCompound(String key);
|
||||
|
||||
/**
|
||||
* Retrieve a compound (map) value by its key, or create a new compound if it doesn't exist.
|
||||
* @param key - the key of the entry to find or create.
|
||||
* @return The compound value that was retrieved or just created.
|
||||
*/
|
||||
public NbtCompound getCompoundOrDefault(String key) {
|
||||
return (NbtCompound) getValueOrDefault(key, NbtType.TAG_COMPOUND);
|
||||
}
|
||||
public abstract NbtCompound getCompoundOrDefault(String key);
|
||||
|
||||
/**
|
||||
* Associate a NBT compound with its name as key.
|
||||
* @param compound - the compound value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public NbtCompound put(NbtCompound compound) {
|
||||
getValue().put(compound.getName(), compound);
|
||||
return this;
|
||||
}
|
||||
public abstract NbtCompound put(WrappedCompound compound);
|
||||
|
||||
/**
|
||||
* Retrieve the NBT list value of an entry identified by a given key.
|
||||
@ -488,30 +269,21 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @return The NBT list value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public <T> NbtList<T> getList(String key) {
|
||||
return (NbtList) getValueExact(key);
|
||||
}
|
||||
public abstract <T> NbtList<T> getList(String key);
|
||||
|
||||
/**
|
||||
* Retrieve a NBT list value by its key, or create a new list if it doesn't exist.
|
||||
* @param key - the key of the entry to find or create.
|
||||
* @return The compound value that was retrieved or just created.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> NbtList<T> getListOrDefault(String key) {
|
||||
return (NbtList<T>) getValueOrDefault(key, NbtType.TAG_LIST);
|
||||
}
|
||||
public abstract <T> NbtList<T> getListOrDefault(String key);
|
||||
|
||||
/**
|
||||
* Associate a NBT list with the given key.
|
||||
* @param list - the list value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public <T> NbtCompound put(NbtList<T> list) {
|
||||
getValue().put(list.getName(), list);
|
||||
return this;
|
||||
}
|
||||
public abstract <T> NbtCompound put(WrappedList<T> list);
|
||||
|
||||
/**
|
||||
* Associate a new NBT list with the given key.
|
||||
@ -519,52 +291,11 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
|
||||
* @param list - the list of NBT elements.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
public <T> NbtCompound put(String key, Collection<? extends NbtBase<T>> list) {
|
||||
return put(NbtList.fromList(key, list));
|
||||
}
|
||||
public abstract <T> NbtCompound put(String key, Collection<? extends NbtBase<T>> list);
|
||||
|
||||
@Override
|
||||
public void write(DataOutput destination) {
|
||||
NbtFactory.toStream(container, destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof NbtCompound) {
|
||||
NbtCompound other = (NbtCompound) obj;
|
||||
return container.equals(other.container);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return container.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<NbtBase<?>> iterator() {
|
||||
return getValue().values().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append("{");
|
||||
builder.append("\"name\": \"" + getName() + "\"");
|
||||
|
||||
for (NbtBase<?> element : this) {
|
||||
builder.append(", ");
|
||||
|
||||
// Wrap in quotation marks
|
||||
if (element.getType() == NbtType.TAG_STRING)
|
||||
builder.append("\"" + element.getName() + "\": \"" + element.getValue() + "\"");
|
||||
else
|
||||
builder.append("\"" + element.getName() + "\": " + element.getValue());
|
||||
}
|
||||
|
||||
builder.append("}");
|
||||
return builder.toString();
|
||||
}
|
||||
/**
|
||||
* Retrieve an iterator view of the NBT tags stored in this compound.
|
||||
* @return The tags stored in this compound.
|
||||
*/
|
||||
public abstract Iterator<NbtBase<?>> iterator();
|
||||
}
|
@ -85,16 +85,16 @@ public class NbtFactory {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> NbtWrapper<T> fromBase(NbtBase<T> base) {
|
||||
if (base instanceof NbtElement) {
|
||||
return (NbtElement<T>) base;
|
||||
} else if (base instanceof NbtCompound) {
|
||||
if (base instanceof WrappedElement) {
|
||||
return (WrappedElement<T>) base;
|
||||
} else if (base instanceof WrappedCompound) {
|
||||
return (NbtWrapper<T>) base;
|
||||
} else if (base instanceof NbtList) {
|
||||
} else if (base instanceof WrappedList) {
|
||||
return (NbtWrapper<T>) base;
|
||||
} else {
|
||||
if (base.getType() == NbtType.TAG_COMPOUND) {
|
||||
// Load into a NBT-backed wrapper
|
||||
NbtCompound copy = NbtCompound.fromName(base.getName());
|
||||
WrappedCompound copy = WrappedCompound.fromName(base.getName());
|
||||
T value = base.getValue();
|
||||
|
||||
copy.setValue((Map<String, NbtBase<?>>) value);
|
||||
@ -102,7 +102,7 @@ public class NbtFactory {
|
||||
|
||||
} else if (base.getType() == NbtType.TAG_LIST) {
|
||||
// As above
|
||||
NbtList<T> copy = NbtList.fromName(base.getName());
|
||||
WrappedList<T> copy = WrappedList.fromName(base.getName());
|
||||
|
||||
copy.setValue((List<NbtBase<T>>) base.getValue());
|
||||
return (NbtWrapper<T>) copy;
|
||||
@ -156,13 +156,13 @@ public class NbtFactory {
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static <T> NbtWrapper<T> fromNMS(Object handle) {
|
||||
NbtElement<T> partial = new NbtElement<T>(handle);
|
||||
WrappedElement<T> partial = new WrappedElement<T>(handle);
|
||||
|
||||
// See if this is actually a compound tag
|
||||
if (partial.getType() == NbtType.TAG_COMPOUND)
|
||||
return (NbtWrapper<T>) new NbtCompound(handle);
|
||||
return (NbtWrapper<T>) new WrappedCompound(handle);
|
||||
else if (partial.getType() == NbtType.TAG_LIST)
|
||||
return new NbtList(handle);
|
||||
return new WrappedList(handle);
|
||||
else
|
||||
return partial;
|
||||
}
|
||||
@ -306,7 +306,7 @@ public class NbtFactory {
|
||||
* @return The new wrapped NBT compound.
|
||||
*/
|
||||
public static NbtCompound ofCompound(String name, Collection<? extends NbtBase<?>> list) {
|
||||
return NbtCompound.fromList(name, list);
|
||||
return WrappedCompound.fromList(name, list);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -314,8 +314,8 @@ public class NbtFactory {
|
||||
* @param name - the name of the compound wrapper.
|
||||
* @return The new wrapped NBT compound.
|
||||
*/
|
||||
public static NbtCompound ofCompound(String name) {
|
||||
return NbtCompound.fromName(name);
|
||||
public static WrappedCompound ofCompound(String name) {
|
||||
return WrappedCompound.fromName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -325,7 +325,7 @@ public class NbtFactory {
|
||||
* @return The new filled NBT list.
|
||||
*/
|
||||
public static <T> NbtList<T> ofList(String name, T... elements) {
|
||||
return NbtList.fromArray(name, elements);
|
||||
return WrappedList.fromArray(name, elements);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -354,11 +354,11 @@ public class NbtFactory {
|
||||
Object handle = methodCreateTag.invoke(null, (byte) type.getRawID(), name);
|
||||
|
||||
if (type == NbtType.TAG_COMPOUND)
|
||||
return (NbtWrapper<T>) new NbtCompound(handle);
|
||||
return (NbtWrapper<T>) new WrappedCompound(handle);
|
||||
else if (type == NbtType.TAG_LIST)
|
||||
return (NbtWrapper<T>) new NbtList(handle);
|
||||
return (NbtWrapper<T>) new WrappedList(handle);
|
||||
else
|
||||
return new NbtElement<T>(handle);
|
||||
return new WrappedElement<T>(handle);
|
||||
|
||||
} catch (Exception e) {
|
||||
// Inform the caller
|
||||
|
@ -1,33 +1,9 @@
|
||||
/*
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2012 Kristian S. Stangeland
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
package com.comphenix.protocol.wrappers.nbt;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* Represents a list of NBT tags of the same type without names.
|
||||
* <p>
|
||||
@ -37,299 +13,108 @@ import com.google.common.collect.Iterables;
|
||||
*
|
||||
* @param <TType> - the value type of each NBT tag.
|
||||
*/
|
||||
public class NbtList<TType> implements NbtWrapper<List<NbtBase<TType>>>, Iterable<TType> {
|
||||
public interface NbtList<TType> extends NbtBase<List<NbtBase<TType>>>, Iterable<TType> {
|
||||
/**
|
||||
* The name of every NBT tag in a list.
|
||||
*/
|
||||
public static String EMPTY_NAME = "";
|
||||
|
||||
// A list container
|
||||
private NbtElement<List<Object>> container;
|
||||
|
||||
// Saved wrapper list
|
||||
private ConvertedList<Object, NbtBase<TType>> savedList;
|
||||
|
||||
/**
|
||||
* Construct a new empty NBT list.
|
||||
* @param name - name of this list.
|
||||
* @return The new empty NBT list.
|
||||
*/
|
||||
public static <T> NbtList<T> fromName(String name) {
|
||||
return (NbtList<T>) NbtFactory.<List<NbtBase<T>>>ofType(NbtType.TAG_LIST, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a NBT list of out an array of values..
|
||||
* @param name - name of this list.
|
||||
* @param elements - values to add.
|
||||
* @return The new filled NBT list.
|
||||
*/
|
||||
public static <T> NbtList<T> fromArray(String name, T... elements) {
|
||||
NbtList<T> result = fromName(name);
|
||||
|
||||
for (T element : elements) {
|
||||
if (element == null)
|
||||
throw new IllegalArgumentException("An NBT list cannot contain a null element!");
|
||||
result.add(NbtFactory.ofType(element.getClass(), EMPTY_NAME, element));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a NBT list of out a list of NBT elements.
|
||||
* @param name - name of this list.
|
||||
* @param elements - elements to add.
|
||||
* @return The new filled NBT list.
|
||||
*/
|
||||
public static <T> NbtList<T> fromList(String name, Collection<? extends T> elements) {
|
||||
NbtList<T> result = fromName(name);
|
||||
|
||||
for (T element : elements) {
|
||||
if (element == null)
|
||||
throw new IllegalArgumentException("An NBT list cannot contain a null element!");
|
||||
result.add(NbtFactory.ofType(element.getClass(), EMPTY_NAME, element));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NbtList(Object handle) {
|
||||
this.container = new NbtElement<List<Object>>(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return container.getHandle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NbtType getType() {
|
||||
return NbtType.TAG_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of each element.
|
||||
* @return Element type.
|
||||
*/
|
||||
public NbtType getElementType() {
|
||||
return container.getSubType();
|
||||
}
|
||||
public abstract NbtType getElementType();
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return container.getName();
|
||||
}
|
||||
/**
|
||||
* Add a NBT list or NBT compound to the list.
|
||||
* @param element
|
||||
*/
|
||||
public abstract void add(NbtBase<TType> element);
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
container.setName(name);
|
||||
}
|
||||
/**
|
||||
* Add a new string element to the list.
|
||||
* @param value - the string element to add.
|
||||
* @throws IllegalArgumentException If this is not a list of strings.
|
||||
*/
|
||||
public abstract void add(String value);
|
||||
|
||||
@Override
|
||||
public List<NbtBase<TType>> getValue() {
|
||||
if (savedList == null) {
|
||||
savedList = new ConvertedList<Object, NbtBase<TType>>(container.getValue()) {
|
||||
// Check and see if the element is valid
|
||||
private void verifyElement(NbtBase<TType> element) {
|
||||
if (element == null)
|
||||
throw new IllegalArgumentException("Cannot store NULL elements in list.");
|
||||
if (!element.getName().equals(EMPTY_NAME))
|
||||
throw new IllegalArgumentException("Cannot add a the named NBT tag " + element + " to a list.");
|
||||
/**
|
||||
* Add a new byte element to the list.
|
||||
* @param value - the byte element to add.
|
||||
* @throws IllegalArgumentException If this is not a list of bytes.
|
||||
*/
|
||||
public abstract void add(byte value);
|
||||
|
||||
// Check element type
|
||||
if (size() > 0) {
|
||||
if (!element.getType().equals(getElementType())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot add " + element + " of " + element.getType() + " to a list of type " + getElementType());
|
||||
}
|
||||
} else {
|
||||
container.setSubType(element.getType());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Add a new short element to the list.
|
||||
* @param value - the short element to add.
|
||||
* @throws IllegalArgumentException If this is not a list of shorts.
|
||||
*/
|
||||
public abstract void add(short value);
|
||||
|
||||
@Override
|
||||
public boolean add(NbtBase<TType> e) {
|
||||
verifyElement(e);
|
||||
return super.add(e);
|
||||
}
|
||||
/**
|
||||
* Add a new integer element to the list.
|
||||
* @param value - the string element to add.
|
||||
* @throws IllegalArgumentException If this is not a list of integers.
|
||||
*/
|
||||
public abstract void add(int value);
|
||||
|
||||
@Override
|
||||
public void add(int index, NbtBase<TType> element) {
|
||||
verifyElement(element);
|
||||
super.add(index, element);
|
||||
}
|
||||
/**
|
||||
* Add a new long element to the list.
|
||||
* @param value - the string element to add.
|
||||
* @throws IllegalArgumentException If this is not a list of longs.
|
||||
*/
|
||||
public abstract void add(long value);
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends NbtBase<TType>> c) {
|
||||
boolean empty = size() == 0;
|
||||
boolean result = false;
|
||||
/**
|
||||
* Add a new double element to the list.
|
||||
* @param value - the double element to add.
|
||||
* @throws IllegalArgumentException If this is not a list of doubles.
|
||||
*/
|
||||
public abstract void add(double value);
|
||||
|
||||
for (NbtBase<TType> element : c) {
|
||||
add(element);
|
||||
result = true;
|
||||
}
|
||||
/**
|
||||
* Add a new byte array element to the list.
|
||||
* @param value - the byte array element to add.
|
||||
* @throws IllegalArgumentException If this is not a list of byte arrays.
|
||||
*/
|
||||
public abstract void add(byte[] value);
|
||||
|
||||
// See if we now added our first object(s)
|
||||
if (empty && result) {
|
||||
container.setSubType(get(0).getType());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Add a new int array element to the list.
|
||||
* @param value - the int array element to add.
|
||||
* @throws IllegalArgumentException If this is not a list of int arrays.
|
||||
*/
|
||||
public abstract void add(int[] value);
|
||||
|
||||
@Override
|
||||
protected Object toInner(NbtBase<TType> outer) {
|
||||
if (outer == null)
|
||||
return null;
|
||||
return NbtFactory.fromBase(outer).getHandle();
|
||||
}
|
||||
/**
|
||||
* Remove a given object from the list.
|
||||
* @param remove - the object to remove.
|
||||
*/
|
||||
public abstract void remove(Object remove);
|
||||
|
||||
@Override
|
||||
protected NbtBase<TType> toOuter(Object inner) {
|
||||
if (inner == null)
|
||||
return null;
|
||||
return NbtFactory.fromNMS(inner);
|
||||
}
|
||||
/**
|
||||
* Retrieve an element by index.
|
||||
* @param index - index of the element to retrieve.
|
||||
* @return The element to retrieve.
|
||||
* @throws IndexOutOfBoundsException If the index is out of range (index < 0 || index >= size())
|
||||
*/
|
||||
public abstract TType getValue(int index);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return NbtList.this.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
return savedList;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public NbtBase<List<NbtBase<TType>>> deepClone() {
|
||||
return (NbtBase) container.deepClone();
|
||||
}
|
||||
|
||||
public void add(NbtBase<TType> element) {
|
||||
getValue().add(element);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(String value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(byte value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(short value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(int value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(long value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(double value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(byte[] value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(int[] value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return getValue().size();
|
||||
}
|
||||
|
||||
public TType getValue(int index) {
|
||||
return getValue().get(index).getValue();
|
||||
}
|
||||
/**
|
||||
* Retrieve the number of elements in this list.
|
||||
* @return The number of elements in this list.
|
||||
*/
|
||||
public abstract int size();
|
||||
|
||||
/**
|
||||
* Retrieve each NBT tag in this list.
|
||||
* @return A view of NBT tag in this list.
|
||||
*/
|
||||
public Collection<NbtBase<TType>> asCollection() {
|
||||
return getValue();
|
||||
}
|
||||
public abstract Collection<NbtBase<TType>> asCollection();
|
||||
|
||||
@Override
|
||||
public void setValue(List<NbtBase<TType>> newValue) {
|
||||
NbtBase<TType> lastElement = null;
|
||||
List<Object> list = container.getValue();
|
||||
list.clear();
|
||||
|
||||
// Set each underlying element
|
||||
for (NbtBase<TType> type : newValue) {
|
||||
if (type != null) {
|
||||
lastElement = type;
|
||||
list.add(NbtFactory.fromBase(type).getHandle());
|
||||
} else {
|
||||
list.add(null);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the sub type as well
|
||||
if (lastElement != null) {
|
||||
container.setSubType(lastElement.getType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput destination) {
|
||||
NbtFactory.toStream(container, destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof NbtList) {
|
||||
@SuppressWarnings("unchecked")
|
||||
NbtList<TType> other = (NbtList<TType>) obj;
|
||||
return container.equals(other.container);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return container.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<TType> iterator() {
|
||||
return Iterables.transform(getValue(), new Function<NbtBase<TType>, TType>() {
|
||||
@Override
|
||||
public TType apply(@Nullable NbtBase<TType> param) {
|
||||
return param.getValue();
|
||||
}
|
||||
}).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// Essentially JSON
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append("{\"name\": \"" + getName() + "\", \"value\": [");
|
||||
|
||||
if (size() > 0) {
|
||||
if (getElementType() == NbtType.TAG_STRING)
|
||||
builder.append("\"" + Joiner.on("\", \"").join(this) + "\"");
|
||||
else
|
||||
builder.append(Joiner.on(", ").join(this));
|
||||
}
|
||||
|
||||
builder.append("]}");
|
||||
return builder.toString();
|
||||
}
|
||||
/**
|
||||
* Iterate over all the elements in this list.
|
||||
*/
|
||||
public abstract Iterator<TType> iterator();
|
||||
}
|
@ -0,0 +1,606 @@
|
||||
/*
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2012 Kristian S. Stangeland
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
package com.comphenix.protocol.wrappers.nbt;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A concrete implementation of an NbtCompound that wraps an underlying NMS Compound.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterable<NbtBase<?>>, NbtCompound {
|
||||
// A list container
|
||||
private WrappedElement<Map<String, Object>> container;
|
||||
|
||||
// Saved wrapper map
|
||||
private ConvertedMap<String, Object, NbtBase<?>> savedMap;
|
||||
|
||||
/**
|
||||
* Construct a new NBT compound wrapper.
|
||||
* @param name - the name of the wrapper.
|
||||
* @return The wrapped NBT compound.
|
||||
*/
|
||||
public static WrappedCompound fromName(String name) {
|
||||
// Simplify things for the caller
|
||||
return (WrappedCompound) NbtFactory.<Map<String, NbtBase<?>>>ofType(NbtType.TAG_COMPOUND, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new NBT compound wrapper initialized with a given list of NBT values.
|
||||
* @param name - the name of the compound wrapper.
|
||||
* @param list - the list of elements to add.
|
||||
* @return The new wrapped NBT compound.
|
||||
*/
|
||||
public static NbtCompound fromList(String name, Collection<? extends NbtBase<?>> list) {
|
||||
WrappedCompound copy = fromName(name);
|
||||
|
||||
for (NbtBase<?> base : list)
|
||||
copy.getValue().put(base.getName(), base);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a wrapped compound from a given NMS handle.
|
||||
* @param handle - the NMS handle.
|
||||
*/
|
||||
WrappedCompound(Object handle) {
|
||||
this.container = new WrappedElement<Map<String,Object>>(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return container.getHandle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NbtType getType() {
|
||||
return NbtType.TAG_COMPOUND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return container.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
container.setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an entry with the given key exists or not.
|
||||
* @param key - the key to lookup.
|
||||
* @return TRUE if an entry with the given key exists, FALSE otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
return getValue().containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a Set view of the keys of each entry in this compound.
|
||||
* @return The keys of each entry.
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getKeys() {
|
||||
return getValue().keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, NbtBase<?>> getValue() {
|
||||
// Return a wrapper map
|
||||
if (savedMap == null) {
|
||||
savedMap = new ConvertedMap<String, Object, NbtBase<?>>(container.getValue()) {
|
||||
@Override
|
||||
protected Object toInner(NbtBase<?> outer) {
|
||||
if (outer == null)
|
||||
return null;
|
||||
return NbtFactory.fromBase(outer).getHandle();
|
||||
}
|
||||
|
||||
protected NbtBase<?> toOuter(Object inner) {
|
||||
if (inner == null)
|
||||
return null;
|
||||
return NbtFactory.fromNMS(inner);
|
||||
};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return WrappedCompound.this.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
return savedMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Map<String, NbtBase<?>> newValue) {
|
||||
// Write all the entries
|
||||
for (Map.Entry<String, NbtBase<?>> entry : newValue.entrySet()) {
|
||||
put(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value of a given entry.
|
||||
* @param key - key of the entry to retrieve.
|
||||
* @return The value of this entry, or NULL if not found.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> NbtBase<T> getValue(String key) {
|
||||
return (NbtBase<T>) getValue().get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value by its key, or assign and return a new NBT element if it doesn't exist.
|
||||
* @param key - the key of the entry to find or create.
|
||||
* @param type - the NBT element we will create if not found.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
@Override
|
||||
public NbtBase<?> getValueOrDefault(String key, NbtType type) {
|
||||
NbtBase<?> nbt = getValue(key);
|
||||
|
||||
// Create or get a compound
|
||||
if (nbt == null)
|
||||
put(nbt = NbtFactory.ofType(type, key));
|
||||
else if (nbt.getType() != type)
|
||||
throw new IllegalArgumentException("Cannot get tag " + nbt + ": Not a " + type);
|
||||
|
||||
return nbt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value, or throw an exception.
|
||||
* @param key - the key to retrieve.
|
||||
* @return The value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
private <T> NbtBase<T> getValueExact(String key) {
|
||||
NbtBase<T> value = getValue(key);
|
||||
|
||||
// Only return a legal key
|
||||
if (value != null)
|
||||
return value;
|
||||
else
|
||||
throw new IllegalArgumentException("Cannot find key " + key);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public NbtBase<Map<String, NbtBase<?>>> deepClone() {
|
||||
return (NbtBase) container.deepClone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a entry based on its name.
|
||||
* @param entry - entry with a name and value.
|
||||
* @return This compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public <T> NbtCompound put(NbtBase<T> entry) {
|
||||
getValue().put(entry.getName(), entry);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the string value of an entry identified by a given key.
|
||||
* @param key - the key of the entry.
|
||||
* @return The string value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@Override
|
||||
public String getString(String key) {
|
||||
return (String) getValueExact(key).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the string value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
@Override
|
||||
public String getStringOrDefault(String key) {
|
||||
return (String) getValueOrDefault(key, NbtType.TAG_STRING).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a NBT string value with the given key.
|
||||
* @param key - the key and NBT name.
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public NbtCompound put(String key, String value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the byte value of an entry identified by a given key.
|
||||
* @param key - the key of the entry.
|
||||
* @return The byte value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@Override
|
||||
public byte getByte(String key) {
|
||||
return (Byte) getValueExact(key).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the byte value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
@Override
|
||||
public byte getByteOrDefault(String key) {
|
||||
return (Byte) getValueOrDefault(key, NbtType.TAG_BYTE).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a NBT byte value with the given key.
|
||||
* @param key - the key and NBT name.
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public NbtCompound put(String key, byte value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the short value of an entry identified by a given key.
|
||||
* @param key - the key of the entry.
|
||||
* @return The short value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@Override
|
||||
public Short getShort(String key) {
|
||||
return (Short) getValueExact(key).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the short value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
@Override
|
||||
public short getShortOrDefault(String key) {
|
||||
return (Short) getValueOrDefault(key, NbtType.TAG_SHORT).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a NBT short value with the given key.
|
||||
* @param key - the key and NBT name.
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public NbtCompound put(String key, short value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the integer value of an entry identified by a given key.
|
||||
* @param key - the key of the entry.
|
||||
* @return The integer value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@Override
|
||||
public int getInteger(String key) {
|
||||
return (Integer) getValueExact(key).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the integer value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
@Override
|
||||
public int getIntegerOrDefault(String key) {
|
||||
return (Integer) getValueOrDefault(key, NbtType.TAG_INT).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a NBT integer value with the given key.
|
||||
* @param key - the key and NBT name.
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public NbtCompound put(String key, int value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the long value of an entry identified by a given key.
|
||||
* @param key - the key of the entry.
|
||||
* @return The long value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@Override
|
||||
public long getLong(String key) {
|
||||
return (Long) getValueExact(key).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the long value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
@Override
|
||||
public long getLongOrDefault(String key) {
|
||||
return (Long) getValueOrDefault(key, NbtType.TAG_LONG).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a NBT long value with the given key.
|
||||
* @param key - the key and NBT name.
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public NbtCompound put(String key, long value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the float value of an entry identified by a given key.
|
||||
* @param key - the key of the entry.
|
||||
* @return The float value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@Override
|
||||
public float getFloat(String key) {
|
||||
return (Float) getValueExact(key).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the float value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
@Override
|
||||
public float getFloatOrDefault(String key) {
|
||||
return (Float) getValueOrDefault(key, NbtType.TAG_FLOAT).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a NBT float value with the given key.
|
||||
* @param key - the key and NBT name.
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public NbtCompound put(String key, float value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the double value of an entry identified by a given key.
|
||||
* @param key - the key of the entry.
|
||||
* @return The double value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@Override
|
||||
public double getDouble(String key) {
|
||||
return (Double) getValueExact(key).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the double value of an existing entry, or from a new default entry if it doesn't exist.
|
||||
* @param key - the key of the entry.
|
||||
* @return The value that was retrieved or just created.
|
||||
*/
|
||||
@Override
|
||||
public double getDoubleOrDefault(String key) {
|
||||
return (Double) getValueOrDefault(key, NbtType.TAG_DOUBlE).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a NBT double value with the given key.
|
||||
* @param key - the key and NBT name.
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public NbtCompound put(String key, double value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the byte array value of an entry identified by a given key.
|
||||
* @param key - the key of the entry.
|
||||
* @return The byte array value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@Override
|
||||
public byte[] getByteArray(String key) {
|
||||
return (byte[]) getValueExact(key).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a NBT byte array value with the given key.
|
||||
* @param key - the key and NBT name.
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public NbtCompound put(String key, byte[] value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the integer array value of an entry identified by a given key.
|
||||
* @param key - the key of the entry.
|
||||
* @return The integer array value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@Override
|
||||
public int[] getIntegerArray(String key) {
|
||||
return (int[]) getValueExact(key).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a NBT integer array value with the given key.
|
||||
* @param key - the key and NBT name.
|
||||
* @param value - the value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public NbtCompound put(String key, int[] value) {
|
||||
getValue().put(key, NbtFactory.of(key, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the compound (map) value of an entry identified by a given key.
|
||||
* @param key - the key of the entry.
|
||||
* @return The compound value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public NbtCompound getCompound(String key) {
|
||||
return (NbtCompound) ((NbtBase) getValueExact(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a compound (map) value by its key, or create a new compound if it doesn't exist.
|
||||
* @param key - the key of the entry to find or create.
|
||||
* @return The compound value that was retrieved or just created.
|
||||
*/
|
||||
@Override
|
||||
public NbtCompound getCompoundOrDefault(String key) {
|
||||
return (NbtCompound) getValueOrDefault(key, NbtType.TAG_COMPOUND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a NBT compound with its name as key.
|
||||
* @param compound - the compound value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public NbtCompound put(WrappedCompound compound) {
|
||||
getValue().put(compound.getName(), compound);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the NBT list value of an entry identified by a given key.
|
||||
* @param key - the key of the entry.
|
||||
* @return The NBT list value of the entry.
|
||||
* @throws IllegalArgumentException If the key doesn't exist.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public <T> NbtList<T> getList(String key) {
|
||||
return (NbtList) getValueExact(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a NBT list value by its key, or create a new list if it doesn't exist.
|
||||
* @param key - the key of the entry to find or create.
|
||||
* @return The compound value that was retrieved or just created.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> NbtList<T> getListOrDefault(String key) {
|
||||
return (NbtList<T>) getValueOrDefault(key, NbtType.TAG_LIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a NBT list with the given key.
|
||||
* @param list - the list value.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public <T> NbtCompound put(WrappedList<T> list) {
|
||||
getValue().put(list.getName(), list);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a new NBT list with the given key.
|
||||
* @param key - the key and name of the new NBT list.
|
||||
* @param list - the list of NBT elements.
|
||||
* @return This current compound, for chaining.
|
||||
*/
|
||||
@Override
|
||||
public <T> NbtCompound put(String key, Collection<? extends NbtBase<T>> list) {
|
||||
return put(WrappedList.fromList(key, list));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput destination) {
|
||||
NbtFactory.toStream(container, destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof WrappedCompound) {
|
||||
WrappedCompound other = (WrappedCompound) obj;
|
||||
return container.equals(other.container);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return container.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<NbtBase<?>> iterator() {
|
||||
return getValue().values().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append("{");
|
||||
builder.append("\"name\": \"" + getName() + "\"");
|
||||
|
||||
for (NbtBase<?> element : this) {
|
||||
builder.append(", ");
|
||||
|
||||
// Wrap in quotation marks
|
||||
if (element.getType() == NbtType.TAG_STRING)
|
||||
builder.append("\"" + element.getName() + "\": \"" + element.getValue() + "\"");
|
||||
else
|
||||
builder.append("\"" + element.getName() + "\": " + element.getValue());
|
||||
}
|
||||
|
||||
builder.append("}");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ import com.google.common.base.Objects;
|
||||
*
|
||||
* @param <TType> - type of the value field.
|
||||
*/
|
||||
public class NbtElement<TType> implements NbtWrapper<TType> {
|
||||
public class WrappedElement<TType> implements NbtWrapper<TType> {
|
||||
// Structure modifier for the base class
|
||||
private static volatile StructureModifier<Object> baseModifier;
|
||||
|
||||
@ -57,7 +57,7 @@ public class NbtElement<TType> implements NbtWrapper<TType> {
|
||||
* Initialize a NBT wrapper for a generic element.
|
||||
* @param handle - the NBT element to wrap.
|
||||
*/
|
||||
NbtElement(Object handle) {
|
||||
WrappedElement(Object handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
|
@ -0,0 +1,346 @@
|
||||
/*
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2012 Kristian S. Stangeland
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
package com.comphenix.protocol.wrappers.nbt;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* Represents a concrete implementation of an NBT list that wraps an underlying NMS list.
|
||||
* @author Kristian
|
||||
*
|
||||
* @param <TType> - the type of the value in each NBT sub element.
|
||||
*/
|
||||
public class WrappedList<TType> implements NbtWrapper<List<NbtBase<TType>>>, Iterable<TType>, NbtList<TType> {
|
||||
// A list container
|
||||
private WrappedElement<List<Object>> container;
|
||||
|
||||
// Saved wrapper list
|
||||
private ConvertedList<Object, NbtBase<TType>> savedList;
|
||||
|
||||
/**
|
||||
* Construct a new empty NBT list.
|
||||
* @param name - name of this list.
|
||||
* @return The new empty NBT list.
|
||||
*/
|
||||
public static <T> WrappedList<T> fromName(String name) {
|
||||
return (WrappedList<T>) NbtFactory.<List<NbtBase<T>>>ofType(NbtType.TAG_LIST, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a NBT list of out an array of values..
|
||||
* @param name - name of this list.
|
||||
* @param elements - values to add.
|
||||
* @return The new filled NBT list.
|
||||
*/
|
||||
public static <T> WrappedList<T> fromArray(String name, T... elements) {
|
||||
WrappedList<T> result = fromName(name);
|
||||
|
||||
for (T element : elements) {
|
||||
if (element == null)
|
||||
throw new IllegalArgumentException("An NBT list cannot contain a null element!");
|
||||
result.add(NbtFactory.ofType(element.getClass(), EMPTY_NAME, element));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a NBT list of out a list of NBT elements.
|
||||
* @param name - name of this list.
|
||||
* @param elements - elements to add.
|
||||
* @return The new filled NBT list.
|
||||
*/
|
||||
public static <T> WrappedList<T> fromList(String name, Collection<? extends T> elements) {
|
||||
WrappedList<T> result = fromName(name);
|
||||
|
||||
for (T element : elements) {
|
||||
if (element == null)
|
||||
throw new IllegalArgumentException("An NBT list cannot contain a null element!");
|
||||
result.add(NbtFactory.ofType(element.getClass(), EMPTY_NAME, element));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public WrappedList(Object handle) {
|
||||
this.container = new WrappedElement<List<Object>>(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return container.getHandle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NbtType getType() {
|
||||
return NbtType.TAG_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of each element.
|
||||
* @return Element type.
|
||||
*/
|
||||
@Override
|
||||
public NbtType getElementType() {
|
||||
return container.getSubType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return container.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
container.setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NbtBase<TType>> getValue() {
|
||||
if (savedList == null) {
|
||||
savedList = new ConvertedList<Object, NbtBase<TType>>(container.getValue()) {
|
||||
// Check and see if the element is valid
|
||||
private void verifyElement(NbtBase<TType> element) {
|
||||
if (element == null)
|
||||
throw new IllegalArgumentException("Cannot store NULL elements in list.");
|
||||
if (!element.getName().equals(EMPTY_NAME))
|
||||
throw new IllegalArgumentException("Cannot add a the named NBT tag " + element + " to a list.");
|
||||
|
||||
// Check element type
|
||||
if (size() > 0) {
|
||||
if (!element.getType().equals(getElementType())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot add " + element + " of " + element.getType() + " to a list of type " + getElementType());
|
||||
}
|
||||
} else {
|
||||
container.setSubType(element.getType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(NbtBase<TType> e) {
|
||||
verifyElement(e);
|
||||
return super.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, NbtBase<TType> element) {
|
||||
verifyElement(element);
|
||||
super.add(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends NbtBase<TType>> c) {
|
||||
boolean empty = size() == 0;
|
||||
boolean result = false;
|
||||
|
||||
for (NbtBase<TType> element : c) {
|
||||
add(element);
|
||||
result = true;
|
||||
}
|
||||
|
||||
// See if we now added our first object(s)
|
||||
if (empty && result) {
|
||||
container.setSubType(get(0).getType());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object toInner(NbtBase<TType> outer) {
|
||||
if (outer == null)
|
||||
return null;
|
||||
return NbtFactory.fromBase(outer).getHandle();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NbtBase<TType> toOuter(Object inner) {
|
||||
if (inner == null)
|
||||
return null;
|
||||
return NbtFactory.fromNMS(inner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return WrappedList.this.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
return savedList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public NbtBase<List<NbtBase<TType>>> deepClone() {
|
||||
return (NbtBase) container.deepClone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(NbtBase<TType> element) {
|
||||
getValue().add(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(String value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(byte value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(short value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(int value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(long value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(double value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(byte[] value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(int[] value) {
|
||||
add((NbtBase<TType>) NbtFactory.of(EMPTY_NAME, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return getValue().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TType getValue(int index) {
|
||||
return getValue().get(index).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve each NBT tag in this list.
|
||||
* @return A view of NBT tag in this list.
|
||||
*/
|
||||
@Override
|
||||
public Collection<NbtBase<TType>> asCollection() {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(List<NbtBase<TType>> newValue) {
|
||||
NbtBase<TType> lastElement = null;
|
||||
List<Object> list = container.getValue();
|
||||
list.clear();
|
||||
|
||||
// Set each underlying element
|
||||
for (NbtBase<TType> type : newValue) {
|
||||
if (type != null) {
|
||||
lastElement = type;
|
||||
list.add(NbtFactory.fromBase(type).getHandle());
|
||||
} else {
|
||||
list.add(null);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the sub type as well
|
||||
if (lastElement != null) {
|
||||
container.setSubType(lastElement.getType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput destination) {
|
||||
NbtFactory.toStream(container, destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof WrappedList) {
|
||||
@SuppressWarnings("unchecked")
|
||||
WrappedList<TType> other = (WrappedList<TType>) obj;
|
||||
return container.equals(other.container);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return container.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<TType> iterator() {
|
||||
return Iterables.transform(getValue(), new Function<NbtBase<TType>, TType>() {
|
||||
@Override
|
||||
public TType apply(@Nullable NbtBase<TType> param) {
|
||||
return param.getValue();
|
||||
}
|
||||
}).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// Essentially JSON
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append("{\"name\": \"" + getName() + "\", \"value\": [");
|
||||
|
||||
if (size() > 0) {
|
||||
if (getElementType() == NbtType.TAG_STRING)
|
||||
builder.append("\"" + Joiner.on("\", \"").join(this) + "\"");
|
||||
else
|
||||
builder.append(Joiner.on(", ").join(this));
|
||||
}
|
||||
|
||||
builder.append("]}");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Object remove) {
|
||||
getValue().remove(remove);
|
||||
}
|
||||
}
|
@ -50,6 +50,7 @@ import com.comphenix.protocol.wrappers.ChunkPosition;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
||||
import com.comphenix.protocol.wrappers.nbt.WrappedCompound;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
@ -256,7 +257,7 @@ public class PacketContainerTest {
|
||||
public void testGetNbtModifier() {
|
||||
PacketContainer updateTileEntity = new PacketContainer(132);
|
||||
|
||||
NbtCompound compound = NbtFactory.ofCompound("test");
|
||||
WrappedCompound compound = NbtFactory.ofCompound("test");
|
||||
compound.put("test", "name");
|
||||
compound.put(NbtFactory.ofList("ages", 1, 2, 3));
|
||||
|
||||
|
@ -34,7 +34,7 @@ public class NbtCompoundTest {
|
||||
public void testCustomTags() {
|
||||
NbtCustomTag<Integer> test = new NbtCustomTag<Integer>("hello", 12);
|
||||
|
||||
NbtCompound map = NbtCompound.fromName("test");
|
||||
WrappedCompound map = WrappedCompound.fromName("test");
|
||||
map.put(test);
|
||||
|
||||
// Note that the custom tag will be cloned
|
||||
|
@ -40,7 +40,7 @@ public class NbtFactoryTest {
|
||||
|
||||
@Test
|
||||
public void testFromStream() {
|
||||
NbtCompound compound = NbtCompound.fromName("tag");
|
||||
WrappedCompound compound = WrappedCompound.fromName("tag");
|
||||
|
||||
compound.put("name", "Test Testerson");
|
||||
compound.put("age", 42);
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren