mirror of
https://github.com/tr7zw/Item-NBT-API.git
synced 2026-11-14 04:42:02 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e769113e51 |
No files matched your search
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>item-nbt-api</artifactId>
|
||||
|
||||
+183
-183
@@ -1,183 +1,183 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.logger;
|
||||
|
||||
/**
|
||||
* This class caches method reflections, keeps track of method name changes between versions and allows early checking for problems
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@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_MERGE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "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_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_COMPOUND(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getCompound")),
|
||||
|
||||
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")),
|
||||
|
||||
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")), //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")),
|
||||
|
||||
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_7_R4, new Since(MinecraftVersion.MC1_7_R4, "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_7_R4, new Since(MinecraftVersion.MC1_7_R4, "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, "g"), new Since(MinecraftVersion.MC1_9_R1, "h"), new Since(MinecraftVersion.MC1_12_R1, "i"), new Since(MinecraftVersion.MC1_13_R1, "get")),
|
||||
|
||||
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")),
|
||||
|
||||
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_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTileEntity")),
|
||||
NMS_WORLD_SET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz(), ClassWrapper.NMS_TILEENTITY.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setTileEntity")),
|
||||
NMS_WORLD_REMOVE_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "t"), new Since(MinecraftVersion.MC1_9_R1, "s"), new Since(MinecraftVersion.MC1_13_R1, "n"), new Since(MinecraftVersion.MC1_14_R1, "removeTileEntity")),
|
||||
|
||||
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(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_12_R1, "create")),
|
||||
|
||||
TILEENTITY_GET_NBT(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "b"), new Since(MinecraftVersion.MC1_9_R1, "save")),
|
||||
TILEENTITY_SET_NBT(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_12_R1, "load")),
|
||||
|
||||
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_8_R3, new Since(MinecraftVersion.MC1_8_R3, "f")), //FIXME: No Spigot mapping!
|
||||
NMS_ENTITY_GET_NBT(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "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")),
|
||||
|
||||
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!
|
||||
|
||||
|
||||
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")),
|
||||
|
||||
|
||||
;
|
||||
|
||||
private MinecraftVersion removedAfter;
|
||||
private Since targetVersion;
|
||||
private Method method;
|
||||
private boolean loaded = false;
|
||||
private boolean compatible = false;
|
||||
private String methodName = null;
|
||||
|
||||
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, MinecraftVersion removedAfter, Since... methodnames){
|
||||
this.removedAfter = removedAfter;
|
||||
MinecraftVersion server = MinecraftVersion.getVersion();
|
||||
if(server.compareTo(addedSince) < 0 || (this.removedAfter != null && server.getVersionId() > this.removedAfter.getVersionId()))return;
|
||||
compatible = true;
|
||||
Since target = methodnames[0];
|
||||
for(Since s : methodnames){
|
||||
if(s.version.getVersionId() <= server.getVersionId() && target.version.getVersionId() < s.version.getVersionId())
|
||||
target = s;
|
||||
}
|
||||
targetVersion = target;
|
||||
try{
|
||||
method = targetClass.getMethod(targetVersion.name, args);
|
||||
method.setAccessible(true);
|
||||
loaded = true;
|
||||
methodName = targetVersion.name;
|
||||
}catch(NullPointerException | NoSuchMethodException | SecurityException ex){
|
||||
logger.log(Level.SEVERE, "Unable to find the method '" + targetVersion.name + "' in '" + targetClass.getSimpleName() + "'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, Since... methodnames){
|
||||
this(targetClass, args, addedSince, null, methodnames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the method on a given target object using the given args.
|
||||
*
|
||||
* @param target
|
||||
* @param args
|
||||
* @return Value returned by the method
|
||||
*/
|
||||
public Object run(Object target, Object... args){
|
||||
try{
|
||||
return method.invoke(target, args);
|
||||
}catch(Exception ex){
|
||||
throw new NbtApiException("Error while calling the method '" + methodName + "', loaded: " + loaded + ".", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The MethodName, used in this Minecraft Version
|
||||
*/
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Has this method been linked
|
||||
*/
|
||||
public boolean isLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Is this method available in this Minecraft Version
|
||||
*/
|
||||
public boolean isCompatible() {
|
||||
return compatible;
|
||||
}
|
||||
|
||||
protected static class Since{
|
||||
public final MinecraftVersion version;
|
||||
public final String name;
|
||||
public Since(MinecraftVersion version, String name) {
|
||||
this.version = version;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.logger;
|
||||
|
||||
/**
|
||||
* This class caches method reflections, keeps track of method name changes between versions and allows early checking for problems
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@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_MERGE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "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_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_COMPOUND(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getCompound")),
|
||||
|
||||
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")),
|
||||
|
||||
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")), //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")),
|
||||
|
||||
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_7_R4, new Since(MinecraftVersion.MC1_7_R4, "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_7_R4, new Since(MinecraftVersion.MC1_7_R4, "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, "g"), new Since(MinecraftVersion.MC1_9_R1, "h"), new Since(MinecraftVersion.MC1_12_R1, "i"), new Since(MinecraftVersion.MC1_13_R1, "get")),
|
||||
|
||||
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")),
|
||||
|
||||
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_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTileEntity")),
|
||||
NMS_WORLD_SET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz(), ClassWrapper.NMS_TILEENTITY.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setTileEntity")),
|
||||
NMS_WORLD_REMOVE_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "t"), new Since(MinecraftVersion.MC1_9_R1, "s"), new Since(MinecraftVersion.MC1_13_R1, "n"), new Since(MinecraftVersion.MC1_14_R1, "removeTileEntity")),
|
||||
|
||||
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(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_12_R1, "create")),
|
||||
|
||||
TILEENTITY_GET_NBT(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "b"), new Since(MinecraftVersion.MC1_9_R1, "save")),
|
||||
TILEENTITY_SET_NBT(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_12_R1, "load")),
|
||||
|
||||
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_8_R3, new Since(MinecraftVersion.MC1_8_R3, "f")), //FIXME: No Spigot mapping!
|
||||
NMS_ENTITY_GET_NBT(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "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")),
|
||||
|
||||
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!
|
||||
|
||||
|
||||
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")),
|
||||
|
||||
|
||||
;
|
||||
|
||||
private MinecraftVersion removedAfter;
|
||||
private Since targetVersion;
|
||||
private Method method;
|
||||
private boolean loaded = false;
|
||||
private boolean compatible = false;
|
||||
private String methodName = null;
|
||||
|
||||
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, MinecraftVersion removedAfter, Since... methodnames){
|
||||
this.removedAfter = removedAfter;
|
||||
MinecraftVersion server = MinecraftVersion.getVersion();
|
||||
if(server.compareTo(addedSince) < 0 || (this.removedAfter != null && server.getVersionId() > this.removedAfter.getVersionId()))return;
|
||||
compatible = true;
|
||||
Since target = methodnames[0];
|
||||
for(Since s : methodnames){
|
||||
if(s.version.getVersionId() <= server.getVersionId() && target.version.getVersionId() < s.version.getVersionId())
|
||||
target = s;
|
||||
}
|
||||
targetVersion = target;
|
||||
try{
|
||||
method = targetClass.getMethod(targetVersion.name, 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.getSimpleName() + "'"); //NOSONAR This gets loaded before the logger is loaded
|
||||
}
|
||||
}
|
||||
|
||||
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, Since... methodnames){
|
||||
this(targetClass, args, addedSince, null, methodnames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the method on a given target object using the given args.
|
||||
*
|
||||
* @param target
|
||||
* @param args
|
||||
* @return Value returned by the method
|
||||
*/
|
||||
public Object run(Object target, Object... args){
|
||||
try{
|
||||
return method.invoke(target, args);
|
||||
}catch(Exception ex){
|
||||
throw new NbtApiException("Error while calling the method '" + methodName + "', loaded: " + loaded + ".", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The MethodName, used in this Minecraft Version
|
||||
*/
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Has this method been linked
|
||||
*/
|
||||
public boolean isLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Is this method available in this Minecraft Version
|
||||
*/
|
||||
public boolean isCompatible() {
|
||||
return compatible;
|
||||
}
|
||||
|
||||
protected static class Since{
|
||||
public final MinecraftVersion version;
|
||||
public final String name;
|
||||
public Since(MinecraftVersion version, String name) {
|
||||
this.version = version;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<artifactId>item-nbt-api-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
@@ -12,13 +12,13 @@
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-api</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<version>2.1.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>nbt-injector</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<version>2.1.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -73,11 +73,11 @@
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<!-- 1.8.8-R0.1-SNAPSHOT-latest, 1.9.2-R0.1-SNAPSHOT-latest, 1.9.4-R0.1-SNAPSHOT-latest, 1.10.2-R0.1-SNAPSHOT-latest,1.11.2,1.12.2,1.13.2,1.14.1,1.14.2,1.14.3 -->
|
||||
<versions>1.8.8-R0.1-SNAPSHOT-latest, 1.9.2-R0.1-SNAPSHOT-latest, 1.9.4-R0.1-SNAPSHOT-latest, 1.10.2-R0.1-SNAPSHOT-latest,1.11.2,1.12.2,1.13.2,1.14.1,1.14.2,1.14.3</versions>
|
||||
<!-- 1.8.8-R0.1-SNAPSHOT-latest, 1.9.2-R0.1-SNAPSHOT-latest, 1.9.4-R0.1-SNAPSHOT-latest, 1.10.2-R0.1-SNAPSHOT-latest,1.11.2,1.12.2,1.13.2,1.14.1,1.14.2,1.14.3,1.14.4 -->
|
||||
<versions>1.8.8-R0.1-SNAPSHOT-latest, 1.9.2-R0.1-SNAPSHOT-latest, 1.9.4-R0.1-SNAPSHOT-latest, 1.10.2-R0.1-SNAPSHOT-latest,1.11.2,1.12.2,1.13.2,1.14.1,1.14.2,1.14.3,1.14.4</versions>
|
||||
<works>Success! This version of NBT-API</works>
|
||||
<error>WARNING! This version of NBT-API</error>
|
||||
<filename>item-nbt-api-plugin-2.0.0.jar</filename>
|
||||
<filename>item-nbt-api-plugin-2.1.0.jar</filename>
|
||||
<foldername>item-nbt-plugin</foldername>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@@ -1,148 +1,153 @@
|
||||
package de.tr7zw.nbtapi.plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
import de.tr7zw.nbtapi.plugin.tests.NBTFileTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.GetterSetterTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.ListTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.MergeTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.RemovingKeys;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.SubCompoundsTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.TypeTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.entities.EntityCustomNbtTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.entities.EntityTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.EmptyItemTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.ItemConvertionTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.tiles.TilesCustomNBTTest;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class NBTAPI extends JavaPlugin {
|
||||
|
||||
private boolean compatible = true;
|
||||
private ArrayList<de.tr7zw.nbtapi.plugin.tests.Test> apiTests = new ArrayList<>();
|
||||
|
||||
private static NBTAPI instance;
|
||||
|
||||
public static NBTAPI getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
getLogger().info("Injecting custom NBT");
|
||||
try {
|
||||
NBTInjector.inject();
|
||||
getLogger().info("Injected!");
|
||||
} catch (Throwable ex) { // NOSONAR
|
||||
getLogger().log(Level.SEVERE, "Error while Injecting custom Tile/Entity classes!", ex);
|
||||
compatible = false;
|
||||
}
|
||||
|
||||
// NBTCompounds
|
||||
apiTests.add(new GetterSetterTest());
|
||||
apiTests.add(new TypeTest());
|
||||
apiTests.add(new RemovingKeys());
|
||||
apiTests.add(new ListTest());
|
||||
apiTests.add(new SubCompoundsTest());
|
||||
apiTests.add(new MergeTest());
|
||||
|
||||
// Items
|
||||
apiTests.add(new ItemConvertionTest());
|
||||
apiTests.add(new EmptyItemTest());
|
||||
|
||||
// Entity
|
||||
apiTests.add(new EntityTest());
|
||||
apiTests.add(new EntityCustomNbtTest());
|
||||
|
||||
// Tiles
|
||||
apiTests.add(new TilesCustomNBTTest());
|
||||
|
||||
// Files
|
||||
apiTests.add(new NBTFileTest());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this; // NOSONAR
|
||||
// new MetricsLite(this); The metrics moved into the API
|
||||
|
||||
getLogger().info("Checking bindings...");
|
||||
MinecraftVersion.getVersion();
|
||||
getLogger().info("Gson:");
|
||||
MinecraftVersion.hasGsonSupport();
|
||||
getLogger().info("Classes:");
|
||||
boolean classUnlinked = false;
|
||||
for (ClassWrapper c : ClassWrapper.values()) {
|
||||
if (c.isEnabled() && c.getClazz() == null) {
|
||||
getLogger().warning(c.name() + " did not find it's class!");
|
||||
compatible = false;
|
||||
classUnlinked = true;
|
||||
}
|
||||
}
|
||||
if (!classUnlinked)
|
||||
getLogger().info("All Classes where able to link!");
|
||||
|
||||
getLogger().info("Methods:");
|
||||
boolean methodUnlinked = false;
|
||||
for (ReflectionMethod method : ReflectionMethod.values()) {
|
||||
if (method.isCompatible() && !method.isLoaded()) {
|
||||
getLogger().warning(method.name() + " did not find the method!");
|
||||
compatible = false;
|
||||
methodUnlinked = true;
|
||||
}
|
||||
}
|
||||
if (!methodUnlinked)
|
||||
getLogger().info("All Methods where able to link!");
|
||||
getLogger().info("Running NBT reflection test...");
|
||||
|
||||
Map<de.tr7zw.nbtapi.plugin.tests.Test, Exception> results = new HashMap<>();
|
||||
for (de.tr7zw.nbtapi.plugin.tests.Test test : apiTests) {
|
||||
try {
|
||||
test.test();
|
||||
results.put(test, null);
|
||||
} catch (Exception ex) {
|
||||
results.put(test, ex);
|
||||
getLogger().log(Level.WARNING, "Error during '" + test.getClass().getSimpleName() + "' test!", ex);
|
||||
} catch (Throwable th) { // NOSONAR
|
||||
getLogger().log(Level.SEVERE, "Servere error during '" + test.getClass().getSimpleName() + "' test!");
|
||||
getLogger().warning(
|
||||
"WARNING! This version of Item-NBT-API seems to be broken with your Spigot version! Canceled the other tests!");
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<de.tr7zw.nbtapi.plugin.tests.Test, Exception> entry : results.entrySet()) {
|
||||
if (entry.getValue() != null)
|
||||
compatible = false;
|
||||
getLogger().info(entry.getKey().getClass().getSimpleName() + ": "
|
||||
+ (entry.getValue() == null ? "Ok" : entry.getValue().getMessage()));
|
||||
}
|
||||
|
||||
String checkMessage = "Plugins that don't check properly may throw Exeptions, crash or have unexpected behaviors!";
|
||||
if (compatible) {
|
||||
getLogger().info("Success! This version of NBT-API is compatible with your server.");
|
||||
} else {
|
||||
getLogger().warning(
|
||||
"WARNING! This version of NBT-API seems to be broken with your Spigot version! " + checkMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if all selfchecks succeeded
|
||||
*/
|
||||
public boolean isCompatible() {
|
||||
return compatible;
|
||||
}
|
||||
|
||||
}
|
||||
package de.tr7zw.nbtapi.plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
import de.tr7zw.nbtapi.plugin.tests.NBTFileTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.GetterSetterTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.ListTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.MergeTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.RemovingKeys;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.SubCompoundsTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.TypeTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.entities.EntityCustomNbtTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.entities.EntityTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.EmptyItemTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.ItemConvertionTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.tiles.TilesCustomNBTTest;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class NBTAPI extends JavaPlugin {
|
||||
|
||||
private boolean compatible = true;
|
||||
private ArrayList<de.tr7zw.nbtapi.plugin.tests.Test> apiTests = new ArrayList<>();
|
||||
|
||||
private static NBTAPI instance;
|
||||
|
||||
public static NBTAPI getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
|
||||
//Disabled by default since 2.1. Enable it yourself by calling NBTInjector.inject(); during onLoad.
|
||||
/*getLogger().info("Injecting custom NBT");
|
||||
try {
|
||||
NBTInjector.inject();
|
||||
getLogger().info("Injected!");
|
||||
} catch (Throwable ex) { // NOSONAR
|
||||
getLogger().log(Level.SEVERE, "Error while Injecting custom Tile/Entity classes!", ex);
|
||||
compatible = false;
|
||||
}*/
|
||||
|
||||
// NBTCompounds
|
||||
apiTests.add(new GetterSetterTest());
|
||||
apiTests.add(new TypeTest());
|
||||
apiTests.add(new RemovingKeys());
|
||||
apiTests.add(new ListTest());
|
||||
apiTests.add(new SubCompoundsTest());
|
||||
apiTests.add(new MergeTest());
|
||||
|
||||
// Items
|
||||
apiTests.add(new ItemConvertionTest());
|
||||
apiTests.add(new EmptyItemTest());
|
||||
|
||||
// Entity
|
||||
apiTests.add(new EntityTest());
|
||||
apiTests.add(new EntityCustomNbtTest());
|
||||
|
||||
// Tiles
|
||||
apiTests.add(new TilesCustomNBTTest());
|
||||
|
||||
// Files
|
||||
apiTests.add(new NBTFileTest());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this; // NOSONAR
|
||||
// new MetricsLite(this); The metrics moved into the API
|
||||
|
||||
getLogger().info("Adding listeners...");
|
||||
Bukkit.getPluginManager().registerEvents(new ReloadListener(), this);
|
||||
getLogger().info("Checking bindings...");
|
||||
MinecraftVersion.getVersion();
|
||||
getLogger().info("Gson:");
|
||||
MinecraftVersion.hasGsonSupport();
|
||||
getLogger().info("Classes:");
|
||||
boolean classUnlinked = false;
|
||||
for (ClassWrapper c : ClassWrapper.values()) {
|
||||
if (c.isEnabled() && c.getClazz() == null) {
|
||||
getLogger().warning(c.name() + " did not find it's class!");
|
||||
compatible = false;
|
||||
classUnlinked = true;
|
||||
}
|
||||
}
|
||||
if (!classUnlinked)
|
||||
getLogger().info("All Classes where able to link!");
|
||||
|
||||
getLogger().info("Methods:");
|
||||
boolean methodUnlinked = false;
|
||||
for (ReflectionMethod method : ReflectionMethod.values()) {
|
||||
if (method.isCompatible() && !method.isLoaded()) {
|
||||
getLogger().warning(method.name() + " did not find the method!");
|
||||
compatible = false;
|
||||
methodUnlinked = true;
|
||||
}
|
||||
}
|
||||
if (!methodUnlinked)
|
||||
getLogger().info("All Methods where able to link!");
|
||||
getLogger().info("Running NBT reflection test...");
|
||||
|
||||
Map<de.tr7zw.nbtapi.plugin.tests.Test, Exception> results = new HashMap<>();
|
||||
for (de.tr7zw.nbtapi.plugin.tests.Test test : apiTests) {
|
||||
try {
|
||||
test.test();
|
||||
results.put(test, null);
|
||||
} catch (Exception ex) {
|
||||
results.put(test, ex);
|
||||
getLogger().log(Level.WARNING, "Error during '" + test.getClass().getSimpleName() + "' test!", ex);
|
||||
} catch (Throwable th) { // NOSONAR
|
||||
getLogger().log(Level.SEVERE, "Servere error during '" + test.getClass().getSimpleName() + "' test!");
|
||||
getLogger().warning(
|
||||
"WARNING! This version of Item-NBT-API seems to be broken with your Spigot version! Canceled the other tests!");
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<de.tr7zw.nbtapi.plugin.tests.Test, Exception> entry : results.entrySet()) {
|
||||
if (entry.getValue() != null)
|
||||
compatible = false;
|
||||
getLogger().info(entry.getKey().getClass().getSimpleName() + ": "
|
||||
+ (entry.getValue() == null ? "Ok" : entry.getValue().getMessage()));
|
||||
}
|
||||
|
||||
String checkMessage = "Plugins that don't check properly may throw Exeptions, crash or have unexpected behaviors!";
|
||||
if (compatible) {
|
||||
getLogger().info("Success! This version of NBT-API is compatible with your server.");
|
||||
} else {
|
||||
getLogger().warning(
|
||||
"WARNING! This version of NBT-API seems to be broken with your Spigot version! " + checkMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if all selfchecks succeeded
|
||||
*/
|
||||
public boolean isCompatible() {
|
||||
return compatible;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package de.tr7zw.nbtapi.plugin;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
/**
|
||||
* This listener class tries to prevent people from reloading while the NBTInjector is enabled.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class ReloadListener implements Listener{
|
||||
|
||||
/**
|
||||
* Console handler
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
@EventHandler
|
||||
public void onCommand(org.bukkit.event.server.ServerCommandEvent event) {
|
||||
if(event.getCommand().toLowerCase().startsWith("reload") && NBTInjector.isInjected()) {
|
||||
event.setCancelled(true);
|
||||
event.getSender().sendMessage("[NBTAPI] The NBTInjector is currently enabled. Reloading will turn the server into an unstable state and data-loss may accure. Please do a clean restart. Canceled reload!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Player handler
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
@EventHandler
|
||||
public void onCommand(org.bukkit.event.player.PlayerCommandPreprocessEvent event) {
|
||||
if(event.getMessage().toLowerCase().startsWith("/reload") && NBTInjector.isInjected()) {
|
||||
event.setCancelled(true);
|
||||
event.getPlayer().sendMessage("[NBTAPI] The NBTInjector is currently enabled. Reloading will turn the server into an unstable state and data-loss may accure. Please do a clean restart. Canceled reload!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+41
-40
@@ -1,40 +1,41 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.entities;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Monster;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTEntity;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class EntityCustomNbtTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
|
||||
Entity ent = world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next();
|
||||
ent = NBTInjector.patchEntity(ent);
|
||||
NBTCompound comp = NBTInjector.getNbtData(ent);
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(ent);
|
||||
if (!nbtent.asNBTString().contains("__extraData:{Hello:\"World\"}")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package de.tr7zw.nbtapi.plugin.tests.entities;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Monster;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTEntity;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class EntityCustomNbtTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if(!NBTInjector.isInjected())return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
|
||||
Entity ent = world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next();
|
||||
ent = NBTInjector.patchEntity(ent);
|
||||
NBTCompound comp = NBTInjector.getNbtData(ent);
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(ent);
|
||||
if (!nbtent.asNBTString().contains("__extraData:{Hello:\"World\"}")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+40
-39
@@ -1,39 +1,40 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.tiles;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTTileEntity;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class TilesCustomNBTTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 255,
|
||||
world.getSpawnLocation().getBlockZ());
|
||||
if (block.getType() == Material.AIR) {
|
||||
block.setType(Material.CHEST);
|
||||
NBTCompound comp = NBTInjector.getNbtData(block.getState());
|
||||
comp.setString("Foo", "Bar");
|
||||
if (!new NBTTileEntity(block.getState()).asNBTString().contains("__extraData:{Foo:\"Bar\"}")) {
|
||||
block.setType(Material.AIR);
|
||||
throw new NbtApiException("Custom Data did not save to the Tile!");
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTTiles!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package de.tr7zw.nbtapi.plugin.tests.tiles;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTTileEntity;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class TilesCustomNBTTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if(!NBTInjector.isInjected())return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 255,
|
||||
world.getSpawnLocation().getBlockZ());
|
||||
if (block.getType() == Material.AIR) {
|
||||
block.setType(Material.CHEST);
|
||||
NBTCompound comp = NBTInjector.getNbtData(block.getState());
|
||||
comp.setString("Foo", "Bar");
|
||||
if (!new NBTTileEntity(block.getState()).asNBTString().contains("__extraData:{Foo:\"Bar\"}")) {
|
||||
block.setType(Material.AIR);
|
||||
throw new NbtApiException("Custom Data did not save to the Tile!");
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTTiles!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<version>2.1.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.0.0</version>
|
||||
<version>2.1.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -1,277 +1,280 @@
|
||||
package de.tr7zw.nbtinjector;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
import de.tr7zw.nbtinjector.NBTInjector.Entity;
|
||||
import de.tr7zw.nbtinjector.NBTInjector.TileEntity;
|
||||
import javassist.ClassPool;
|
||||
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.logger;
|
||||
|
||||
/**
|
||||
* Contains the internal methods for different Minecraft Versions of injecting
|
||||
* the Entities/Tiles
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class InternalInjectors {
|
||||
|
||||
private static final List<String> skippingEntities = Arrays.asList("minecraft:player", "minecraft:fishing_bobber",
|
||||
"minecraft:lightning_bolt"); // These are broken/won't work, used by 1.14+
|
||||
private static final Map<String, String> classMappings = new HashMap<>();
|
||||
|
||||
static {
|
||||
classMappings.put("minecraft:wandering_trader", "VillagerTrader");
|
||||
classMappings.put("minecraft:trader_llama", "LlamaTrader");
|
||||
classMappings.put("minecraft:area_effect_cloud", "AreaEffectCloud");
|
||||
classMappings.put("minecraft:donkey", "HorseDonkey");
|
||||
classMappings.put("minecraft:ender_dragon", "EnderDragon");
|
||||
classMappings.put("minecraft:skeleton_horse", "HorseSkeleton");
|
||||
classMappings.put("minecraft:fireball", "LargeFireball");
|
||||
classMappings.put("minecraft:mule", "HorseMule");
|
||||
classMappings.put("minecraft:zombie_horse", "HorseZombie");
|
||||
classMappings.put("minecraft:mooshroom", "MushroomCow");
|
||||
classMappings.put("minecraft:wither_skeleton", "SkeletonWither");
|
||||
classMappings.put("minecraft:snow_golem", "Snowman");
|
||||
classMappings.put("minecraft:polar_bear", "PolarBear");
|
||||
classMappings.put("minecraft:magma_cube", "MagmaCube");
|
||||
classMappings.put("minecraft:armor_stand", "ArmorStand");
|
||||
classMappings.put("minecraft:elder_guardian", "GuardianElder");
|
||||
classMappings.put("minecraft:zombie_pigman", "PigZombie");
|
||||
classMappings.put("minecraft:giant", "GiantZombie");
|
||||
classMappings.put("minecraft:zombie_villager", "ZombieVillager");
|
||||
classMappings.put("minecraft:husk", "ZombieHusk");
|
||||
classMappings.put("minecraft:iron_golem", "IronGolem");
|
||||
classMappings.put("minecraft:tropical_fish", "TropicalFish");
|
||||
classMappings.put("minecraft:stray", "SkeletonStray");
|
||||
classMappings.put("minecraft:illusioner", "IllagerIllusioner");
|
||||
classMappings.put("minecraft:pufferfish", "PufferFish");
|
||||
classMappings.put("minecraft:cave_spider", "CaveSpider");
|
||||
}
|
||||
|
||||
/**
|
||||
* Hidden constructor
|
||||
*/
|
||||
private InternalInjectors() {
|
||||
|
||||
}
|
||||
|
||||
protected static void entity1v10Below(ClassPool classPool) throws ReflectiveOperationException {
|
||||
for (Map.Entry<String, Class<?>> entry : new HashSet<>(Entity.getCMap().entrySet())) {
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(entry.getValue())) {
|
||||
continue;
|
||||
} // Already injected
|
||||
int entityId = Entity.getFMap().get(entry.getValue());
|
||||
|
||||
Class<?> wrapped = ClassGenerator.wrapEntity(classPool, entry.getValue(), "__extraData");
|
||||
Entity.getCMap().put(entry.getKey(), wrapped);
|
||||
Entity.getDMap().put(wrapped, entry.getKey());
|
||||
|
||||
Entity.getEMap().put(entityId, wrapped);
|
||||
Entity.getFMap().put(wrapped, entityId);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + entry.getKey(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void entity1v12Below(ClassPool classPool) throws ReflectiveOperationException {
|
||||
Object registry = Entity.getRegistry();
|
||||
Map<Object, Object> inverse = new HashMap<>();
|
||||
Set<?> it = new HashSet<>((Set<?>) ReflectionMethod.REGISTRY_KEYSET.run(registry));
|
||||
for (Object mckey : it) {
|
||||
Class<?> tileclass = (Class<?>) ReflectionMethod.REGISTRY_GET.run(registry, mckey);
|
||||
inverse.put(tileclass, mckey);
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(tileclass)) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapEntity(classPool, tileclass, "__extraData");
|
||||
ReflectionMethod.REGISTRY_SET.run(registry, mckey, wrapped);
|
||||
inverse.put(wrapped, mckey);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
}
|
||||
Field inverseField = registry.getClass().getDeclaredField("b");
|
||||
NBTInjector.setFinal(registry, inverseField, inverse);
|
||||
}
|
||||
|
||||
protected static void entity1v13Below(ClassPool classPool) throws ReflectiveOperationException {
|
||||
Object entityRegistry = ClassWrapper.NMS_IREGISTRY.getClazz().getField("ENTITY_TYPE").get(null);
|
||||
Set<?> registryentries = new HashSet<>((Set<?>) ReflectionMethod.REGISTRYMATERIALS_KEYSET.run(entityRegistry));
|
||||
for (Object mckey : registryentries) {
|
||||
Object entityTypesObj = ReflectionMethod.REGISTRYMATERIALS_GET.run(entityRegistry, mckey);
|
||||
Field supplierField = entityTypesObj.getClass().getDeclaredField("aT");
|
||||
Field classField = entityTypesObj.getClass().getDeclaredField("aS");
|
||||
classField.setAccessible(true);
|
||||
supplierField.setAccessible(true);
|
||||
Function<Object, Object> function = (Function<Object, Object>) supplierField.get(entityTypesObj);
|
||||
Class<?> nmsclass = (Class<?>) classField.get(entityTypesObj);
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(nmsclass)) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapEntity(classPool, nmsclass, "__extraData");
|
||||
NBTInjector.setFinal(entityTypesObj, classField, wrapped);
|
||||
NBTInjector.setFinal(entityTypesObj, supplierField, new Function<Object, Object>() {
|
||||
|
||||
@Override
|
||||
public Object apply(Object t) {
|
||||
try {
|
||||
return wrapped.getConstructor(ClassWrapper.NMS_WORLD.getClazz()).newInstance(t);
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Error while creating custom entity instance! ", ex);
|
||||
return function.apply(t);// Fallback to the original one
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void entity1v14(ClassPool classPool) throws ReflectiveOperationException {
|
||||
Object entityRegistry = ClassWrapper.NMS_IREGISTRY.getClazz().getField("ENTITY_TYPE").get(null);
|
||||
Set<?> registryentries = new HashSet<>((Set<?>) ReflectionMethod.REGISTRYMATERIALS_KEYSET.run(entityRegistry));
|
||||
for (Object mckey : registryentries) {
|
||||
if (skippingEntities.contains(mckey.toString())) {
|
||||
logger.info("Skipping, won't be able add NBT to '" + mckey + "' entities!");
|
||||
continue;
|
||||
}
|
||||
Object entityTypesObj = ReflectionMethod.REGISTRYMATERIALS_GET.run(entityRegistry, mckey);
|
||||
Field creatorField = entityTypesObj.getClass().getDeclaredField("aZ");
|
||||
creatorField.setAccessible(true);
|
||||
Object creator = creatorField.get(entityTypesObj);
|
||||
Method createEntityMethod = creator.getClass().getMethod("create", ClassWrapper.NMS_ENTITYTYPES.getClazz(),
|
||||
ClassWrapper.NMS_WORLD.getClazz());
|
||||
createEntityMethod.setAccessible(true);
|
||||
Class<?> nmsclass = null;
|
||||
try {
|
||||
nmsclass = createEntityMethod.invoke(creator, entityTypesObj, null).getClass();
|
||||
} catch (Exception ignore) {
|
||||
// ignore
|
||||
}
|
||||
if (nmsclass == null) {
|
||||
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
String name = mckey.toString().replace("minecraft:", "");
|
||||
name = name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||
name = "Entity" + name;
|
||||
if (classMappings.containsKey(mckey.toString()))
|
||||
name = "Entity" + classMappings.get(mckey.toString());
|
||||
try {
|
||||
nmsclass = Class.forName("net.minecraft.server." + version + "." + name);
|
||||
} catch (Exception ignore) {
|
||||
logger.info("Not found: " + "net.minecraft.server." + version + "." + name);
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (nmsclass == null) {
|
||||
logger.info(
|
||||
"Wasn't able to create an Entity instace, won't be able add NBT to '" + mckey + "' entities!");
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(nmsclass)) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapEntity(classPool, nmsclass, "__extraData");
|
||||
NBTInjector.setFinal(entityTypesObj, creatorField,
|
||||
ClassGenerator.createEntityTypeWrapper(classPool, wrapped).newInstance());
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void tile1v10Below(ClassPool classPool) throws ReflectiveOperationException {
|
||||
for (Map.Entry<String, Class<?>> entry : new HashSet<>(TileEntity.getFMap().entrySet())) {
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(entry.getValue())) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapTileEntity(classPool, entry.getValue(), "__extraData");
|
||||
TileEntity.getFMap().put(entry.getKey(), wrapped);
|
||||
TileEntity.getGMap().put(wrapped, entry.getKey());
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + entry.getKey(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void tile1v12Below(ClassPool classPool) throws ReflectiveOperationException {
|
||||
Object registry = TileEntity.getRegistry();
|
||||
Map<Object, Object> inverse = new HashMap<>();
|
||||
Set<?> it = new HashSet<>((Set<?>) ReflectionMethod.REGISTRY_KEYSET.run(registry));
|
||||
for (Object mckey : it) {
|
||||
Class<?> tileclass = (Class<?>) ReflectionMethod.REGISTRY_GET.run(registry, mckey);
|
||||
inverse.put(tileclass, mckey);
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(tileclass)) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapTileEntity(classPool, tileclass, "__extraData");
|
||||
ReflectionMethod.REGISTRY_SET.run(registry, mckey, wrapped);
|
||||
inverse.put(wrapped, mckey);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
}
|
||||
Field inverseField = registry.getClass().getDeclaredField("b");
|
||||
NBTInjector.setFinal(registry, inverseField, inverse);
|
||||
}
|
||||
|
||||
protected static void tile1v13(ClassPool classPool) throws ReflectiveOperationException {
|
||||
Object tileRegistry = ClassWrapper.NMS_IREGISTRY.getClazz().getField("BLOCK_ENTITY_TYPE").get(null);
|
||||
Set<?> registryentries = new HashSet<>((Set<?>) ReflectionMethod.REGISTRYMATERIALS_KEYSET.run(tileRegistry));
|
||||
for (Object mckey : registryentries) {
|
||||
Object tileEntityTypesObj = ReflectionMethod.REGISTRYMATERIALS_GET.run(tileRegistry, mckey);
|
||||
String supplierFieldName = "A";
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId())
|
||||
supplierFieldName = "H";
|
||||
Field supplierField = tileEntityTypesObj.getClass().getDeclaredField(supplierFieldName);
|
||||
supplierField.setAccessible(true);
|
||||
Supplier<Object> supplier = (Supplier<Object>) supplierField.get(tileEntityTypesObj);
|
||||
Class<?> nmsclass = supplier.get().getClass();
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(nmsclass)) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapTileEntity(classPool, nmsclass, "__extraData");
|
||||
NBTInjector.setFinal(tileEntityTypesObj, supplierField, new Supplier<Object>() {
|
||||
@Override
|
||||
public Object get() {
|
||||
try {
|
||||
return wrapped.newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
logger.log(Level.SEVERE, "Error while creating custom tile instance! ", e);
|
||||
return supplier.get(); // Use the original one as fallback
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package de.tr7zw.nbtinjector;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
import de.tr7zw.nbtinjector.NBTInjector.Entity;
|
||||
import de.tr7zw.nbtinjector.NBTInjector.TileEntity;
|
||||
import javassist.ClassPool;
|
||||
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.logger;
|
||||
|
||||
/**
|
||||
* Contains the internal methods for different Minecraft Versions of injecting
|
||||
* the Entities/Tiles
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class InternalInjectors {
|
||||
|
||||
private static final List<String> skippingEntities = Arrays.asList("minecraft:player", "minecraft:fishing_bobber",
|
||||
"minecraft:lightning_bolt"); // These are broken/won't work, used by 1.14+
|
||||
private static final Map<String, String> classMappings = new HashMap<>();
|
||||
|
||||
static {
|
||||
classMappings.put("minecraft:wandering_trader", "VillagerTrader");
|
||||
classMappings.put("minecraft:trader_llama", "LlamaTrader");
|
||||
classMappings.put("minecraft:area_effect_cloud", "AreaEffectCloud");
|
||||
classMappings.put("minecraft:donkey", "HorseDonkey");
|
||||
classMappings.put("minecraft:ender_dragon", "EnderDragon");
|
||||
classMappings.put("minecraft:skeleton_horse", "HorseSkeleton");
|
||||
classMappings.put("minecraft:fireball", "LargeFireball");
|
||||
classMappings.put("minecraft:mule", "HorseMule");
|
||||
classMappings.put("minecraft:zombie_horse", "HorseZombie");
|
||||
classMappings.put("minecraft:mooshroom", "MushroomCow");
|
||||
classMappings.put("minecraft:wither_skeleton", "SkeletonWither");
|
||||
classMappings.put("minecraft:snow_golem", "Snowman");
|
||||
classMappings.put("minecraft:polar_bear", "PolarBear");
|
||||
classMappings.put("minecraft:magma_cube", "MagmaCube");
|
||||
classMappings.put("minecraft:armor_stand", "ArmorStand");
|
||||
classMappings.put("minecraft:elder_guardian", "GuardianElder");
|
||||
classMappings.put("minecraft:zombie_pigman", "PigZombie");
|
||||
classMappings.put("minecraft:giant", "GiantZombie");
|
||||
classMappings.put("minecraft:zombie_villager", "ZombieVillager");
|
||||
classMappings.put("minecraft:husk", "ZombieHusk");
|
||||
classMappings.put("minecraft:iron_golem", "IronGolem");
|
||||
classMappings.put("minecraft:tropical_fish", "TropicalFish");
|
||||
classMappings.put("minecraft:stray", "SkeletonStray");
|
||||
classMappings.put("minecraft:illusioner", "IllagerIllusioner");
|
||||
classMappings.put("minecraft:pufferfish", "PufferFish");
|
||||
classMappings.put("minecraft:cave_spider", "CaveSpider");
|
||||
}
|
||||
|
||||
/**
|
||||
* Hidden constructor
|
||||
*/
|
||||
private InternalInjectors() {
|
||||
|
||||
}
|
||||
|
||||
protected static void entity1v10Below(ClassPool classPool) throws ReflectiveOperationException {
|
||||
for (Map.Entry<String, Class<?>> entry : new HashSet<>(Entity.getCMap().entrySet())) {
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(entry.getValue())) {
|
||||
continue;
|
||||
} // Already injected
|
||||
int entityId = Entity.getFMap().get(entry.getValue());
|
||||
|
||||
Class<?> wrapped = ClassGenerator.wrapEntity(classPool, entry.getValue(), "__extraData");
|
||||
Entity.getCMap().put(entry.getKey(), wrapped);
|
||||
Entity.getDMap().put(wrapped, entry.getKey());
|
||||
|
||||
Entity.getEMap().put(entityId, wrapped);
|
||||
Entity.getFMap().put(wrapped, entityId);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + entry.getKey(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void entity1v12Below(ClassPool classPool) throws ReflectiveOperationException {
|
||||
Object registry = Entity.getRegistry();
|
||||
Map<Object, Object> inverse = new HashMap<>();
|
||||
Set<?> it = new HashSet<>((Set<?>) ReflectionMethod.REGISTRY_KEYSET.run(registry));
|
||||
Object registryId = Entity.getRegistryId(registry);
|
||||
for (Object mckey : it) {
|
||||
Class<?> entclass = (Class<?>) ReflectionMethod.REGISTRY_GET.run(registry, mckey);
|
||||
inverse.put(entclass, mckey);
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(entclass)) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapEntity(classPool, entclass, "__extraData");
|
||||
ReflectionMethod.REGISTRY_SET.run(registry, mckey, wrapped);
|
||||
inverse.put(wrapped, mckey);
|
||||
int id = (int) registryId.getClass().getMethod("getId", new Class[] {Object.class}).invoke(registryId, entclass);
|
||||
registryId.getClass().getMethod("a", new Class[] {Object.class, int.class}).invoke(registryId, wrapped, id);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
}
|
||||
Field inverseField = registry.getClass().getDeclaredField("b");
|
||||
NBTInjector.setFinal(registry, inverseField, inverse);
|
||||
}
|
||||
|
||||
protected static void entity1v13Below(ClassPool classPool) throws ReflectiveOperationException {
|
||||
Object entityRegistry = ClassWrapper.NMS_IREGISTRY.getClazz().getField("ENTITY_TYPE").get(null);
|
||||
Set<?> registryentries = new HashSet<>((Set<?>) ReflectionMethod.REGISTRYMATERIALS_KEYSET.run(entityRegistry));
|
||||
for (Object mckey : registryentries) {
|
||||
Object entityTypesObj = ReflectionMethod.REGISTRYMATERIALS_GET.run(entityRegistry, mckey);
|
||||
Field supplierField = entityTypesObj.getClass().getDeclaredField("aT");
|
||||
Field classField = entityTypesObj.getClass().getDeclaredField("aS");
|
||||
classField.setAccessible(true);
|
||||
supplierField.setAccessible(true);
|
||||
Function<Object, Object> function = (Function<Object, Object>) supplierField.get(entityTypesObj);
|
||||
Class<?> nmsclass = (Class<?>) classField.get(entityTypesObj);
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(nmsclass)) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapEntity(classPool, nmsclass, "__extraData");
|
||||
NBTInjector.setFinal(entityTypesObj, classField, wrapped);
|
||||
NBTInjector.setFinal(entityTypesObj, supplierField, new Function<Object, Object>() {
|
||||
|
||||
@Override
|
||||
public Object apply(Object t) {
|
||||
try {
|
||||
return wrapped.getConstructor(ClassWrapper.NMS_WORLD.getClazz()).newInstance(t);
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Error while creating custom entity instance! ", ex);
|
||||
return function.apply(t);// Fallback to the original one
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void entity1v14(ClassPool classPool) throws ReflectiveOperationException {
|
||||
Object entityRegistry = ClassWrapper.NMS_IREGISTRY.getClazz().getField("ENTITY_TYPE").get(null);
|
||||
Set<?> registryentries = new HashSet<>((Set<?>) ReflectionMethod.REGISTRYMATERIALS_KEYSET.run(entityRegistry));
|
||||
for (Object mckey : registryentries) {
|
||||
if (skippingEntities.contains(mckey.toString())) {
|
||||
logger.info("Skipping, won't be able add NBT to '" + mckey + "' entities!");
|
||||
continue;
|
||||
}
|
||||
Object entityTypesObj = ReflectionMethod.REGISTRYMATERIALS_GET.run(entityRegistry, mckey);
|
||||
Field creatorField = entityTypesObj.getClass().getDeclaredField("aZ");
|
||||
creatorField.setAccessible(true);
|
||||
Object creator = creatorField.get(entityTypesObj);
|
||||
Method createEntityMethod = creator.getClass().getMethod("create", ClassWrapper.NMS_ENTITYTYPES.getClazz(),
|
||||
ClassWrapper.NMS_WORLD.getClazz());
|
||||
createEntityMethod.setAccessible(true);
|
||||
Class<?> nmsclass = null;
|
||||
try {
|
||||
nmsclass = createEntityMethod.invoke(creator, entityTypesObj, null).getClass();
|
||||
} catch (Exception ignore) {
|
||||
// ignore
|
||||
}
|
||||
if (nmsclass == null) {
|
||||
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
String name = mckey.toString().replace("minecraft:", "");
|
||||
name = name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||
name = "Entity" + name;
|
||||
if (classMappings.containsKey(mckey.toString()))
|
||||
name = "Entity" + classMappings.get(mckey.toString());
|
||||
try {
|
||||
nmsclass = Class.forName("net.minecraft.server." + version + "." + name);
|
||||
} catch (Exception ignore) {
|
||||
logger.info("Not found: " + "net.minecraft.server." + version + "." + name);
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (nmsclass == null) {
|
||||
logger.info(
|
||||
"Wasn't able to create an Entity instace, won't be able add NBT to '" + mckey + "' entities!");
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(nmsclass)) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapEntity(classPool, nmsclass, "__extraData");
|
||||
NBTInjector.setFinal(entityTypesObj, creatorField,
|
||||
ClassGenerator.createEntityTypeWrapper(classPool, wrapped).newInstance());
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void tile1v10Below(ClassPool classPool) throws ReflectiveOperationException {
|
||||
for (Map.Entry<String, Class<?>> entry : new HashSet<>(TileEntity.getFMap().entrySet())) {
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(entry.getValue())) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapTileEntity(classPool, entry.getValue(), "__extraData");
|
||||
TileEntity.getFMap().put(entry.getKey(), wrapped);
|
||||
TileEntity.getGMap().put(wrapped, entry.getKey());
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + entry.getKey(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void tile1v12Below(ClassPool classPool) throws ReflectiveOperationException {
|
||||
Object registry = TileEntity.getRegistry();
|
||||
Map<Object, Object> inverse = new HashMap<>();
|
||||
Set<?> it = new HashSet<>((Set<?>) ReflectionMethod.REGISTRY_KEYSET.run(registry));
|
||||
for (Object mckey : it) {
|
||||
Class<?> tileclass = (Class<?>) ReflectionMethod.REGISTRY_GET.run(registry, mckey);
|
||||
inverse.put(tileclass, mckey);
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(tileclass)) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapTileEntity(classPool, tileclass, "__extraData");
|
||||
ReflectionMethod.REGISTRY_SET.run(registry, mckey, wrapped);
|
||||
inverse.put(wrapped, mckey);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
}
|
||||
Field inverseField = registry.getClass().getDeclaredField("b");
|
||||
NBTInjector.setFinal(registry, inverseField, inverse);
|
||||
}
|
||||
|
||||
protected static void tile1v13(ClassPool classPool) throws ReflectiveOperationException {
|
||||
Object tileRegistry = ClassWrapper.NMS_IREGISTRY.getClazz().getField("BLOCK_ENTITY_TYPE").get(null);
|
||||
Set<?> registryentries = new HashSet<>((Set<?>) ReflectionMethod.REGISTRYMATERIALS_KEYSET.run(tileRegistry));
|
||||
for (Object mckey : registryentries) {
|
||||
Object tileEntityTypesObj = ReflectionMethod.REGISTRYMATERIALS_GET.run(tileRegistry, mckey);
|
||||
String supplierFieldName = "A";
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId())
|
||||
supplierFieldName = "H";
|
||||
Field supplierField = tileEntityTypesObj.getClass().getDeclaredField(supplierFieldName);
|
||||
supplierField.setAccessible(true);
|
||||
Supplier<Object> supplier = (Supplier<Object>) supplierField.get(tileEntityTypesObj);
|
||||
Class<?> nmsclass = supplier.get().getClass();
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(nmsclass)) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapTileEntity(classPool, nmsclass, "__extraData");
|
||||
NBTInjector.setFinal(tileEntityTypesObj, supplierField, new Supplier<Object>() {
|
||||
@Override
|
||||
public Object get() {
|
||||
try {
|
||||
return wrapped.newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
logger.log(Level.SEVERE, "Error while creating custom tile instance! ", e);
|
||||
return supplier.get(); // Use the original one as fallback
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,6 +36,7 @@ public class NBTInjector {
|
||||
}
|
||||
|
||||
static Logger logger = Logger.getLogger("NBTInjector");
|
||||
private static boolean isInjected = false;
|
||||
|
||||
/**
|
||||
* Replaces the vanilla classes with Wrapped classes that support custom NBT.
|
||||
@@ -44,6 +45,8 @@ public class NBTInjector {
|
||||
* this method so it's class gets Wrapped.
|
||||
*/
|
||||
public static void inject() {
|
||||
if(isInjected)return;
|
||||
isInjected = true;
|
||||
try {
|
||||
ClassPool classPool = ClassPool.getDefault();
|
||||
logger.info("[NBTINJECTOR] Injecting Entity classes...");
|
||||
@@ -70,6 +73,10 @@ public class NBTInjector {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isInjected() {
|
||||
return isInjected;
|
||||
}
|
||||
|
||||
private static NBTCompound getNbtData(Object object) {
|
||||
if (object instanceof INBTWrapper) {
|
||||
return ((INBTWrapper) object).getNbtData();
|
||||
@@ -109,7 +116,7 @@ public class NBTInjector {
|
||||
String id = "";
|
||||
if (MinecraftVersion.getVersion().getVersionId() <= MinecraftVersion.MC1_10_R1.getVersionId()) {
|
||||
id = Entity.getBackupMap().get(ent.getClass());
|
||||
} else if (MinecraftVersion.getVersion().getVersionId() <= MinecraftVersion.MC1_13_R1.getVersionId()) {
|
||||
} else if (MinecraftVersion.getVersion().getVersionId() <= MinecraftVersion.MC1_13_R2.getVersionId()) {
|
||||
id = ReflectionMethod.REGISTRY_GET_INVERSE.run(Entity.getRegistry(), ent.getClass()).toString();
|
||||
} else {
|
||||
id = (String) ReflectionMethod.NMS_ENTITY_GETSAVEID.run(ent);
|
||||
@@ -245,6 +252,10 @@ public class NBTInjector {
|
||||
static Object getRegistry() throws ReflectiveOperationException {
|
||||
return getAccessable(ClassWrapper.NMS_ENTITYTYPES.getClazz().getDeclaredField("b")).get(null);
|
||||
}
|
||||
|
||||
static Object getRegistryId(Object reg) throws ReflectiveOperationException {
|
||||
return getAccessable(reg.getClass().getDeclaredField("a")).get(reg);
|
||||
}
|
||||
|
||||
static Map<Class<?>, String> getBackupMap() throws ReflectiveOperationException {
|
||||
return backupMap;
|
||||
|
||||
Reference in new issue
Block a user