Compare commits

..
16 Commits
Author SHA1 Message Date
tr7zw 0602a2b8c3 Bump to 2.9.0. Reduce/change logging 2021-12-17 22:58:07 +01:00
tr7zw e0c060a982 Fix 1.8 2021-11-29 19:54:36 +01:00
tr7zw caa37d4cb0 Update NBTReflectionUtil.java 2021-11-29 19:26:51 +01:00
tr7zw de9f2a786f Fix BlockEntities 2021-11-29 19:04:26 +01:00
tr7zw 423f0a07e4 Fix NMS_WORLD_GET_TILEENTITY 2021-11-28 16:28:20 +01:00
tr7zw eda1d60ccc Forgot to press "replace" 2021-11-25 20:43:41 +01:00
tr7zw acb5a376e9 Update ReflectionMethod.java 2021-11-25 20:16:58 +01:00
tr7zw 165bb4ce68 Fallback logic 2021-11-25 20:13:34 +01:00
tr7zw 08bde0923f Update MojangToMapping.java 2021-11-25 20:05:29 +01:00
tr7zw a78b68d16f Bump version, 1.18 WIP 2021-11-25 20:02:24 +01:00
tr7zw 87204ac4a0 Update spigot.bb 2021-11-15 00:06:32 +01:00
tr7zw 71701d4a3a Replace apache commons-lang exceptions with internal ones. Fix #138
It was never inteded to use external exceptions like that one inside the project.
2021-09-03 23:40:56 +02:00
tr7zw 6b156c47e4 no 1.17 in unit-test 2021-06-28 22:03:38 +02:00
tr7zw f783db7fca Bump download links 2021-06-28 21:54:01 +02:00
tr7zw 394c093981 Fix #127 2021-06-28 21:44:18 +02:00
tr7zw 1f94a8452e 2.8.1-SNAPSHOT, fix equals check and add more unit tests for it 2021-06-28 21:40:25 +02:00
23 changed files with 447 additions and 160 deletions

No files matched your search

+1
View File
@@ -51,6 +51,7 @@ tmp/
local.properties
.settings/
.loadpath
.factorypath
# Eclipse Core
.project
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
</parent>
<artifactId>item-nbt-api</artifactId>
@@ -798,8 +798,8 @@ public class NBTCompound {
if(!isEqual(this, other, key)) {
return false;
}
return true;
}
return true;
}
}
return false;
@@ -1,7 +1,5 @@
package de.tr7zw.changeme.nbtapi;
import org.apache.commons.lang.NotImplementedException;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
@@ -70,7 +68,7 @@ public class NBTCompoundList extends NBTList<NBTListCompound> {
@Override
public void add(int index, NBTListCompound element) {
if (element != null) {
throw new NotImplementedException("You need to pass null! ListCompounds from other lists won't work.");
throw new NbtApiException("You need to pass null! ListCompounds from other lists won't work.");
}
try {
Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
@@ -97,7 +95,7 @@ public class NBTCompoundList extends NBTList<NBTListCompound> {
@Override
public NBTListCompound set(int index, NBTListCompound element) {
throw new NotImplementedException("This method doesn't work in the ListCompound context.");
throw new NbtApiException("This method doesn't work in the ListCompound context.");
}
@Override
@@ -103,6 +103,17 @@ public class NBTItem extends NBTCompound {
item.setItemMeta(meta);
}
/**
* True, if the item has any tags now known for this item type.
*
* @return true when custom tags are present
*/
public boolean hasCustomNbtData() {
ItemMeta meta = bukkitItem.getItemMeta();
return !NBTReflectionUtil.getUnhandledNBTTags(meta).isEmpty();
}
/**
* Remove all custom (non-vanilla) NBT tags from the NBTItem.
*/
@@ -226,10 +226,17 @@ public class NBTReflectionUtil {
Object pos = ObjectCreator.NMS_BLOCKPOSITION.getInstance(tile.getX(), tile.getY(), tile.getZ());
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY.run(nmsworld, pos);
}
Object tag = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
Object answer = ReflectionMethod.TILEENTITY_GET_NBT.run(o, tag);
if (answer == null)
answer = tag;
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);
@@ -17,7 +17,7 @@ import org.bukkit.Bukkit;
public enum MinecraftVersion {
UNKNOWN(Integer.MAX_VALUE), // Use the newest known mappings
MC1_7_R4(174), MC1_8_R3(183), MC1_9_R1(191), MC1_9_R2(192), MC1_10_R1(1101), MC1_11_R1(1111), MC1_12_R1(1121),
MC1_13_R1(1131), MC1_13_R2(1132), MC1_14_R1(1141), MC1_15_R1(1151), MC1_16_R1(1161), MC1_16_R2(1162), MC1_16_R3(1163), MC1_17_R1(1171);
MC1_13_R1(1131), MC1_13_R2(1132), MC1_14_R1(1141), MC1_15_R1(1151), MC1_16_R1(1161), MC1_16_R2(1162), MC1_16_R3(1163), MC1_17_R1(1171), MC1_18_R1(1181, true);
private static MinecraftVersion version;
private static Boolean hasGsonSupport;
@@ -30,12 +30,18 @@ public enum MinecraftVersion {
private static Logger logger = Logger.getLogger("NBTAPI");
// NBT-API Version
protected static final String VERSION = "2.8.0";
protected static final String VERSION = "2.9.0";
private final int versionId;
private final boolean mojangMapping;
MinecraftVersion(int versionId) {
MinecraftVersion(int versionId) {
this(versionId, false);
}
MinecraftVersion(int versionId, boolean mojangMapping) {
this.versionId = versionId;
this.mojangMapping = mojangMapping;
}
/**
@@ -44,8 +50,22 @@ public enum MinecraftVersion {
public int getVersionId() {
return versionId;
}
/**
* @return True if method names are in Mojang format and need to be remapped internally
*/
public boolean isMojangMapping() {
return mojangMapping;
}
public String getPackageName() {
if(this == UNKNOWN) {
return values()[values().length-1].name().replace("MC", "v");
}
return this.name().replace("MC", "v");
}
/**
* Returns true if the current versions is at least the given Version
*
* @param version The minimum version
@@ -85,7 +105,7 @@ public enum MinecraftVersion {
if (version != UNKNOWN) {
logger.info("[NBTAPI] NMS support '" + version.name() + "' loaded!");
} else {
logger.warning("[NBTAPI] Wasn't able to find NMS Support! Some functions may not work!");
logger.warning("[NBTAPI] This Server-Version(" + ver + ") is not supported by this NBT-API Version(" + VERSION + ") located at " + MinecraftVersion.class.getName() + ". The NBT-API will try to work as good as it can! Some functions may not work!");
}
init();
return version;
@@ -21,6 +21,7 @@ public class VersionChecker {
private static final String USER_AGENT = "nbt-api Version check";
private static final String REQUEST_URL = "https://api.spiget.org/v2/resources/7939/versions?size=100";
public static boolean hideOk = false;
protected static void checkForUpdates() throws Exception {
URL url = new URL(REQUEST_URL);
@@ -43,18 +44,19 @@ public class VersionChecker {
int versionDifference = getVersionDifference(latest.get("name").getAsString());
if (versionDifference == -1) { // Outdated
MinecraftVersion.getLogger().log(Level.WARNING,
"[NBTAPI] The NBT-API at '" + NBTItem.class.getPackage() + "' seems to be outdated!");
"[NBTAPI] The NBT-API located at '" + NBTItem.class.getPackage() + "' seems to be outdated!");
MinecraftVersion.getLogger().log(Level.WARNING, "[NBTAPI] Current Version: '" + MinecraftVersion.VERSION
+ "' Newest Version: " + latest.get("name").getAsString() + "'");
MinecraftVersion.getLogger().log(Level.WARNING,
"[NBTAPI] Please update the nbt-api or the plugin that contains the api!");
"[NBTAPI] Please update the NBTAPI or the plugin that contains the api(nag the mod author when the newest release has an old version, not the NBTAPI dev)!");
} else if (versionDifference == 0) {
MinecraftVersion.getLogger().log(Level.INFO, "[NBTAPI] The NBT-API seems to be up-to-date!");
if(!hideOk)
MinecraftVersion.getLogger().log(Level.INFO, "[NBTAPI] The NBT-API seems to be up-to-date!");
} else if (versionDifference == 1) {
MinecraftVersion.getLogger().log(Level.WARNING, "[NBTAPI] The NBT-API at '" + NBTItem.class.getPackage()
+ "' seems to be a future Version, not yet released on Spigot/CurseForge!");
MinecraftVersion.getLogger().log(Level.WARNING, "[NBTAPI] Current Version: '" + MinecraftVersion.VERSION
MinecraftVersion.getLogger().log(Level.INFO, "[NBTAPI] The NBT-API at '" + NBTItem.class.getPackage()
+ "' seems to be a future Version, not yet released on Spigot/CurseForge! This is not an error!");
MinecraftVersion.getLogger().log(Level.INFO, "[NBTAPI] Current Version: '" + MinecraftVersion.VERSION
+ "' Newest Version: " + latest.get("name").getAsString() + "'");
}
} else {
@@ -1,10 +1,10 @@
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.getLogger;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.getLogger;
/**
* Wraps NMS and CRAFT classes
@@ -20,42 +20,44 @@ public enum ClassWrapper {
CRAFT_WORLD(PackageWrapper.CRAFTBUKKIT, "CraftWorld", null, null),
CRAFT_PERSISTENTDATACONTAINER(PackageWrapper.CRAFTBUKKIT, "persistence.CraftPersistentDataContainer",
MinecraftVersion.MC1_14_R1, null),
NMS_NBTBASE(PackageWrapper.NMS, "NBTBase", null, null, "net.minecraft.nbt"),
NMS_NBTTAGSTRING(PackageWrapper.NMS, "NBTTagString", null, null, "net.minecraft.nbt"),
NMS_NBTTAGINT(PackageWrapper.NMS, "NBTTagInt", null, null, "net.minecraft.nbt"),
NMS_NBTTAGFLOAT(PackageWrapper.NMS, "NBTTagFloat", null, null, "net.minecraft.nbt"),
NMS_NBTTAGDOUBLE(PackageWrapper.NMS, "NBTTagDouble", null, null, "net.minecraft.nbt"),
NMS_NBTTAGLONG(PackageWrapper.NMS, "NBTTagLong", null, null, "net.minecraft.nbt"),
NMS_ITEMSTACK(PackageWrapper.NMS, "ItemStack", null, null, "net.minecraft.world.item"),
NMS_NBTTAGCOMPOUND(PackageWrapper.NMS, "NBTTagCompound", null, null, "net.minecraft.nbt"),
NMS_NBTTAGLIST(PackageWrapper.NMS, "NBTTagList", null, null, "net.minecraft.nbt"),
NMS_NBTCOMPRESSEDSTREAMTOOLS(PackageWrapper.NMS, "NBTCompressedStreamTools", null, null, "net.minecraft.nbt"),
NMS_MOJANGSONPARSER(PackageWrapper.NMS, "MojangsonParser", null, null, "net.minecraft.nbt"),
NMS_TILEENTITY(PackageWrapper.NMS, "TileEntity", null, null, "net.minecraft.world.level.block.entity"),
NMS_BLOCKPOSITION(PackageWrapper.NMS, "BlockPosition", MinecraftVersion.MC1_8_R3, null, "net.minecraft.core"),
NMS_WORLDSERVER(PackageWrapper.NMS, "WorldServer", null, null, "net.minecraft.server.level"),
NMS_MINECRAFTSERVER(PackageWrapper.NMS, "MinecraftServer", null, null, "net.minecraft.server"),
NMS_WORLD(PackageWrapper.NMS, "World", null, null, "net.minecraft.world.level"),
NMS_ENTITY(PackageWrapper.NMS, "Entity", null, null, "net.minecraft.world.entity"),
NMS_ENTITYTYPES(PackageWrapper.NMS, "EntityTypes", null, null, "net.minecraft.world.entity"),
NMS_NBTBASE(PackageWrapper.NMS, "NBTBase", null, null, "net.minecraft.nbt", "net.minecraft.nbt.Tag"),
NMS_NBTTAGSTRING(PackageWrapper.NMS, "NBTTagString", null, null, "net.minecraft.nbt", "net.minecraft.nbt.StringTag"),
NMS_NBTTAGINT(PackageWrapper.NMS, "NBTTagInt", null, null, "net.minecraft.nbt", "net.minecraft.nbt.IntTag"),
NMS_NBTTAGFLOAT(PackageWrapper.NMS, "NBTTagFloat", null, null, "net.minecraft.nbt", "net.minecraft.nbt.FloatTag"),
NMS_NBTTAGDOUBLE(PackageWrapper.NMS, "NBTTagDouble", null, null, "net.minecraft.nbt", "net.minecraft.nbt.DoubleTag"),
NMS_NBTTAGLONG(PackageWrapper.NMS, "NBTTagLong", null, null, "net.minecraft.nbt", "net.minecraft.nbt.LongTag"),
NMS_ITEMSTACK(PackageWrapper.NMS, "ItemStack", null, null, "net.minecraft.world.item", "net.minecraft.world.item.ItemStack"),
NMS_NBTTAGCOMPOUND(PackageWrapper.NMS, "NBTTagCompound", null, null, "net.minecraft.nbt", "net.minecraft.nbt.CompoundTag"),
NMS_NBTTAGLIST(PackageWrapper.NMS, "NBTTagList", null, null, "net.minecraft.nbt", "net.minecraft.nbt.ListTag"),
NMS_NBTCOMPRESSEDSTREAMTOOLS(PackageWrapper.NMS, "NBTCompressedStreamTools", null, null, "net.minecraft.nbt", "net.minecraft.nbt.NbtIo"),
NMS_MOJANGSONPARSER(PackageWrapper.NMS, "MojangsonParser", null, null, "net.minecraft.nbt", "net.minecraft.nbt.TagParser"),
NMS_TILEENTITY(PackageWrapper.NMS, "TileEntity", null, null, "net.minecraft.world.level.block.entity", "net.minecraft.world.level.block.entity.BlockEntity"),
NMS_BLOCKPOSITION(PackageWrapper.NMS, "BlockPosition", MinecraftVersion.MC1_8_R3, null, "net.minecraft.core", "net.minecraft.core.BlockPos"),
NMS_WORLDSERVER(PackageWrapper.NMS, "WorldServer", null, null, "net.minecraft.server.level", "net.minecraft.server.level.ServerLevel"),
NMS_MINECRAFTSERVER(PackageWrapper.NMS, "MinecraftServer", null, null, "net.minecraft.server", "net.minecraft.server.MinecraftServer"),
NMS_WORLD(PackageWrapper.NMS, "World", null, null, "net.minecraft.world.level", "net.minecraft.world.level.Level"),
NMS_ENTITY(PackageWrapper.NMS, "Entity", null, null, "net.minecraft.world.entity", "net.minecraft.world.entity.Entity"),
NMS_ENTITYTYPES(PackageWrapper.NMS, "EntityTypes", null, null, "net.minecraft.world.entity", "net.minecraft.world.entity.EntityType"),
NMS_REGISTRYSIMPLE(PackageWrapper.NMS, "RegistrySimple", MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_12_R1),
NMS_REGISTRYMATERIALS(PackageWrapper.NMS, "RegistryMaterials", null, null, "net.minecraft.core"),
NMS_IREGISTRY(PackageWrapper.NMS, "IRegistry", null, null, "net.minecraft.core"),
NMS_MINECRAFTKEY(PackageWrapper.NMS, "MinecraftKey", MinecraftVersion.MC1_8_R3, null, "net.minecraft.resources"),
NMS_GAMEPROFILESERIALIZER(PackageWrapper.NMS, "GameProfileSerializer", null, null, "net.minecraft.nbt"),
NMS_REGISTRYMATERIALS(PackageWrapper.NMS, "RegistryMaterials", null, null, "net.minecraft.core", "net.minecraft.core.MappedRegistry"),
NMS_IREGISTRY(PackageWrapper.NMS, "IRegistry", null, null, "net.minecraft.core", "net.minecraft.core.Registry"),
NMS_MINECRAFTKEY(PackageWrapper.NMS, "MinecraftKey", MinecraftVersion.MC1_8_R3, null, "net.minecraft.resources", "net.minecraft.resources.ResourceKey"),
NMS_GAMEPROFILESERIALIZER(PackageWrapper.NMS, "GameProfileSerializer", null, null, "net.minecraft.nbt", "net.minecraft.nbt.NbtUtils"),
NMS_IBLOCKDATA(PackageWrapper.NMS, "IBlockData", MinecraftVersion.MC1_8_R3, null,
"net.minecraft.world.level.block.state"),
"net.minecraft.world.level.block.state", "net.minecraft.world.level.block.state.BlockState"),
GAMEPROFILE(PackageWrapper.NONE, "com.mojang.authlib.GameProfile", MinecraftVersion.MC1_8_R3, null);
private Class<?> clazz;
private boolean enabled = false;
private final String mojangName;
ClassWrapper(PackageWrapper packageId, String clazzName, MinecraftVersion from, MinecraftVersion to) {
this(packageId, clazzName, from, to, null);
this(packageId, clazzName, from, to, null, null);
}
ClassWrapper(PackageWrapper packageId, String clazzName, MinecraftVersion from, MinecraftVersion to,
String mojangMap) {
String mojangMap, String mojangName) {
this.mojangName = mojangName;
if (from != null && MinecraftVersion.getVersion().getVersionId() < from.getVersionId()) {
return;
}
@@ -69,10 +71,10 @@ public enum ClassWrapper {
} else if (packageId == PackageWrapper.NONE) {
clazz = Class.forName(clazzName);
} else {
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
String version = MinecraftVersion.getVersion().getPackageName();
clazz = Class.forName(packageId.getUri() + "." + version + "." + clazzName);
}
} catch (Exception ex) {
} catch (Throwable ex) {
getLogger().log(Level.WARNING, "[NBTAPI] Error while trying to resolve the class '" + clazzName + "'!", ex);
}
}
@@ -91,4 +93,11 @@ public enum ClassWrapper {
return enabled;
}
/**
* @return Package+Class name used by Mojang
*/
public String getMojangName() {
return mojangName;
}
}
@@ -0,0 +1,80 @@
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
import java.util.HashMap;
import java.util.Map;
/**
* Temporary solution to hold Mojang to unmapped Spigot mappings.
*
* @author tr7zw
*
*/
public class MojangToMapping {
@SuppressWarnings("serial")
private static Map<String, String> MC1_18R1 = new HashMap<String, String>() {
{
put("net.minecraft.nbt.CompoundTag#contains(java.lang.String)", "e");
put("net.minecraft.nbt.CompoundTag#getCompound(java.lang.String)", "p");
put("net.minecraft.nbt.CompoundTag#getList(java.lang.String,int)", "c");
put("net.minecraft.nbt.CompoundTag#putByteArray(java.lang.String,byte[])", "a");
put("net.minecraft.nbt.CompoundTag#getDouble(java.lang.String)", "k");
put("net.minecraft.nbt.CompoundTag#putDouble(java.lang.String,double)", "a");
put("net.minecraft.nbt.CompoundTag#getByteArray(java.lang.String)", "m");
put("net.minecraft.nbt.CompoundTag#putInt(java.lang.String,int)", "a");
put("net.minecraft.nbt.CompoundTag#getIntArray(java.lang.String)", "n");
put("net.minecraft.nbt.CompoundTag#remove(java.lang.String)", "r");
put("net.minecraft.nbt.CompoundTag#get(java.lang.String)", "c");
put("net.minecraft.nbt.CompoundTag#put(java.lang.String,net.minecraft.nbt.Tag)", "a");
put("net.minecraft.nbt.CompoundTag#putBoolean(java.lang.String,boolean)", "a");
put("net.minecraft.nbt.CompoundTag#getTagType(java.lang.String)", "d");
put("net.minecraft.nbt.CompoundTag#putLong(java.lang.String,long)", "a");
put("net.minecraft.nbt.CompoundTag#getString(java.lang.String)", "l");
put("net.minecraft.nbt.CompoundTag#getInt(java.lang.String)", "h");
put("net.minecraft.nbt.CompoundTag#putString(java.lang.String,java.lang.String)", "a");
put("net.minecraft.nbt.CompoundTag#put(java.lang.String,net.minecraft.nbt.Tag)", "a");
put("net.minecraft.nbt.CompoundTag#getByte(java.lang.String)", "f");
put("net.minecraft.nbt.CompoundTag#putIntArray(java.lang.String,int[])", "a");
put("net.minecraft.nbt.CompoundTag#getShort(java.lang.String)", "g");
put("net.minecraft.nbt.CompoundTag#putByte(java.lang.String,byte)", "a");
put("net.minecraft.nbt.CompoundTag#getAllKeys()", "d");
put("net.minecraft.nbt.CompoundTag#getAllKeys()", "d");
put("net.minecraft.nbt.CompoundTag#putUUID(java.lang.String,java.util.UUID)", "a");
put("net.minecraft.nbt.CompoundTag#putShort(java.lang.String,short)", "a");
put("net.minecraft.nbt.CompoundTag#getLong(java.lang.String)", "i");
put("net.minecraft.nbt.CompoundTag#putFloat(java.lang.String,float)", "a");
put("net.minecraft.nbt.CompoundTag#getBoolean(java.lang.String)", "q");
put("net.minecraft.nbt.CompoundTag#getUUID(java.lang.String)", "a");
put("net.minecraft.nbt.CompoundTag#getFloat(java.lang.String)", "j");
put("net.minecraft.nbt.ListTag#addTag(int,net.minecraft.nbt.Tag)", "b");
put("net.minecraft.nbt.ListTag#setTag(int,net.minecraft.nbt.Tag)", "a");
put("net.minecraft.nbt.ListTag#getString(int)", "j");
put("net.minecraft.nbt.ListTag#remove(int)", "remove");
put("net.minecraft.nbt.ListTag#getCompound(int)", "a");
put("net.minecraft.nbt.ListTag#size()", "size");
put("net.minecraft.nbt.ListTag#get(int)", "get");
put("net.minecraft.nbt.NbtIo#readCompressed(java.io.InputStream)", "a");
put("net.minecraft.nbt.NbtIo#writeCompressed(net.minecraft.nbt.CompoundTag,java.io.OutputStream)", "a");
put("net.minecraft.nbt.NbtUtils#readGameProfile(net.minecraft.nbt.CompoundTag)", "a");
put("net.minecraft.nbt.NbtUtils#writeGameProfile(net.minecraft.nbt.CompoundTag,com.mojang.authlib.GameProfile)", "a");
put("net.minecraft.nbt.TagParser#parseTag(java.lang.String)", "a");
put("net.minecraft.world.entity.Entity#getEncodeId()", "bk");
put("net.minecraft.world.entity.Entity#load(net.minecraft.nbt.CompoundTag)", "g");
put("net.minecraft.world.entity.Entity#saveWithoutId(net.minecraft.nbt.CompoundTag)", "f");
put("net.minecraft.world.item.ItemStack#setTag(net.minecraft.nbt.CompoundTag)", "c");
put("net.minecraft.world.item.ItemStack#getTag()", "s");
put("net.minecraft.world.item.ItemStack#save(net.minecraft.nbt.CompoundTag)", "b");
put("net.minecraft.world.level.block.entity.BlockEntity#saveWithId()", "n");
put("net.minecraft.world.level.block.entity.BlockEntity#getBlockState()", "q");
put("net.minecraft.world.level.block.entity.BlockEntity#load(net.minecraft.nbt.CompoundTag)", "a");
put("net.minecraft.server.level.ServerLevel#getBlockEntity(net.minecraft.core.BlockPos)", "c_");
}
};
public static Map<String, String> getMapping(){
return MC1_18R1;
}
}
@@ -3,6 +3,7 @@ package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.UUID;
import org.bukkit.inventory.ItemStack;
@@ -19,101 +20,102 @@ import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
@SuppressWarnings("javadoc")
public enum ReflectionMethod {
COMPOUND_SET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, float.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setFloat")),
COMPOUND_SET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setString")),
COMPOUND_SET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setInt")),
COMPOUND_SET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, byte[].class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByteArray")),
COMPOUND_SET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, int[].class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setIntArray")),
COMPOUND_SET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, long.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setLong")),
COMPOUND_SET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, short.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setShort")),
COMPOUND_SET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, byte.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByte")),
COMPOUND_SET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, double.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setDouble")),
COMPOUND_SET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, boolean.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setBoolean")),
COMPOUND_SET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, UUID.class}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a")),
COMPOUND_MERGE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a")), //FIXME: No Spigot mapping!
COMPOUND_SET(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "set")),
COMPOUND_GET(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get")),
COMPOUND_GET_LIST(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getList")),
COMPOUND_OWN_TYPE(ClassWrapper.NMS_NBTBASE.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTypeId")), // Only needed for 1.7.10 getType
COMPOUND_SET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, float.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setFloat"), new Since(MinecraftVersion.MC1_18_R1, "putFloat(java.lang.String,float)")),
COMPOUND_SET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setString"), new Since(MinecraftVersion.MC1_18_R1, "putString(java.lang.String,java.lang.String)")),
COMPOUND_SET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setInt"), new Since(MinecraftVersion.MC1_18_R1, "putInt(java.lang.String,int)")),
COMPOUND_SET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, byte[].class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByteArray"), new Since(MinecraftVersion.MC1_18_R1, "putByteArray(java.lang.String,byte[])")),
COMPOUND_SET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, int[].class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setIntArray"), new Since(MinecraftVersion.MC1_18_R1, "putIntArray(java.lang.String,int[])")),
COMPOUND_SET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, long.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setLong"), new Since(MinecraftVersion.MC1_18_R1, "putLong(java.lang.String,long)")),
COMPOUND_SET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, short.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setShort"), new Since(MinecraftVersion.MC1_18_R1, "putShort(java.lang.String,short)")),
COMPOUND_SET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, byte.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByte"), new Since(MinecraftVersion.MC1_18_R1, "putByte(java.lang.String,byte)")),
COMPOUND_SET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, double.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setDouble"), new Since(MinecraftVersion.MC1_18_R1, "putDouble(java.lang.String,double)")),
COMPOUND_SET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, boolean.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setBoolean"), new Since(MinecraftVersion.MC1_18_R1, "putBoolean(java.lang.String,boolean)")),
COMPOUND_SET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, UUID.class}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a"), new Since(MinecraftVersion.MC1_18_R1, "putUUID(java.lang.String,java.util.UUID)")),
COMPOUND_MERGE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_18_R1, "put(java.lang.String,net.minecraft.nbt.Tag)")),
COMPOUND_SET(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "set"), new Since(MinecraftVersion.MC1_18_R1, "put(java.lang.String,net.minecraft.nbt.Tag)")),
COMPOUND_GET(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get"), new Since(MinecraftVersion.MC1_18_R1, "get(java.lang.String)")),
COMPOUND_GET_LIST(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class, int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getList"), new Since(MinecraftVersion.MC1_18_R1, "getList(java.lang.String,int)")),
COMPOUND_OWN_TYPE(ClassWrapper.NMS_NBTBASE, new Class[]{}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTypeId")), // Only needed for 1.7.10 getType
COMPOUND_GET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getFloat")),
COMPOUND_GET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString")),
COMPOUND_GET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getInt")),
COMPOUND_GET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByteArray")),
COMPOUND_GET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getIntArray")),
COMPOUND_GET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getLong")),
COMPOUND_GET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getShort")),
COMPOUND_GET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByte")),
COMPOUND_GET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getDouble")),
COMPOUND_GET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getBoolean")),
COMPOUND_GET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a")),
COMPOUND_GET_COMPOUND(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getCompound")),
COMPOUND_GET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getFloat"), new Since(MinecraftVersion.MC1_18_R1, "getFloat(java.lang.String)")),
COMPOUND_GET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString"), new Since(MinecraftVersion.MC1_18_R1, "getString(java.lang.String)")),
COMPOUND_GET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getInt"), new Since(MinecraftVersion.MC1_18_R1, "getInt(java.lang.String)")),
COMPOUND_GET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByteArray"), new Since(MinecraftVersion.MC1_18_R1, "getByteArray(java.lang.String)")),
COMPOUND_GET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getIntArray"), new Since(MinecraftVersion.MC1_18_R1, "getIntArray(java.lang.String)")),
COMPOUND_GET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getLong"), new Since(MinecraftVersion.MC1_18_R1, "getLong(java.lang.String)")),
COMPOUND_GET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getShort"), new Since(MinecraftVersion.MC1_18_R1, "getShort(java.lang.String)")),
COMPOUND_GET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByte"), new Since(MinecraftVersion.MC1_18_R1, "getByte(java.lang.String)")),
COMPOUND_GET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getDouble"), new Since(MinecraftVersion.MC1_18_R1, "getDouble(java.lang.String)")),
COMPOUND_GET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getBoolean"), new Since(MinecraftVersion.MC1_18_R1, "getBoolean(java.lang.String)")),
COMPOUND_GET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a"), new Since(MinecraftVersion.MC1_18_R1, "getUUID(java.lang.String)")),
COMPOUND_GET_COMPOUND(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getCompound"), new Since(MinecraftVersion.MC1_18_R1, "getCompound(java.lang.String)")),
NMSITEM_GETTAG(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[] {}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTag")),
NMSITEM_SAVE(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[] {ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "save")),
NMSITEM_CREATESTACK(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[] {ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_10_R1, new Since(MinecraftVersion.MC1_7_R4, "createStack")),
NMSITEM_GETTAG(ClassWrapper.NMS_ITEMSTACK, new Class[] {}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTag"), new Since(MinecraftVersion.MC1_18_R1, "getTag()")),
NMSITEM_SAVE(ClassWrapper.NMS_ITEMSTACK, new Class[] {ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "save"), new Since(MinecraftVersion.MC1_18_R1, "save(net.minecraft.nbt.CompoundTag)")),
NMSITEM_CREATESTACK(ClassWrapper.NMS_ITEMSTACK, new Class[] {ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_10_R1, new Since(MinecraftVersion.MC1_7_R4, "createStack")),
COMPOUND_REMOVE_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "remove")),
COMPOUND_HAS_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "hasKey")),
COMPOUND_GET_TYPE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "b"), new Since(MinecraftVersion.MC1_9_R1, "d"), new Since(MinecraftVersion.MC1_15_R1, "e"), new Since(MinecraftVersion.MC1_16_R1, "d")), //FIXME: No Spigot mapping!
COMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys")),
COMPOUND_REMOVE_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "remove"), new Since(MinecraftVersion.MC1_18_R1, "remove(java.lang.String)")),
COMPOUND_HAS_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "hasKey"), new Since(MinecraftVersion.MC1_18_R1, "contains(java.lang.String)")),
COMPOUND_GET_TYPE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{String.class}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "b"), new Since(MinecraftVersion.MC1_9_R1, "d"), new Since(MinecraftVersion.MC1_15_R1, "e"), new Since(MinecraftVersion.MC1_16_R1, "d"), new Since(MinecraftVersion.MC1_18_R1, "getTagType(java.lang.String)")),
COMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys"), new Since(MinecraftVersion.MC1_18_R1, "getAllKeys()")),
LISTCOMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys")),
LIST_REMOVE_KEY(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_9_R1, "remove")),
LIST_SIZE(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "size")),
LIST_SET(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_13_R1, "set")),
LEGACY_LIST_ADD(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_13_R2, new Since(MinecraftVersion.MC1_7_R4, "add")),
LIST_ADD(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "add")),
LIST_GET_STRING(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString")),
LIST_GET_COMPOUND(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get")),
LIST_GET(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get"), new Since(MinecraftVersion.MC1_8_R3, "g"), new Since(MinecraftVersion.MC1_9_R1, "h"), new Since(MinecraftVersion.MC1_12_R1, "i"), new Since(MinecraftVersion.MC1_13_R1, "get")),
LISTCOMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys"), new Since(MinecraftVersion.MC1_18_R1, "getAllKeys()")), // FIXME ?!?
LIST_REMOVE_KEY(ClassWrapper.NMS_NBTTAGLIST, new Class[]{int.class}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_9_R1, "remove"), new Since(MinecraftVersion.MC1_18_R1, "remove(int)")),
LIST_SIZE(ClassWrapper.NMS_NBTTAGLIST, new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "size"), new Since(MinecraftVersion.MC1_18_R1, "size()")),
LIST_SET(ClassWrapper.NMS_NBTTAGLIST, new Class[]{int.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_13_R1, "set"), new Since(MinecraftVersion.MC1_18_R1, "setTag(int,net.minecraft.nbt.Tag)")),
LEGACY_LIST_ADD(ClassWrapper.NMS_NBTTAGLIST, new Class[]{ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_13_R2, new Since(MinecraftVersion.MC1_7_R4, "add")),
LIST_ADD(ClassWrapper.NMS_NBTTAGLIST, new Class[]{int.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "add"), new Since(MinecraftVersion.MC1_18_R1, "addTag(int,net.minecraft.nbt.Tag)")),
LIST_GET_STRING(ClassWrapper.NMS_NBTTAGLIST, new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString"), new Since(MinecraftVersion.MC1_18_R1, "getString(int)")),
LIST_GET_COMPOUND(ClassWrapper.NMS_NBTTAGLIST, new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get"), new Since(MinecraftVersion.MC1_18_R1, "getCompound(int)")),
LIST_GET(ClassWrapper.NMS_NBTTAGLIST, new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get"), new Since(MinecraftVersion.MC1_8_R3, "g"), new Since(MinecraftVersion.MC1_9_R1, "h"), new Since(MinecraftVersion.MC1_12_R1, "i"), new Since(MinecraftVersion.MC1_13_R1, "get"), new Since(MinecraftVersion.MC1_18_R1, "get(int)")),
ITEMSTACK_SET_TAG(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setTag")),
ITEMSTACK_NMSCOPY(ClassWrapper.CRAFT_ITEMSTACK.getClazz(), new Class[]{ItemStack.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asNMSCopy")),
ITEMSTACK_BUKKITMIRROR(ClassWrapper.CRAFT_ITEMSTACK.getClazz(), new Class[]{ClassWrapper.NMS_ITEMSTACK.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asCraftMirror")),
ITEMSTACK_SET_TAG(ClassWrapper.NMS_ITEMSTACK, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setTag"), new Since(MinecraftVersion.MC1_18_R1, "setTag(net.minecraft.nbt.CompoundTag)")),
ITEMSTACK_NMSCOPY(ClassWrapper.CRAFT_ITEMSTACK, new Class[]{ItemStack.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asNMSCopy")),
ITEMSTACK_BUKKITMIRROR(ClassWrapper.CRAFT_ITEMSTACK, new Class[]{ClassWrapper.NMS_ITEMSTACK.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asCraftMirror")),
CRAFT_WORLD_GET_HANDLE(ClassWrapper.CRAFT_WORLD.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
NMS_WORLD_GET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "getTileEntity")),
NMS_WORLD_SET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz(), ClassWrapper.NMS_TILEENTITY.getClazz()}, MinecraftVersion.MC1_8_R3, MinecraftVersion.MC1_16_R3, new Since(MinecraftVersion.MC1_8_R3, "setTileEntity")),
NMS_WORLD_REMOVE_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "t"), new Since(MinecraftVersion.MC1_9_R1, "s"), new Since(MinecraftVersion.MC1_13_R1, "n"), new Since(MinecraftVersion.MC1_14_R1, "removeTileEntity")),
CRAFT_WORLD_GET_HANDLE(ClassWrapper.CRAFT_WORLD, new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
NMS_WORLD_GET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER, new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "getTileEntity"), new Since(MinecraftVersion.MC1_18_R1, "getBlockEntity(net.minecraft.core.BlockPos)")),
NMS_WORLD_SET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER, new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz(), ClassWrapper.NMS_TILEENTITY.getClazz()}, MinecraftVersion.MC1_8_R3, MinecraftVersion.MC1_16_R3, new Since(MinecraftVersion.MC1_8_R3, "setTileEntity")),
NMS_WORLD_REMOVE_TILEENTITY(ClassWrapper.NMS_WORLDSERVER, new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz()}, MinecraftVersion.MC1_8_R3, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_8_R3, "t"), new Since(MinecraftVersion.MC1_9_R1, "s"), new Since(MinecraftVersion.MC1_13_R1, "n"), new Since(MinecraftVersion.MC1_14_R1, "removeTileEntity")),
NMS_WORLD_GET_TILEENTITY_1_7_10(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{int.class, int.class, int.class}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTileEntity")),
NMS_WORLD_GET_TILEENTITY_1_7_10(ClassWrapper.NMS_WORLDSERVER, new Class[]{int.class, int.class, int.class}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTileEntity")),
TILEENTITY_LOAD_LEGACY191(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_MINECRAFTSERVER.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_9_R1, MinecraftVersion.MC1_9_R1, new Since(MinecraftVersion.MC1_9_R1, "a")), //FIXME: No Spigot mapping!
TILEENTITY_LOAD_LEGACY183(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, MinecraftVersion.MC1_9_R2, new Since(MinecraftVersion.MC1_8_R3, "c"), new Since(MinecraftVersion.MC1_9_R1, "a"), new Since(MinecraftVersion.MC1_9_R2, "c")), //FIXME: No Spigot mapping!
TILEENTITY_LOAD_LEGACY1121(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_WORLD.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_10_R1, MinecraftVersion.MC1_12_R1, new Since(MinecraftVersion.MC1_10_R1, "a"), new Since(MinecraftVersion.MC1_12_R1, "create")),
TILEENTITY_LOAD_LEGACY1151(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_13_R1, MinecraftVersion.MC1_15_R1, new Since(MinecraftVersion.MC1_12_R1, "create")),
TILEENTITY_LOAD(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_IBLOCKDATA.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_16_R1, MinecraftVersion.MC1_16_R3, new Since(MinecraftVersion.MC1_16_R1, "create")),
TILEENTITY_LOAD_LEGACY191(ClassWrapper.NMS_TILEENTITY, new Class[]{ClassWrapper.NMS_MINECRAFTSERVER.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_9_R1, MinecraftVersion.MC1_9_R1, new Since(MinecraftVersion.MC1_9_R1, "a")), //FIXME: No Spigot mapping!
TILEENTITY_LOAD_LEGACY183(ClassWrapper.NMS_TILEENTITY, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, MinecraftVersion.MC1_9_R2, new Since(MinecraftVersion.MC1_8_R3, "c"), new Since(MinecraftVersion.MC1_9_R1, "a"), new Since(MinecraftVersion.MC1_9_R2, "c")), //FIXME: No Spigot mapping!
TILEENTITY_LOAD_LEGACY1121(ClassWrapper.NMS_TILEENTITY, new Class[]{ClassWrapper.NMS_WORLD.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_10_R1, MinecraftVersion.MC1_12_R1, new Since(MinecraftVersion.MC1_10_R1, "a"), new Since(MinecraftVersion.MC1_12_R1, "create")),
TILEENTITY_LOAD_LEGACY1151(ClassWrapper.NMS_TILEENTITY, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_13_R1, MinecraftVersion.MC1_15_R1, new Since(MinecraftVersion.MC1_12_R1, "create")),
TILEENTITY_LOAD(ClassWrapper.NMS_TILEENTITY, new Class[]{ClassWrapper.NMS_IBLOCKDATA.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_16_R1, MinecraftVersion.MC1_16_R3, new Since(MinecraftVersion.MC1_16_R1, "create")),
TILEENTITY_GET_NBT(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "b"), new Since(MinecraftVersion.MC1_9_R1, "save")),
TILEENTITY_SET_NBT_LEGACY1151(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_15_R1, new Since(MinecraftVersion.MC1_7_R4, "a"), new Since(MinecraftVersion.MC1_12_R1, "load")),
TILEENTITY_SET_NBT_LEGACY1161(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_IBLOCKDATA.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_16_R1, MinecraftVersion.MC1_16_R3, new Since(MinecraftVersion.MC1_16_R1, "load")),
TILEENTITY_SET_NBT(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_16_R1, "load")),
TILEENTITY_GET_BLOCKDATA(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "getBlock")),
TILEENTITY_GET_NBT(ClassWrapper.NMS_TILEENTITY, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_7_R4, "b"), new Since(MinecraftVersion.MC1_9_R1, "save")),
TILEENTITY_GET_NBT_1181(ClassWrapper.NMS_TILEENTITY, new Class[]{}, MinecraftVersion.MC1_18_R1, new Since(MinecraftVersion.MC1_18_R1, "saveWithId()")),
TILEENTITY_SET_NBT_LEGACY1151(ClassWrapper.NMS_TILEENTITY, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_15_R1, new Since(MinecraftVersion.MC1_7_R4, "a"), new Since(MinecraftVersion.MC1_12_R1, "load")),
TILEENTITY_SET_NBT_LEGACY1161(ClassWrapper.NMS_TILEENTITY, new Class[]{ClassWrapper.NMS_IBLOCKDATA.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_16_R1, MinecraftVersion.MC1_16_R3, new Since(MinecraftVersion.MC1_16_R1, "load")),
TILEENTITY_SET_NBT(ClassWrapper.NMS_TILEENTITY, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_16_R1, "load"), new Since(MinecraftVersion.MC1_18_R1, "load(net.minecraft.nbt.CompoundTag)")),
TILEENTITY_GET_BLOCKDATA(ClassWrapper.NMS_TILEENTITY, new Class[]{}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "getBlock"), new Since(MinecraftVersion.MC1_18_R1, "getBlockState()")),
CRAFT_ENTITY_GET_HANDLE(ClassWrapper.CRAFT_ENTITY.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
NMS_ENTITY_SET_NBT(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "f"), new Since(MinecraftVersion.MC1_16_R1, "load")), //FIXME: No Spigot mapping!
NMS_ENTITY_GET_NBT(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "e"), new Since(MinecraftVersion.MC1_12_R1, "save")),
NMS_ENTITY_GETSAVEID(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{}, MinecraftVersion.MC1_14_R1,new Since(MinecraftVersion.MC1_14_R1, "getSaveID")),
CRAFT_ENTITY_GET_HANDLE(ClassWrapper.CRAFT_ENTITY, new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
NMS_ENTITY_SET_NBT(ClassWrapper.NMS_ENTITY, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "f"), new Since(MinecraftVersion.MC1_16_R1, "load"), new Since(MinecraftVersion.MC1_18_R1, "load(net.minecraft.nbt.CompoundTag)")),
NMS_ENTITY_GET_NBT(ClassWrapper.NMS_ENTITY, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "e"), new Since(MinecraftVersion.MC1_12_R1, "save"), new Since(MinecraftVersion.MC1_18_R1, "saveWithoutId(net.minecraft.nbt.CompoundTag)")),
NMS_ENTITY_GETSAVEID(ClassWrapper.NMS_ENTITY, new Class[]{}, MinecraftVersion.MC1_14_R1,new Since(MinecraftVersion.MC1_14_R1, "getSaveID"), new Since(MinecraftVersion.MC1_18_R1, "getEncodeId()")),
NBTFILE_READ(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS.getClazz(), new Class[]{InputStream.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a")), //FIXME: No Spigot mapping!
NBTFILE_WRITE(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), OutputStream.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a")), //FIXME: No Spigot mapping!
NBTFILE_READ(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS, new Class[]{InputStream.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a"), new Since(MinecraftVersion.MC1_18_R1, "readCompressed(java.io.InputStream)")),
NBTFILE_WRITE(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), OutputStream.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a"), new Since(MinecraftVersion.MC1_18_R1, "writeCompressed(net.minecraft.nbt.CompoundTag,java.io.OutputStream)")),
PARSE_NBT(ClassWrapper.NMS_MOJANGSONPARSER.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "parse")),
REGISTRY_KEYSET (ClassWrapper.NMS_REGISTRYSIMPLE.getClazz(), new Class[]{}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "keySet")),
REGISTRY_GET (ClassWrapper.NMS_REGISTRYSIMPLE.getClazz(), new Class[]{Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "get")),
REGISTRY_SET (ClassWrapper.NMS_REGISTRYSIMPLE.getClazz(), new Class[]{Object.class, Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "a")), //FIXME: No Spigot mapping!
REGISTRY_GET_INVERSE (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "b")), //FIXME: No Spigot mapping!
REGISTRYMATERIALS_KEYSET (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{}, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_13_R1, "keySet")),
REGISTRYMATERIALS_GET (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{ClassWrapper.NMS_MINECRAFTKEY.getClazz()}, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_13_R1, "get")),
REGISTRYMATERIALS_GETKEY (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{Object.class}, MinecraftVersion.MC1_13_R2, new Since(MinecraftVersion.MC1_13_R2, "getKey")),
PARSE_NBT(ClassWrapper.NMS_MOJANGSONPARSER, new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "parse"), new Since(MinecraftVersion.MC1_18_R1, "parseTag(java.lang.String)")),
REGISTRY_KEYSET (ClassWrapper.NMS_REGISTRYSIMPLE, new Class[]{}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "keySet")),
REGISTRY_GET (ClassWrapper.NMS_REGISTRYSIMPLE, new Class[]{Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "get")),
REGISTRY_SET (ClassWrapper.NMS_REGISTRYSIMPLE, new Class[]{Object.class, Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "a")), //FIXME: No Spigot mapping!
REGISTRY_GET_INVERSE (ClassWrapper.NMS_REGISTRYMATERIALS, new Class[]{Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "b")), //FIXME: No Spigot mapping!
REGISTRYMATERIALS_KEYSET (ClassWrapper.NMS_REGISTRYMATERIALS, new Class[]{}, MinecraftVersion.MC1_13_R1, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_13_R1, "keySet")),
REGISTRYMATERIALS_GET (ClassWrapper.NMS_REGISTRYMATERIALS, new Class[]{ClassWrapper.NMS_MINECRAFTKEY.getClazz()}, MinecraftVersion.MC1_13_R1, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_13_R1, "get")),
REGISTRYMATERIALS_GETKEY (ClassWrapper.NMS_REGISTRYMATERIALS, new Class[]{Object.class}, MinecraftVersion.MC1_13_R2, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_13_R2, "getKey")),
GAMEPROFILE_DESERIALIZE (ClassWrapper.NMS_GAMEPROFILESERIALIZER.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "deserialize")),
GAMEPROFILE_SERIALIZE (ClassWrapper.NMS_GAMEPROFILESERIALIZER.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), ClassWrapper.GAMEPROFILE.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "serialize")),
GAMEPROFILE_DESERIALIZE (ClassWrapper.NMS_GAMEPROFILESERIALIZER, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "deserialize"), new Since(MinecraftVersion.MC1_18_R1, "readGameProfile(net.minecraft.nbt.CompoundTag)")),
GAMEPROFILE_SERIALIZE (ClassWrapper.NMS_GAMEPROFILESERIALIZER, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), ClassWrapper.GAMEPROFILE.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "serialize"), new Since(MinecraftVersion.MC1_18_R1, "writeGameProfile(net.minecraft.nbt.CompoundTag,com.mojang.authlib.GameProfile)")),
CRAFT_PERSISTENT_DATA_CONTAINER_TO_TAG (ClassWrapper.CRAFT_PERSISTENTDATACONTAINER.getClazz(), new Class[]{}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "toTagCompound")),
CRAFT_PERSISTENT_DATA_CONTAINER_GET_MAP (ClassWrapper.CRAFT_PERSISTENTDATACONTAINER.getClazz(), new Class[]{}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "getRaw")),
CRAFT_PERSISTENT_DATA_CONTAINER_PUT_ALL (ClassWrapper.CRAFT_PERSISTENTDATACONTAINER.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "putAll")),
CRAFT_PERSISTENT_DATA_CONTAINER_TO_TAG (ClassWrapper.CRAFT_PERSISTENTDATACONTAINER, new Class[]{}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "toTagCompound")),
CRAFT_PERSISTENT_DATA_CONTAINER_GET_MAP (ClassWrapper.CRAFT_PERSISTENTDATACONTAINER, new Class[]{}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "getRaw")),
CRAFT_PERSISTENT_DATA_CONTAINER_PUT_ALL (ClassWrapper.CRAFT_PERSISTENTDATACONTAINER, new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "putAll")),
;
private MinecraftVersion removedAfter;
@@ -122,9 +124,11 @@ public enum ReflectionMethod {
private boolean loaded = false;
private boolean compatible = false;
private String methodName = null;
private ClassWrapper parentClassWrapper;
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, MinecraftVersion removedAfter, Since... methodnames){
ReflectionMethod(ClassWrapper targetClass, Class<?>[] args, MinecraftVersion addedSince, MinecraftVersion removedAfter, Since... methodnames){
this.removedAfter = removedAfter;
this.parentClassWrapper = targetClass;
if(!MinecraftVersion.isAtLeastVersion(addedSince) || (this.removedAfter != null && MinecraftVersion.isNewerThan(removedAfter)))return;
compatible = true;
MinecraftVersion server = MinecraftVersion.getVersion();
@@ -134,17 +138,29 @@ public enum ReflectionMethod {
target = s;
}
targetVersion = target;
String targetMethodName = targetVersion.name;
try{
method = targetClass.getMethod(targetVersion.name, args);
if(targetVersion.version.isMojangMapping())
targetMethodName = MojangToMapping.getMapping().getOrDefault(targetClass.getMojangName() + "#" + targetVersion.name, "Unmapped" + targetVersion.name);
method = targetClass.getClazz().getDeclaredMethod(targetMethodName, args);
method.setAccessible(true);
loaded = true;
methodName = targetVersion.name;
}catch(NullPointerException | NoSuchMethodException | SecurityException ex){
System.out.println("[NBTAPI] Unable to find the method '" + targetVersion.name + "' in '" + (targetClass == null ? "null" : targetClass.getSimpleName()) + "' Enum: " + this); //NOSONAR This gets loaded before the logger is loaded
try{
if(targetVersion.version.isMojangMapping())
targetMethodName = MojangToMapping.getMapping().getOrDefault(targetClass.getMojangName() + "#" + targetVersion.name, "Unmapped" + targetVersion.name);
method = targetClass.getClazz().getMethod(targetMethodName, args);
method.setAccessible(true);
loaded = true;
methodName = targetVersion.name;
}catch(NullPointerException | NoSuchMethodException | SecurityException ex2){
System.out.println("[NBTAPI] Unable to find the method '" + targetMethodName + "' in '" + (targetClass.getClazz() == null ? targetClass.getMojangName() : targetClass.getClazz().getSimpleName()) + "' Args: " + Arrays.toString(args) + " Enum: " + this); //NOSONAR This gets loaded before the logger is loaded
}
}
}
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, Since... methodnames){
ReflectionMethod(ClassWrapper targetClass, Class<?>[] args, MinecraftVersion addedSince, Since... methodnames){
this(targetClass, args, addedSince, null, methodnames);
}
@@ -161,7 +177,7 @@ public enum ReflectionMethod {
try{
return method.invoke(target, args);
}catch(Exception ex){
throw new NbtApiException("Error while calling the method '" + methodName + "', loaded: " + loaded + ", Enum: " + this, ex);
throw new NbtApiException("Error while calling the method '" + methodName + "', loaded: " + loaded + ", Enum: " + this + " Passed Class: " + target.getClass(), ex);
}
}
@@ -185,8 +201,19 @@ public enum ReflectionMethod {
public boolean isCompatible() {
return compatible;
}
public Since getSelectedVersionInfo() {
return targetVersion;
}
/**
* @return Get Wrapper of the parent class
*/
public ClassWrapper getParentClassWrapper() {
return parentClassWrapper;
}
protected static class Since{
public static class Since{
public final MinecraftVersion version;
public final String name;
public Since(MinecraftVersion version, String name) {
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
</parent>
<artifactId>item-nbt-api-plugin</artifactId>
<packaging>jar</packaging>
@@ -12,19 +12,19 @@
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>nbt-injector</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>nbt-data-api</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -88,7 +88,7 @@
<!--https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.13.2-R0.1-SNAPSHOT/spigot-1.13.2-R0.1-20191113.201242-53.jar,-->
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.14.4-R0.1-SNAPSHOT/spigot-1.14.4-R0.1-20191224.232152-15.jar,
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.15.2-R0.1-SNAPSHOT/spigot-1.15.2-R0.1-20200625.172449-18.jar,
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.16.5-R0.1-SNAPSHOT/spigot-1.16.5-R0.1-20210514.231722-14.jar
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.16.5-R0.1-SNAPSHOT/spigot-1.16.5-R0.1-20210611.090701-17.jar
</versions>
<works>Success! This version of NBT-API</works>
<error>WARNING! This version of NBT-API</error>
@@ -10,6 +10,7 @@ import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.changeme.nbtapi.utils.VersionChecker;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
import de.tr7zw.nbtapi.plugin.tests.GameprofileTest;
@@ -59,6 +60,7 @@ public class NBTAPI extends JavaPlugin {
getConfig().addDefault("nbtInjector.enabled", false);
getConfig().addDefault("bStats.enabled", true);
getConfig().addDefault("updateCheck.enabled", true);
getConfig().addDefault("silentstart", false);
saveConfig();
if(!getConfig().getBoolean("bStats.enabled")) {
@@ -142,7 +144,11 @@ public class NBTAPI extends JavaPlugin {
public void onEnable() {
instance = this; // NOSONAR
// new MetricsLite(this); The metrics moved into the API
if(getConfig().getBoolean("nbtInjector.enabled")) {
// we are silent, won't check anything or pre-init
VersionChecker.hideOk = true;
return;
}
getLogger().info("Adding listeners...");
Bukkit.getPluginManager().registerEvents(new ReloadListener(), this);
getLogger().info("Gson:");
@@ -194,10 +200,11 @@ public class NBTAPI extends JavaPlugin {
}
for (Entry<de.tr7zw.nbtapi.plugin.tests.Test, Exception> entry : results.entrySet()) {
if (entry.getValue() != null)
if (entry.getValue() != null) {
compatible = false;
getLogger().info(entry.getKey().getClass().getSimpleName() + ": "
+ (entry.getValue() == null ? "Ok" : entry.getValue().getMessage()));
getLogger().info(entry.getKey().getClass().getSimpleName() + ": "
+ entry.getValue().getMessage());
}
}
String checkMessage = "Plugins that don't check properly may throw Exeptions, crash or have unexpected behaviors!";
@@ -31,6 +31,23 @@ public class EqualsTest implements Test{
if(!customData.equals(cont)) {
throw new NbtApiException("Compounds did not match! " + customData + " " + cont);
}
// empty test
if(!new NBTContainer().equals(new NBTContainer())) {
throw new NbtApiException("Two empty tags did not match!");
}
// not equal test
NBTContainer part1 = new NBTContainer();
part1.setString("a", "a");
part1.setString("b", "b");
NBTContainer part2 = new NBTContainer();
part2.setString("a", "a");
part2.setString("b", "a");
if(part1.equals(part2)) {
throw new NbtApiException("Missmatched nbt did match!");
}
}
}
@@ -22,9 +22,11 @@ public class TileTest implements Test {
if (block.getType() == Material.AIR) {
block.setType(Material.CHEST);
NBTTileEntity tile = new NBTTileEntity(block.getState());
if(tile.getInteger("y") != 254) {
block.setType(Material.AIR);
throw new NbtApiException("The Tile Y pos wasn't correct!");
if(!MinecraftVersion.isNewerThan(MinecraftVersion.MC1_17_R1)) {
if(tile.getInteger("y") != 254) {
block.setType(Material.AIR);
throw new NbtApiException("The Tile Y pos wasn't correct!");
}
}
tile.setString("Lock", "test");
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3) && !tile.hasKey("Lock") && !"test".equals(tile.getString("test"))) {
@@ -19,7 +19,7 @@ public class TilesCustomNBTPersistentTest implements Test {
if (!Bukkit.getWorlds().isEmpty()) {
World world = Bukkit.getWorlds().get(0);
try {
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 255,
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 250,
world.getSpawnLocation().getBlockZ());
if (block.getType() == Material.AIR) {
block.setType(Material.CHEST);
+1
View File
@@ -0,0 +1 @@
*.txt
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.9.0</version>
</parent>
<artifactId>mappings-parser</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.9.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean</defaultGoal>
</build>
</project>
@@ -0,0 +1,82 @@
package dev.tr7zw.mappingsparser;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
/**
* Internal class to be used to port SpecialSource mapping txt files to nbt-api internal mappings
*
* @author tr7zw
*
*/
public class MappingsParser {
public static StringBuilder builder = new StringBuilder();
public static void main(String[] args) throws IOException {
File input = new File("minecraft_server.1.18-pre8.txt");
List<String> lines = Files.readAllLines(input.toPath());
Map<String, ClassWrapper> classes = new HashMap<>();
for(ClassWrapper wrapper : ClassWrapper.values()) {
if(wrapper.getMojangName() != null) {
classes.put(wrapper.getMojangName(), wrapper);
}
}
String currentClass = null;
String mojangName = null;
String unmappedName = null;
ClassWrapper nmsWrapper = null;
Map<ReflectionMethod, String> mappedNames = null;
for(String line : lines) {
if(!line.startsWith(" ")) {
if(nmsWrapper != null && mappedNames != null) {
proccessMapping(nmsWrapper, mappedNames);
}
currentClass = line.split(" ")[0];
nmsWrapper = classes.get(currentClass);
mappedNames = new HashMap<>();
for(ReflectionMethod method : ReflectionMethod.values()) {
if(method.getParentClassWrapper() == nmsWrapper && method.isCompatible()) {
mappedNames.put(method, null);
}
}
continue;
}
if(nmsWrapper == null)continue;
mojangName = line.trim().split(" ")[1];
unmappedName = line.trim().split(" ")[3];
classes.remove(currentClass);
for(ReflectionMethod method : mappedNames.keySet()) {
if(method.getSelectedVersionInfo() == null)continue;
if(!mojangName.contains("("))continue;
if(mojangName.equals(method.getSelectedVersionInfo().name)) {
mappedNames.put(method, unmappedName);
}
}
//System.out.println(currentClass + ": " + mojangName + " -> " + unmappedName);
}
System.out.println(builder);
}
public static void proccessMapping(ClassWrapper nmsWrapper, Map<ReflectionMethod, String> mappedNames) {
for(Entry<ReflectionMethod, String> entry : mappedNames.entrySet()) {
if(entry.getValue() == null) {
System.out.println("Missing mapping in class " + nmsWrapper.getMojangName() + " method " + entry.getKey().name());
} else {
builder.append("put(\"" + nmsWrapper.getMojangName() + "#" + entry.getKey().getSelectedVersionInfo().name + "\", \"" + entry.getValue() + "\");\n");
}
}
}
}
+2 -2
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
</parent>
<artifactId>nbt-data-api</artifactId>
@@ -14,7 +14,7 @@
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
</parent>
<artifactId>nbt-injector</artifactId>
<packaging>jar</packaging>
@@ -12,7 +12,7 @@
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
<scope>compile</scope>
</dependency>
<dependency>
+2 -1
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
<packaging>pom</packaging>
<inceptionYear>2015</inceptionYear>
<organization>
@@ -22,6 +22,7 @@
<module>nbt-injector</module>
<module>nbt-data-api</module>
<module>item-nbt-plugin</module>
<module>mappings-parser</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+5 -5
View File
@@ -1,11 +1,11 @@
[B][SIZE=6](Item/Entity/Tile) NBT API[/SIZE][/B]
[URL='https://ci.codemc.io/job/Tr7zw/job/Item-NBT-API/'][IMG]https://ci.codemc.org/buildStatus/icon?job=Tr7zw%2FItem-NBT-API[/IMG][/URL] [URL='https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent'][IMG]https://sonarcloud.io/api/project_badges/measure?project=de.tr7zw%3Aitem-nbt-parent&metric=ncloc[/IMG][/URL] [URL='https://bstats.org/plugin/bukkit/ItemNBTAPI'][IMG]https://img.shields.io/bstats/servers/1058.svg?color=green&label=OnlineServers&style=plastic[/IMG][/URL] [URL='https://bstats.org/plugin/bukkit/ItemNBTAPI'][IMG]https://img.shields.io/bstats/players/1058.svg?color=green&label=OnlinePlayers&style=plastic[/IMG] [/URL][URL='https://discordapp.com/invite/yk4caxM'][IMG]https://img.shields.io/discord/342814924310970398?color=%237289DA&label=Discord&logo=discord&logoColor=white[/IMG][/URL] [IMG]https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Dtr7zw%26type%3Dpatrons&style=for-the-badge[/IMG]
[URL='https://ci.codemc.io/job/Tr7zw/job/Item-NBT-API/'][IMG]https://ci.codemc.org/buildStatus/icon?job=Tr7zw%2FItem-NBT-API[/IMG][/URL] [URL='https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent'][IMG]https://sonarcloud.io/api/project_badges/measure?project=de.tr7zw%3Aitem-nbt-parent&metric=ncloc[/IMG][/URL] [URL='https://bstats.org/plugin/bukkit/ItemNBTAPI'][IMG]https://img.shields.io/bstats/servers/1058.svg?color=green&label=OnlineServers&style=plastic[/IMG][/URL] [URL='https://bstats.org/plugin/bukkit/ItemNBTAPI'][IMG]https://img.shields.io/bstats/players/1058.svg?color=green&label=OnlinePlayers&style=plastic[/IMG] [/URL][URL='https://discordapp.com/invite/yk4caxM'][IMG]https://img.shields.io/discord/342814924310970398?color=%237289DA&label=Discord&logo=discord&logoColor=white[/IMG][/URL]
The NBT API allows you to add custom NBT tags to Itemstacks, TileEntities and Entities, or modify excisting ones!
It completely uses reflections to interact with NMS code and works with all the latest versions. On server start the plugin checks all reflections.
Tested on Spigot
[LIST]
[*](1.7*)1.8.8-1.16.4
[*](1.7*)1.8.8-1.17.*
[*]The NBTInjector will not work with: 1.12.0, 1.12.1, 1.13.0 (Please just update to the final release of your chosen version)
[*]On startup you will get a notification if there is a version problem!
@@ -250,7 +250,8 @@ Output:
[B]This API can't be used for:[/B]
[LIST]
[*][I][SIZE=4][S]Adding custom tags to TileEntities/Entities[/S] [/SIZE][/I][SIZE=4]Not true anymore, check the NBTInjector examples above[/SIZE]
[*][I][SIZE=4][S]Adding custom tags to TileEntities/Entities[/S] [/SIZE][/I][SIZE=4]Not true anymore, check the NBTInjector examples above.*[/SIZE]
*This only is required for <= 1.13, 1.14+ can just use the getPersistentDataContainer method on NBTEntity/NBTTileEntity to store custom data.
[/LIST]
Git: [URL='https://github.com/tr7zw/Item-NBT-API']Github[/URL]
Maven Repo: [URL='https://repo.codemc.org/#browse/browse:maven-public:de%2Ftr7zw%2Fitem-nbt-api-plugin']CodeMC[/URL]
@@ -262,6 +263,7 @@ Yes you are allowed to integrate the API into your plugin(remember to shade)! (S
[B][SIZE=5]Projects using the API(That I know of)[/SIZE]
[U][SIZE=4]Plugins[/SIZE][/U][/B]
[URL='https://www.spigotmc.org/resources/crazy-enchantments.16470/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=16470&[/IMG][/URL]
[URL='https://www.spigotmc.org/resources/levelledmobs-for-1-16-x-1-17-x.74304/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=74304&[/IMG][/URL]
[URL='https://www.spigotmc.org/resources/backpacks.45622/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=45622&[/IMG][/URL]
[URL='https://www.spigotmc.org/resources/gravy.45288/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=45288&[/IMG][/URL]
[URL='https://www.spigotmc.org/resources/interactivebooks.45604/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=45604&[/IMG][/URL]
@@ -270,7 +272,6 @@ Yes you are allowed to integrate the API into your plugin(remember to shade)! (S
[URL='https://www.spigotmc.org/resources/comparable-hoppers-2.45058/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=45058&[/IMG][/URL]
[URL='https://www.spigotmc.org/resources/nottooexpensive.62680/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=62680&[/IMG][/URL]
[URL='https://www.spigotmc.org/resources/papermoney.70361/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=70361&[/IMG][/URL]
[URL='https://www.spigotmc.org/resources/blockstackerx-plugin-for-askyblock.71514/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=71514&[/IMG][/URL]
[URL='https://www.spigotmc.org/resources/blockstackerx-recoded.73749/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=73749[/IMG][/URL]
[URL='https://www.spigotmc.org/resources/63020/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=63020&reload[/IMG][/URL]
[URL='https://www.spigotmc.org/resources/72810/'][IMG]https://tr7zw.dev/nbtapi/linkedProjects.php?id=72810&reload[/IMG][/URL]
@@ -279,7 +280,6 @@ Yes you are allowed to integrate the API into your plugin(remember to shade)! (S
[U][B]Other[/B][/U]
- [URL='https://github.com/LogisticsCraft/Logistics-API']Logistics-API[/URL]
If you like this Resource, donate me a Coffee or become a Patreon for cool perks! [URL='https://tr7zw.dev/donate/']Donating[/URL]
[SIZE=4][SIZE=4][U][B]Donators[/B][/U]
[U][B][URL='https://www.spigotmc.org/members/mrdienns.35704/'][IMG]https://tr7zw.dev/nbtapi/spigotPeople.php?id=35704[/IMG][/URL] [/B][/U]
[U][B][URL='https://www.spigotmc.org/members/mraxetv.27720/'][IMG]https://tr7zw.dev/nbtapi/spigotPeople.php?id=27720[/IMG][/URL] [/B][/U]