631 lines
19 KiB
Java
631 lines
19 KiB
Java
package com.pretzel.dev.villagertradelimiter.nms;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.io.Serializable;
|
|
import java.lang.reflect.Field;
|
|
import java.util.*;
|
|
|
|
import org.bukkit.block.BlockState;
|
|
import org.bukkit.entity.Entity;
|
|
import org.bukkit.inventory.meta.ItemMeta;
|
|
|
|
import com.pretzel.dev.villagertradelimiter.nms.utils.GsonWrapper;
|
|
import com.pretzel.dev.villagertradelimiter.nms.utils.MinecraftVersion;
|
|
import com.pretzel.dev.villagertradelimiter.nms.utils.nmsmappings.ClassWrapper;
|
|
import com.pretzel.dev.villagertradelimiter.nms.utils.nmsmappings.ObjectCreator;
|
|
import com.pretzel.dev.villagertradelimiter.nms.utils.nmsmappings.ReflectionMethod;
|
|
|
|
/**
|
|
* Utility class for translating NBTApi calls to reflections into NMS code All
|
|
* methods are allowed to throw {@link NbtApiException}
|
|
*
|
|
* @author tr7zw
|
|
*
|
|
*/
|
|
public class NBTReflectionUtil {
|
|
|
|
private static Field field_unhandledTags = null;
|
|
|
|
static {
|
|
try {
|
|
field_unhandledTags = ClassWrapper.CRAFT_METAITEM.getClazz().getDeclaredField("unhandledTags");
|
|
field_unhandledTags.setAccessible(true);
|
|
} catch (NoSuchFieldException e) {
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hidden constructor
|
|
*/
|
|
private NBTReflectionUtil() {
|
|
|
|
}
|
|
|
|
/**
|
|
* Gets the NMS Entity for a given Bukkit Entity
|
|
*
|
|
* @param entity Bukkit Entity
|
|
* @return NMS Entity
|
|
*/
|
|
public static Object getNMSEntity(Entity entity) {
|
|
try {
|
|
return ReflectionMethod.CRAFT_ENTITY_GET_HANDLE.run(ClassWrapper.CRAFT_ENTITY.getClazz().cast(entity));
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while getting the NMS Entity from a Bukkit Entity!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reads in a InputStream as NMS Compound
|
|
*
|
|
* @param stream InputStream of any NBT file
|
|
* @return NMS Compound
|
|
*/
|
|
public static Object readNBT(InputStream stream) {
|
|
try {
|
|
return ReflectionMethod.NBTFILE_READ.run(null, stream);
|
|
} catch (Exception e) {
|
|
try {
|
|
stream.close();
|
|
}catch(IOException ignore) {}
|
|
throw new NbtApiException("Exception while reading a NBT File!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Writes a NMS Compound to an OutputStream
|
|
*
|
|
* @param nbt NMS Compound
|
|
* @param stream Stream to write to
|
|
* @return ???
|
|
*/
|
|
public static Object writeNBT(Object nbt, OutputStream stream) {
|
|
try {
|
|
return ReflectionMethod.NBTFILE_WRITE.run(null, nbt, stream);
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while writing NBT!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Writes a Compound to an OutputStream
|
|
*
|
|
* @param comp Compound
|
|
* @param stream Stream to write to
|
|
*/
|
|
public static void writeApiNBT(NBTCompound comp, OutputStream stream) {
|
|
try {
|
|
Object nbttag = comp.getCompound();
|
|
if (nbttag == null) {
|
|
nbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(comp))
|
|
return;
|
|
Object workingtag = gettoCompount(nbttag, comp);
|
|
ReflectionMethod.NBTFILE_WRITE.run(null, workingtag, stream);
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while writing NBT!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Simulates getOrCreateTag. If an Item doesn't yet have a Tag, it will return a
|
|
* new empty tag.
|
|
*
|
|
* @param nmsitem
|
|
* @return NMS Compound
|
|
*/
|
|
public static Object getItemRootNBTTagCompound(Object nmsitem) {
|
|
try {
|
|
Object answer = ReflectionMethod.NMSITEM_GETTAG.run(nmsitem);
|
|
return answer != null ? answer : ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while getting an Itemstack's NBTCompound!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Converts {@link NBTCompound} to NMS ItemStacks
|
|
*
|
|
* @param nbtcompound Any valid {@link NBTCompound}
|
|
* @return NMS ItemStack
|
|
*/
|
|
public static Object convertNBTCompoundtoNMSItem(NBTCompound nbtcompound) {
|
|
try {
|
|
Object nmsComp = gettoCompount(nbtcompound.getCompound(), nbtcompound);
|
|
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_11_R1.getVersionId()) {
|
|
return ObjectCreator.NMS_COMPOUNDFROMITEM.getInstance(nmsComp);
|
|
} else {
|
|
return ReflectionMethod.NMSITEM_CREATESTACK.run(null, nmsComp);
|
|
}
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while converting NBTCompound to NMS ItemStack!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Converts NMS ItemStacks to {@link NBTContainer}
|
|
*
|
|
* @param nmsitem NMS ItemStack
|
|
* @return {@link NBTContainer} with all the data
|
|
*/
|
|
public static NBTContainer convertNMSItemtoNBTCompound(Object nmsitem) {
|
|
try {
|
|
Object answer = ReflectionMethod.NMSITEM_SAVE.run(nmsitem, ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance());
|
|
return new NBTContainer(answer);
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while converting NMS ItemStack to NBTCompound!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets a live copy of non-vanilla NBT tags.
|
|
*
|
|
* @param meta ItemMeta from which tags should be retrieved
|
|
* @return Map containing unhandled (custom) NBT tags
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public static Map<String, Object> getUnhandledNBTTags(ItemMeta meta) {
|
|
try {
|
|
return (Map<String, Object>) field_unhandledTags.get(meta);
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while getting unhandled tags from ItemMeta!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the Vanilla NBT Compound from a given NMS Entity
|
|
*
|
|
* @param nmsEntity
|
|
* @return NMS NBT Compound
|
|
*/
|
|
public static Object getEntityNBTTagCompound(Object nmsEntity) {
|
|
try {
|
|
Object nbt = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
|
Object answer = ReflectionMethod.NMS_ENTITY_GET_NBT.run(nmsEntity, nbt);
|
|
if (answer == null)
|
|
answer = nbt;
|
|
return answer;
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while getting NBTCompound from NMS Entity!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads all Vanilla tags from a NMS Compound into a NMS Entity
|
|
*
|
|
* @param nbtTag
|
|
* @param nmsEntity
|
|
* @return The NMS Entity
|
|
*/
|
|
public static Object setEntityNBTTag(Object nbtTag, Object nmsEntity) {
|
|
try {
|
|
ReflectionMethod.NMS_ENTITY_SET_NBT.run(nmsEntity, nbtTag);
|
|
return nmsEntity;
|
|
} catch (Exception ex) {
|
|
throw new NbtApiException("Exception while setting the NBTCompound of an Entity", ex);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the NMS Compound from a given TileEntity
|
|
*
|
|
* @param tile
|
|
* @return NMS Compound with the Vanilla data
|
|
*/
|
|
public static Object getTileEntityNBTTagCompound(BlockState tile) {
|
|
try {
|
|
Object cworld = ClassWrapper.CRAFT_WORLD.getClazz().cast(tile.getWorld());
|
|
Object nmsworld = ReflectionMethod.CRAFT_WORLD_GET_HANDLE.run(cworld);
|
|
Object o = null;
|
|
if(MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4) {
|
|
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY_1_7_10.run(nmsworld, tile.getX(), tile.getY(), tile.getZ());
|
|
}else {
|
|
Object pos = ObjectCreator.NMS_BLOCKPOSITION.getInstance(tile.getX(), tile.getY(), tile.getZ());
|
|
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY.run(nmsworld, pos);
|
|
}
|
|
|
|
Object answer = null;
|
|
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_18_R1)) {
|
|
answer = ReflectionMethod.TILEENTITY_GET_NBT_1181.run(o);
|
|
} else {
|
|
answer = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
|
ReflectionMethod.TILEENTITY_GET_NBT.run(o, answer);
|
|
}
|
|
if (answer == null) {
|
|
throw new NbtApiException("Unable to get NBTCompound from TileEntity! " + tile + " " + o);
|
|
}
|
|
return answer;
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while getting NBTCompound from TileEntity!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets Vanilla tags from a NMS Compound to a TileEntity
|
|
*
|
|
* @param tile
|
|
* @param comp
|
|
*/
|
|
public static void setTileEntityNBTTagCompound(BlockState tile, Object comp) {
|
|
try {
|
|
Object cworld = ClassWrapper.CRAFT_WORLD.getClazz().cast(tile.getWorld());
|
|
Object nmsworld = ReflectionMethod.CRAFT_WORLD_GET_HANDLE.run(cworld);
|
|
Object o = null;
|
|
if(MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4) {
|
|
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY_1_7_10.run(nmsworld, tile.getX(), tile.getY(), tile.getZ());
|
|
}else {
|
|
Object pos = ObjectCreator.NMS_BLOCKPOSITION.getInstance(tile.getX(), tile.getY(), tile.getZ());
|
|
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY.run(nmsworld, pos);
|
|
}
|
|
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_17_R1)) {
|
|
ReflectionMethod.TILEENTITY_SET_NBT.run(o, comp);
|
|
}else if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1)) {
|
|
Object blockData = ReflectionMethod.TILEENTITY_GET_BLOCKDATA.run(o);
|
|
ReflectionMethod.TILEENTITY_SET_NBT_LEGACY1161.run(o, blockData, comp);
|
|
}else {
|
|
ReflectionMethod.TILEENTITY_SET_NBT_LEGACY1151.run(o, comp);
|
|
}
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while setting NBTData for a TileEntity!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the subCompound with a given name from a NMS Compound
|
|
*
|
|
* @param compound
|
|
* @param name
|
|
* @return NMS Compound or null
|
|
*/
|
|
public static Object getSubNBTTagCompound(Object compound, String name) {
|
|
try {
|
|
if ((boolean) ReflectionMethod.COMPOUND_HAS_KEY.run(compound, name)) {
|
|
return ReflectionMethod.COMPOUND_GET_COMPOUND.run(compound, name);
|
|
} else {
|
|
throw new NbtApiException("Tried getting invalide compound '" + name + "' from '" + compound + "'!");
|
|
}
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while getting NBT subcompounds!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a subCompound with a given name in the given NMS Compound
|
|
*
|
|
* @param comp
|
|
* @param name
|
|
*/
|
|
public static void addNBTTagCompound(NBTCompound comp, String name) {
|
|
if (name == null) {
|
|
remove(comp, name);
|
|
return;
|
|
}
|
|
Object nbttag = comp.getCompound();
|
|
if (nbttag == null) {
|
|
nbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(comp)) {
|
|
return;
|
|
}
|
|
Object workingtag = gettoCompount(nbttag, comp);
|
|
try {
|
|
ReflectionMethod.COMPOUND_SET.run(workingtag, name,
|
|
ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance());
|
|
comp.setCompound(nbttag);
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while adding a Compound!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if the Compound is correctly linked to it's roots
|
|
*
|
|
* @param comp
|
|
* @return true if this is a valide Compound, else false
|
|
*/
|
|
public static Boolean valideCompound(NBTCompound comp) {
|
|
Object root = comp.getCompound();
|
|
if (root == null) {
|
|
root = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
return (gettoCompount(root, comp)) != null;
|
|
}
|
|
|
|
protected static Object gettoCompount(Object nbttag, NBTCompound comp) {
|
|
Deque<String> structure = new ArrayDeque<>();
|
|
while (comp.getParent() != null) {
|
|
structure.add(comp.getName());
|
|
comp = comp.getParent();
|
|
}
|
|
while (!structure.isEmpty()) {
|
|
String target = structure.pollLast();
|
|
nbttag = getSubNBTTagCompound(nbttag, target);
|
|
if (nbttag == null) {
|
|
throw new NbtApiException("Unable to find tag '" + target + "' in " + nbttag);
|
|
}
|
|
}
|
|
return nbttag;
|
|
}
|
|
|
|
/**
|
|
* Merges the second {@link NBTCompound} into the first one
|
|
*
|
|
* @param comp Target for the merge
|
|
* @param nbtcompoundSrc Data to merge
|
|
*/
|
|
public static void mergeOtherNBTCompound(NBTCompound comp, NBTCompound nbtcompoundSrc) {
|
|
Object rootnbttag = comp.getCompound();
|
|
if (rootnbttag == null) {
|
|
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(comp))
|
|
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
|
Object workingtag = gettoCompount(rootnbttag, comp);
|
|
Object rootnbttagSrc = nbtcompoundSrc.getCompound();
|
|
if (rootnbttagSrc == null) {
|
|
rootnbttagSrc = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(nbtcompoundSrc))
|
|
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
|
Object workingtagSrc = gettoCompount(rootnbttagSrc, nbtcompoundSrc);
|
|
try {
|
|
ReflectionMethod.COMPOUND_MERGE.run(workingtag, workingtagSrc);
|
|
comp.setCompound(rootnbttag);
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while merging two NBTCompounds!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the content for a given key inside a Compound
|
|
*
|
|
* @param comp
|
|
* @param key
|
|
* @return Content saved under this key
|
|
*/
|
|
public static String getContent(NBTCompound comp, String key) {
|
|
Object rootnbttag = comp.getCompound();
|
|
if (rootnbttag == null) {
|
|
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(comp))
|
|
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
|
Object workingtag = gettoCompount(rootnbttag, comp);
|
|
try {
|
|
return ReflectionMethod.COMPOUND_GET.run(workingtag, key).toString();
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while getting the Content for key '" + key + "'!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets a key in a {@link NBTCompound} to a given value
|
|
*
|
|
* @param comp
|
|
* @param key
|
|
* @param val
|
|
*/
|
|
public static void set(NBTCompound comp, String key, Object val) {
|
|
if (val == null) {
|
|
remove(comp, key);
|
|
return;
|
|
}
|
|
Object rootnbttag = comp.getCompound();
|
|
if (rootnbttag == null) {
|
|
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(comp)) {
|
|
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
|
}
|
|
Object workingtag = gettoCompount(rootnbttag, comp);
|
|
try {
|
|
ReflectionMethod.COMPOUND_SET.run(workingtag, key, val);
|
|
comp.setCompound(rootnbttag);
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while setting key '" + key + "' to '" + val + "'!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the List saved with a given key.
|
|
*
|
|
* @param comp
|
|
* @param key
|
|
* @param type
|
|
* @param clazz
|
|
* @return The list at that key. Null if it's an invalide type
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public static <T> NBTList<T> getList(NBTCompound comp, String key, NBTType type, Class<T> clazz) {
|
|
Object rootnbttag = comp.getCompound();
|
|
if (rootnbttag == null) {
|
|
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(comp))
|
|
return null;
|
|
Object workingtag = gettoCompount(rootnbttag, comp);
|
|
try {
|
|
Object nbt = ReflectionMethod.COMPOUND_GET_LIST.run(workingtag, key, type.getId());
|
|
if (clazz == String.class) {
|
|
return (NBTList<T>) new NBTStringList(comp, key, type, nbt);
|
|
} else if (clazz == NBTListCompound.class) {
|
|
return (NBTList<T>) new NBTCompoundList(comp, key, type, nbt);
|
|
} else if (clazz == Integer.class) {
|
|
return (NBTList<T>) new NBTIntegerList(comp, key, type, nbt);
|
|
} else if (clazz == Float.class) {
|
|
return (NBTList<T>) new NBTFloatList(comp, key, type, nbt);
|
|
} else if (clazz == Double.class) {
|
|
return (NBTList<T>) new NBTDoubleList(comp, key, type, nbt);
|
|
} else if (clazz == Long.class) {
|
|
return (NBTList<T>) new NBTLongList(comp, key, type, nbt);
|
|
} else if (clazz == int[].class) {
|
|
return (NBTList<T>) new NBTIntArrayList(comp, key, type, nbt);
|
|
} else if (clazz == UUID.class) {
|
|
return (NBTList<T>) new NBTUUIDList(comp, key, type, nbt);
|
|
} else {
|
|
return null;
|
|
}
|
|
} catch (Exception ex) {
|
|
throw new NbtApiException("Exception while getting a list with the type '" + type + "'!", ex);
|
|
}
|
|
}
|
|
|
|
public static NBTType getListType(NBTCompound comp, String key) {
|
|
Object rootnbttag = comp.getCompound();
|
|
if (rootnbttag == null) {
|
|
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(comp))
|
|
return null;
|
|
Object workingtag = gettoCompount(rootnbttag, comp);
|
|
try {
|
|
Object nbt = ReflectionMethod.COMPOUND_GET.run(workingtag, key);
|
|
String fieldname = "type";
|
|
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_17_R1)) {
|
|
fieldname = "w";
|
|
}
|
|
Field f = nbt.getClass().getDeclaredField(fieldname);
|
|
f.setAccessible(true);
|
|
return NBTType.valueOf(f.getByte(nbt));
|
|
} catch (Exception ex) {
|
|
throw new NbtApiException("Exception while getting the list type!", ex);
|
|
}
|
|
}
|
|
|
|
public static Object getEntry(NBTCompound comp, String key) {
|
|
Object rootnbttag = comp.getCompound();
|
|
if (rootnbttag == null) {
|
|
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(comp))
|
|
return null;
|
|
Object workingtag = gettoCompount(rootnbttag, comp);
|
|
try {
|
|
Object nbt = ReflectionMethod.COMPOUND_GET.run(workingtag, key);
|
|
return nbt;
|
|
} catch (Exception ex) {
|
|
throw new NbtApiException("Exception while getting an Entry!", ex);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Uses Gson to set a {@link Serializable} value in a Compound
|
|
*
|
|
* @param comp
|
|
* @param key
|
|
* @param value
|
|
*/
|
|
public static void setObject(NBTCompound comp, String key, Object value) {
|
|
if (!MinecraftVersion.hasGsonSupport())
|
|
return;
|
|
try {
|
|
String json = GsonWrapper.getString(value);
|
|
setData(comp, ReflectionMethod.COMPOUND_SET_STRING, key, json);
|
|
} catch (Exception e) {
|
|
throw new NbtApiException("Exception while setting the Object '" + value + "'!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Uses Gson to load back a {@link Serializable} object from the Compound
|
|
*
|
|
* @param comp
|
|
* @param key
|
|
* @param type
|
|
* @return The loaded Object or null, if not found
|
|
*/
|
|
public static <T> T getObject(NBTCompound comp, String key, Class<T> type) {
|
|
if (!MinecraftVersion.hasGsonSupport())
|
|
return null;
|
|
String json = (String) getData(comp, ReflectionMethod.COMPOUND_GET_STRING, key);
|
|
if (json == null) {
|
|
return null;
|
|
}
|
|
return GsonWrapper.deserializeJson(json, type);
|
|
}
|
|
|
|
/**
|
|
* Deletes the given key
|
|
*
|
|
* @param comp
|
|
* @param key
|
|
*/
|
|
public static void remove(NBTCompound comp, String key) {
|
|
Object rootnbttag = comp.getCompound();
|
|
if (rootnbttag == null) {
|
|
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(comp))
|
|
return;
|
|
Object workingtag = gettoCompount(rootnbttag, comp);
|
|
ReflectionMethod.COMPOUND_REMOVE_KEY.run(workingtag, key);
|
|
comp.setCompound(rootnbttag);
|
|
}
|
|
|
|
/**
|
|
* Gets the Keyset inside this Compound
|
|
*
|
|
* @param comp
|
|
* @return Set of all keys
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public static Set<String> getKeys(NBTCompound comp) {
|
|
Object rootnbttag = comp.getCompound();
|
|
if (rootnbttag == null) {
|
|
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(comp))
|
|
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
|
Object workingtag = gettoCompount(rootnbttag, comp);
|
|
return (Set<String>) ReflectionMethod.COMPOUND_GET_KEYS.run(workingtag);
|
|
}
|
|
|
|
/**
|
|
* Sets data inside the Compound
|
|
*
|
|
* @param comp
|
|
* @param type
|
|
* @param key
|
|
* @param data
|
|
*/
|
|
public static void setData(NBTCompound comp, ReflectionMethod type, String key, Object data) {
|
|
if (data == null) {
|
|
remove(comp, key);
|
|
return;
|
|
}
|
|
Object rootnbttag = comp.getCompound();
|
|
if (rootnbttag == null) {
|
|
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
|
}
|
|
if (!valideCompound(comp))
|
|
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
|
Object workingtag = gettoCompount(rootnbttag, comp);
|
|
type.run(workingtag, key, data);
|
|
comp.setCompound(rootnbttag);
|
|
}
|
|
|
|
/**
|
|
* Gets data from the Compound
|
|
*
|
|
* @param comp
|
|
* @param type
|
|
* @param key
|
|
* @return The value or default fallback from NMS
|
|
*/
|
|
public static Object getData(NBTCompound comp, ReflectionMethod type, String key) {
|
|
Object rootnbttag = comp.getCompound();
|
|
if (rootnbttag == null) {
|
|
return null;
|
|
}
|
|
if (!valideCompound(comp))
|
|
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
|
Object workingtag = gettoCompount(rootnbttag, comp);
|
|
return type.run(workingtag, key);
|
|
}
|
|
|
|
}
|