Skip to content

Instantly share code, notes, and snippets.

@TheMasteredPanda
Created July 17, 2017 21:34
Show Gist options
  • Save TheMasteredPanda/b8942f658a10c22fd653cb0b83ed4a7c to your computer and use it in GitHub Desktop.
Save TheMasteredPanda/b8942f658a10c22fd653cb0b83ed4a7c to your computer and use it in GitHub Desktop.
package com.themasteredpanda.library.bukkit.utils;
import com.themasteredpanda.library.utils.UtilException;
import org.bukkit.Bukkit;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectionUtils
{
public ReflectionUtils()
{
throw new UtilException();
}
public static Class<?> getNMSClass(String name)
{
return getClass("net.minecraft.server." + getVersion() + "." + name);
}
public static Class<?> getOBClass(String name)
{
return getClass("org.bukkit.craftbukkit." + getVersion() + "." + name);
}
public static Class<?> getUtilClass(String name)
{
try {
return Class.forName(name);
}
catch (ClassNotFoundException ex) {
try {
return Class.forName("net.minecraft.util." + name);
} catch (ClassNotFoundException ignore) {}
}
return null;
}
public static String getVersion()
{
String packageName = Bukkit.getServer().getClass().getPackage().getName();
return packageName.substring(packageName.lastIndexOf('.') + 1);
}
public static Object getHandle(Object wrapper)
{
Method getHandle = getMethod(wrapper.getClass(), "getHandle", Type.ONLY);
return callMethod(getHandle, wrapper);
}
public static Method getMethod(Class<?> clazz, String methodName, Type methodType, Class<?>... parameters)
{
try {
if (methodType == Type.DECLARED) {
return clazz.getDeclaredMethod(methodName, parameters);
} else {
return clazz.getMethod(methodName, parameters);
}
} catch (NoSuchMethodException ex) {
return null;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static <T> T callMethod(Method method, Object instance, Object... parameters)
{
if (method == null) {
throw new RuntimeException("No such method");
}
method.setAccessible(true);
try {
return (T)method.invoke(instance, parameters);
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex.getCause());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static Constructor<?> getConstructor(Class<?> clazz, Type constructorType, Class<?>... parameterTypes)
{
try {
if (constructorType == Type.DECLARED) {
return clazz.getDeclaredConstructor(parameterTypes);
} else {
return clazz.getConstructor(parameterTypes);
}
} catch (NoSuchMethodException ex) {
return null;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static <T> T callConstructor(Constructor<T> constructor, Object... parameters)
{
if (constructor == null) {
throw new RuntimeException("No such constructor");
}
constructor.setAccessible(true);
try {
return constructor.newInstance(parameters);
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex.getCause());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static Field getField(Class<?> clazz, String name, Type fieldType)
{
try {
if (fieldType == Type.DECLARED) {
return clazz.getDeclaredField(name);
} else {
return clazz.getField(name);
}
} catch (NoSuchFieldException ex) {
return null;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static void setField(Field field, Object instance, Object value)
{
if (field == null) {
throw new RuntimeException("No such field");
}
field.setAccessible(true);
try {
field.set(instance, value);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static Class<?> getClass(String name)
{
try {
return Class.forName(name);
} catch (ClassNotFoundException ignored) {}
return null;
}
public static <T> Class<? extends T> getClass(String name, Class<T> superClass)
{
try {
return Class.forName(name).asSubclass(superClass);
} catch (ClassCastException|ClassNotFoundException ignored) {}
return null;
}
public static boolean isParamsMatchSpec(Class<?>[] parameters, Class<?>... paramSpec)
{
if (parameters.length > paramSpec.length) {
return false;
}
for (int i = 0; i < paramSpec.length; i++)
{
Class<?> spec = paramSpec[i];
if (spec != null)
{
Class parameter = parameters[i];
if (!spec.isAssignableFrom(parameter)) {
return false;
}
}
}
return true;
}
public enum Type
{
DECLARED, ONLY
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment