Added the ability to read NBT ItemStack tags.

This commit is contained in:
Kristian S. Stangeland 2013-01-07 23:39:16 +01:00
parent 38137cea2c
commit 70589a6263
3 changed files with 197 additions and 6 deletions

View File

@ -72,6 +72,15 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
container.setName(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.
*/
public boolean containsKey(String key) {
return getValue().containsKey(key);
}
/** /**
* Retrieve a Set view of the keys of each entry in this compound. * Retrieve a Set view of the keys of each entry in this compound.
* @return The keys of each entry. * @return The keys of each entry.
@ -118,17 +127,36 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
/** /**
* Retrieve the value of a given entry. * Retrieve the value of a given entry.
* @param key - key of the entry to retrieve. * @param key - key of the entry to retrieve.
* @return The value of this entry. * @return The value of this entry, or NULL if not found.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> NbtBase<T> getValue(String key) { public <T> NbtBase<T> getValue(String key) {
return (NbtBase<T>) getValue().get(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.
*/
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. * Retrieve a value, or throw an exception.
* @param key - the key to retrieve. * @param key - the key to retrieve.
* @return The value of the entry. * @return The value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
private <T> NbtBase<T> getValueExact(String key) { private <T> NbtBase<T> getValueExact(String key) {
NbtBase<T> value = getValue(key); NbtBase<T> value = getValue(key);
@ -159,11 +187,21 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
* Retrieve the string value of an entry identified by a given key. * Retrieve the string value of an entry identified by a given key.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The string value of the entry. * @return The string value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
public String getString(String key) { public String getString(String key) {
return (String) getValueExact(key).getValue(); 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.
*/
public String getStringOrDefault(String key) {
return (String) getValueOrDefault(key, NbtType.TAG_STRING).getValue();
}
/** /**
* Associate a NBT string value with the given key. * Associate a NBT string value with the given key.
* @param key - the key and NBT name. * @param key - the key and NBT name.
@ -179,11 +217,21 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
* Retrieve the byte value of an entry identified by a given key. * Retrieve the byte value of an entry identified by a given key.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The byte value of the entry. * @return The byte value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
public Byte getByte(String key) { public byte getByte(String key) {
return (Byte) getValueExact(key).getValue(); 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.
*/
public byte getByteOrDefault(String key) {
return (Byte) getValueOrDefault(key, NbtType.TAG_BYTE).getValue();
}
/** /**
* Associate a NBT byte value with the given key. * Associate a NBT byte value with the given key.
* @param key - the key and NBT name. * @param key - the key and NBT name.
@ -199,11 +247,21 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
* Retrieve the short value of an entry identified by a given key. * Retrieve the short value of an entry identified by a given key.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The short value of the entry. * @return The short value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
public Short getShort(String key) { public Short getShort(String key) {
return (Short) getValueExact(key).getValue(); 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.
*/
public short getShortOrDefault(String key) {
return (Short) getValueOrDefault(key, NbtType.TAG_SHORT).getValue();
}
/** /**
* Associate a NBT short value with the given key. * Associate a NBT short value with the given key.
* @param key - the key and NBT name. * @param key - the key and NBT name.
@ -219,11 +277,21 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
* Retrieve the integer value of an entry identified by a given key. * Retrieve the integer value of an entry identified by a given key.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The integer value of the entry. * @return The integer value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
public Integer getInteger(String key) { public int getInteger(String key) {
return (Integer) getValueExact(key).getValue(); 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.
*/
public int getIntegerOrDefault(String key) {
return (Integer) getValueOrDefault(key, NbtType.TAG_INT).getValue();
}
/** /**
* Associate a NBT integer value with the given key. * Associate a NBT integer value with the given key.
* @param key - the key and NBT name. * @param key - the key and NBT name.
@ -239,11 +307,21 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
* Retrieve the long value of an entry identified by a given key. * Retrieve the long value of an entry identified by a given key.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The long value of the entry. * @return The long value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
public Long getLong(String key) { public long getLong(String key) {
return (Long) getValueExact(key).getValue(); 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.
*/
public long getLongOrDefault(String key) {
return (Long) getValueOrDefault(key, NbtType.TAG_LONG).getValue();
}
/** /**
* Associate a NBT long value with the given key. * Associate a NBT long value with the given key.
* @param key - the key and NBT name. * @param key - the key and NBT name.
@ -259,11 +337,21 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
* Retrieve the float value of an entry identified by a given key. * Retrieve the float value of an entry identified by a given key.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The float value of the entry. * @return The float value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
public Float getFloat(String key) { public float getFloat(String key) {
return (Float) getValueExact(key).getValue(); 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.
*/
public float getFloatOrDefault(String key) {
return (Float) getValueOrDefault(key, NbtType.TAG_FLOAT).getValue();
}
/** /**
* Associate a NBT float value with the given key. * Associate a NBT float value with the given key.
* @param key - the key and NBT name. * @param key - the key and NBT name.
@ -279,11 +367,21 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
* Retrieve the double value of an entry identified by a given key. * Retrieve the double value of an entry identified by a given key.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The double value of the entry. * @return The double value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
public Double getDouble(String key) { public double getDouble(String key) {
return (Double) getValueExact(key).getValue(); 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.
*/
public double getDoubleOrDefault(String key) {
return (Double) getValueOrDefault(key, NbtType.TAG_DOUBlE).getValue();
}
/** /**
* Associate a NBT double value with the given key. * Associate a NBT double value with the given key.
* @param key - the key and NBT name. * @param key - the key and NBT name.
@ -299,6 +397,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
* Retrieve the byte array value of an entry identified by a given key. * Retrieve the byte array value of an entry identified by a given key.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The byte array value of the entry. * @return The byte array value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
public byte[] getByteArray(String key) { public byte[] getByteArray(String key) {
return (byte[]) getValueExact(key).getValue(); return (byte[]) getValueExact(key).getValue();
@ -319,6 +418,7 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
* Retrieve the integer array value of an entry identified by a given key. * Retrieve the integer array value of an entry identified by a given key.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The integer array value of the entry. * @return The integer array value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
public int[] getIntegerArray(String key) { public int[] getIntegerArray(String key) {
return (int[]) getValueExact(key).getValue(); return (int[]) getValueExact(key).getValue();
@ -339,12 +439,22 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
* Retrieve the compound (map) value of an entry identified by a given key. * Retrieve the compound (map) value of an entry identified by a given key.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The compound value of the entry. * @return The compound value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public NbtCompound getCompound(String key) { public NbtCompound getCompound(String key) {
return (NbtCompound) ((NbtBase) getValueExact(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.
*/
public NbtCompound getCompoundOrDefault(String key) {
return (NbtCompound) getValueOrDefault(key, NbtType.TAG_COMPOUND);
}
/** /**
* Associate a NBT compound with its name as key. * Associate a NBT compound with its name as key.
* @param compound - the compound value. * @param compound - the compound value.
@ -359,12 +469,23 @@ public class NbtCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterabl
* Retrieve the NBT list value of an entry identified by a given key. * Retrieve the NBT list value of an entry identified by a given key.
* @param key - the key of the entry. * @param key - the key of the entry.
* @return The NBT list value of the entry. * @return The NBT list value of the entry.
* @throws IllegalArgumentException If the key doesn't exist.
*/ */
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"})
public <T> NbtList<T> getList(String key) { public <T> NbtList<T> getList(String key) {
return (NbtList) getValueExact(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.
*/
@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. * Associate a NBT list with the given key.
* @param list - the list value. * @param list - the list value.

View File

@ -7,9 +7,13 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.bukkit.inventory.ItemStack;
import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.reflect.FieldAccessException;
import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.BukkitConverters;
/** /**
* Factory methods for creating NBT elements, lists and compounds. * Factory methods for creating NBT elements, lists and compounds.
@ -24,6 +28,39 @@ public class NbtFactory {
private static Method methodWrite; private static Method methodWrite;
private static Method methodLoad; private static Method methodLoad;
// Item stack trickery
private static StructureModifier<Object> itemStackModifier;
/**
* Attempt to cast this wrapper as a compund.
* @return This instance as a compound.
* @throws UnsupportedOperationException If this is not a compound.
*/
public static NbtCompound asCompound(NbtWrapper<?> wrapper) {
if (wrapper instanceof NbtCompound)
return (NbtCompound) wrapper;
else if (wrapper != null)
throw new UnsupportedOperationException(
"Cannot cast a " + wrapper.getClass() + "( " + wrapper.getType() + ") to TAG_COMPUND.");
else
throw new IllegalArgumentException("Wrapper cannot be NULL.");
}
/**
* Attempt to cast this wrapper as a list.
* @return This instance as a list.
* @throws UnsupportedOperationException If this is not a list.
*/
public static NbtList<?> asList(NbtWrapper<?> wrapper) {
if (wrapper instanceof NbtList)
return (NbtList<?>) wrapper;
else if (wrapper != null)
throw new UnsupportedOperationException(
"Cannot cast a " + wrapper.getClass() + "( " + wrapper.getType() + ") to TAG_LIST.");
else
throw new IllegalArgumentException("Wrapper cannot be NULL.");
}
/** /**
* Get a NBT wrapper from a NBT base. * Get a NBT wrapper from a NBT base.
* @param base - the base class. * @param base - the base class.
@ -63,6 +100,38 @@ public class NbtFactory {
} }
} }
/**
* Construct a wrapper for an NBT tag stored (in memory) in an item stack.
* <p>
* The item stack must be a wrapper for a CraftItemStack. Use
* {@link MinecraftReflection#getBukkitItemStack(ItemStack)} if not.
* @param stack - the item stack.
* @return A wrapper for its NBT tag.
*/
public static NbtWrapper<?> fromItemStack(ItemStack stack) {
if (!MinecraftReflection.isCraftItemStack(stack))
throw new IllegalArgumentException("Stack must be a CraftItemStack.");
Object nmsStack = MinecraftReflection.getMinecraftItemStack(stack);
if (itemStackModifier == null) {
itemStackModifier = new StructureModifier<Object>(nmsStack.getClass(), Object.class, false);
}
// Use the first and best NBT tag
StructureModifier<NbtWrapper<?>> modifier = itemStackModifier.
withTarget(nmsStack).
withType(MinecraftReflection.getNBTBaseClass(), BukkitConverters.getNbtConverter());
NbtWrapper<?> result = modifier.read(0);
// Create the tag if it doesn't exist
if (result == null) {
result = NbtFactory.ofCompound("tag");
modifier.write(0, result);
}
return result;
}
/** /**
* Initialize a NBT wrapper. * Initialize a NBT wrapper.
* @param handle - the underlying net.minecraft.server object to wrap. * @param handle - the underlying net.minecraft.server object to wrap.

View File

@ -300,6 +300,7 @@ public class NbtList<TType> implements NbtWrapper<List<NbtBase<TType>>>, Iterabl
@Override @Override
public String toString() { public String toString() {
// Essentially JSON
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("{\"name\": \"" + getName() + "\", \"value\": ["); builder.append("{\"name\": \"" + getName() + "\", \"value\": [");