Files
TabooLib/src/main/java/me/skymc/taboolib/nms/NMSUtils.java
2018-05-07 14:44:10 +08:00

362 lines
12 KiB
Java

package me.skymc.taboolib.nms;
import org.bukkit.Bukkit;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class NMSUtils {
public static Class<?> c = getOBCClass("block.CraftBlock");
public static Method m = getMethodSilent(c, "getNMSBlock");
public static String getVersion() {
String name = Bukkit.getServer().getClass().getPackage().getName();
return name.substring(name.lastIndexOf('.') + 1) + ".";
}
public static Class<?> getClassWithException(String name) throws Exception {
return Class.forName(name);
}
public static Class<?> getClass(String name) {
try {
return getClassWithException(name);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Class<?> getClass(String... strings) {
for (String s : strings) {
try {
return getClassWithException(s);
} catch (Exception ignored) {
}
}
return null;
}
public static Class<?> getClassSilent(String name) {
try {
return getClassWithException(name);
} catch (Exception ignored) {
}
return null;
}
public static Class<?> getNMSClassWithException(String className) throws Exception {
return Class.forName("net.minecraft.server." + getVersion() + className);
}
public static Class<?> getNMSClass(String className) {
try {
return getNMSClassWithException(className);
} catch (Exception ignored) {
}
return null;
}
public static Class<?> getNMSClassSilent(String className) {
try {
return getNMSClassWithException(className);
} catch (Exception ignored) {
}
return null;
}
public static Class<?> getNMSClass(String className, String embedded) {
try {
return getNMSClassWithException(className);
} catch (Exception e) {
return getInnerClassSilent(getNMSClassSilent(embedded), className);
}
}
public static Class<?> getNMSClassSilent(String className, String embedded) {
try {
return getNMSClassWithException(className);
} catch (Exception e) {
return getInnerClassSilent(getNMSClassSilent(embedded), className);
}
}
public static Class<?> getOBCClassWithException(String className) throws Exception {
return Class.forName("org.bukkit.craftbukkit." + getVersion() + className);
}
public static Class<?> getOBCClass(String className) {
try {
return getOBCClassWithException(className);
} catch (Exception ignored) {
}
return null;
}
public static Class<?> getOBCClassSilent(String className) {
try {
return getOBCClassWithException(className);
} catch (Exception ignored) {
}
return null;
}
public static Object getHandle(Object obj) {
try {
return getMethodWithException(obj.getClass(), "getHandle").invoke(obj);
} catch (Exception ignored) {
return null;
}
}
public static Object getHandleSilent(Object obj) {
try {
return getMethodWithException(obj.getClass(), "getHandle").invoke(obj);
} catch (Exception e) {
return null;
}
}
public static Object getBlockHandleWithException(Object obj) throws Exception {
return m.invoke(obj);
}
public static Object getBlockHandle(Object obj) {
try {
return m.invoke(obj);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Object getBlockHandleSilent(Object obj) {
try {
return m.invoke(obj);
} catch (Exception e) {
return null;
}
}
public static Field getFieldWithException(Class<?> clazz, String name) throws Exception {
for (Field field : clazz.getDeclaredFields())
if (field.getName().equals(name)) {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
int modifiers = modifiersField.getInt(field);
modifiers &= ~Modifier.FINAL;
modifiersField.setInt(field, modifiers);
return field;
}
for (Field field : clazz.getFields())
if (field.getName().equals(name)) {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
int modifiers = modifiersField.getInt(field);
modifiers &= ~Modifier.FINAL;
modifiersField.setInt(field, modifiers);
return field;
}
throw new Exception("Field Not Found");
}
public static Field getFieldSilent(Class<?> clazz, String... names) {
for (String name : names) {
try {
return getFieldWithException(clazz, name);
} catch (Exception ignored) {
}
}
return null;
}
public static Field getFieldSilent(Class<?> clazz, String name) {
try {
return getFieldWithException(clazz, name);
} catch (Exception ignored) {
}
return null;
}
public static Field getField(Class<?> clazz, String... names) {
for (String name : names) {
try {
return getFieldWithException(clazz, name);
} catch (Exception ignored) {
}
}
return null;
}
public static Field getFieldOfTypeWithException(Class<?> clazz, Class<?> type, String name) throws Exception {
for (Field field : clazz.getDeclaredFields())
if (field.getName().equals(name) && field.getType().equals(type)) {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
int modifiers = modifiersField.getInt(field);
modifiers &= ~Modifier.FINAL;
modifiersField.setInt(field, modifiers);
return field;
}
for (Field field : clazz.getFields())
if (field.getName().equals(name) && field.getType().equals(type)) {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
int modifiers = modifiersField.getInt(field);
modifiers &= ~Modifier.FINAL;
modifiersField.setInt(field, modifiers);
return field;
}
throw new Exception("Field Not Found");
}
public static Field getFieldOfType(Class<?> clazz, Class<?> type, String name) {
try {
return getFieldOfTypeWithException(clazz, type, name);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Field getFirstFieldOfTypeWithException(Class<?> clazz, Class<?> type) throws Exception {
for (Field field : clazz.getDeclaredFields()) {
if (field.getType().equals(type)) {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
int modifiers = modifiersField.getInt(field);
modifiers &= ~Modifier.FINAL;
modifiersField.setInt(field, modifiers);
return field;
}
}
throw new Exception("Field Not Found");
}
public static Field getFirstFieldOfType(Class<?> clazz, Class<?> type) {
try {
return getFirstFieldOfTypeWithException(clazz, type);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Field getLastFieldOfTypeWithException(Class<?> clazz, Class<?> type) throws Exception {
Field field = null;
for (Field f : clazz.getDeclaredFields())
if (f.getType().equals(type)) {
field = f;
}
if (field == null) {
throw new Exception("Field Not Found");
}
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
int modifiers = modifiersField.getInt(field);
modifiers &= ~Modifier.FINAL;
modifiersField.setInt(field, modifiers);
return field;
}
public static Field getLastFieldOfType(Class<?> clazz, Class<?> type) {
try {
return getLastFieldOfTypeWithException(clazz, type);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Method getMethodWithException(Class<?> clazz, String name, Class<?>... args) throws Exception {
for (Method m : clazz.getDeclaredMethods())
if (m.getName().equals(name) && (args.length == 0 && m.getParameterTypes().length == 0 || ClassListEqual(args, m.getParameterTypes()))) {
m.setAccessible(true);
return m;
}
for (Method m : clazz.getMethods())
if (m.getName().equals(name) && (args.length == 0 && m.getParameterTypes().length == 0 || ClassListEqual(args, m.getParameterTypes()))) {
m.setAccessible(true);
return m;
}
throw new Exception("Method Not Found");
}
public static Method getMethodSilent(Class<?> clazz, String name, Class<?>... args) {
try {
return getMethodWithException(clazz, name, args);
} catch (Exception ignored) {
}
return null;
}
public static boolean ClassListEqual(Class<?>[] l1, Class<?>[] l2) {
if (l1.length != l2.length)
return false;
for (int i = 0; i < l1.length; i++)
if (l1[i] != l2[i])
return false;
return true;
}
public static Class<?> getInnerClassWithException(Class<?> c, String className) throws Exception {
for (Class<?> cl : c.getDeclaredClasses())
if (cl.getSimpleName().equals(className))
return cl;
throw new Exception("Inner Class Not Found");
}
public static Class<?> getInnerClass(Class<?> c, String className) {
try {
return getInnerClassWithException(c, className);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Class<?> getInnerClassSilent(Class<?> c, String className) {
try {
return getInnerClassWithException(c, className);
} catch (Exception ignored) {
}
return null;
}
public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... args) throws Exception {
for (Constructor<?> c : clazz.getDeclaredConstructors())
if (args.length == 0 && c.getParameterTypes().length == 0 || ClassListEqual(args, c.getParameterTypes())) {
c.setAccessible(true);
return c;
}
for (Constructor<?> c : clazz.getConstructors())
if (args.length == 0 && c.getParameterTypes().length == 0 || ClassListEqual(args, c.getParameterTypes())) {
c.setAccessible(true);
return c;
}
throw new Exception("Constructor Not Found");
}
public static Constructor<?> getConstructorSilent(Class<?> clazz, Class<?>... args) {
try {
return getConstructor(clazz, args);
} catch (Exception ignored) {
}
return null;
}
@SuppressWarnings({"unchecked", "rawtypes"})
public static Enum<?> getEnum(final String value, final Class enumClass) {
return Enum.valueOf(enumClass, value);
}
}