Skip to content

Instantly share code, notes, and snippets.

@TheMasteredPanda
Created April 12, 2017 09:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheMasteredPanda/b7fe7bb30f1a2c1b2762859721c6afa2 to your computer and use it in GitHub Desktop.
Save TheMasteredPanda/b7fe7bb30f1a2c1b2762859721c6afa2 to your computer and use it in GitHub Desktop.
package net.dungeons.utils;
import com.google.common.base.Preconditions;
import org.bukkit.Bukkit;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Created by TheMasteredPanda on 17/02/2017.
*/
public class ReflectionUtils
{
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<?> getNMUtilClass(String name)
{
try
{
return Class.forName(name);
} catch (ClassNotFoundException ex) {
try
{
return Class.forName("net.minecraft.util." + name);
}
catch (ClassNotFoundException ex2) {}
}
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 = getDeclaredMethod(wrapper.getClass(), "getHandle", new Class[0]);
return callMethod(getHandle, wrapper, new Object[0]);
}
public static Method getDeclaredMethod(Class<?> clazz, String methodName, Class<?>... paramaters)
{
try
{
return clazz.getDeclaredMethod(methodName, paramaters);
} 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 <T> Constructor<T> getConstructor(Class<?> clazz, Class<?>... parameterTypes)
{
try {
return (Constructor<T>) clazz.getConstructor(parameterTypes);
} catch (NoSuchMethodException ex) {
return null;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static <T> T callConstructor(Constructor<T> constructor, Object... paramaters)
{
if (constructor == null) {
throw new RuntimeException("No such constructor");
}
constructor.setAccessible(true);
try {
return constructor.newInstance(paramaters);
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex.getCause());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static Field getDeclaredField(Class<?> clazz, String name)
{
try {
return clazz.getDeclaredField(name);
} catch (NoSuchFieldException ex) {
return null;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static <T> T getField(Field field, Object instance)
{
if (field == null) {
throw new RuntimeException("No such field");
}
field.setAccessible(true);
try {
return (T)field.get(instance);
} 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 ex) {}
return null;
}
public static <T> Class<? extends T> getClass(String name, Class<T> superClass)
{
try {
return Class.forName(name).asSubclass(superClass);
} catch (ClassCastException | ClassNotFoundException ex) {}
return null;
}
public static Field getOnlyField(Class<?> toGetFrom, Class<?> type)
{
Field only = null;
Field[] arrayOfField;
int i = (arrayOfField = toGetFrom.getDeclaredFields()).length;
for (int j = 0; j < i; j++) {
Field field = arrayOfField[j];
if (type.isAssignableFrom(field.getClass())) {
Preconditions.checkArgument(only == null, "More than one field of type %s on %s: %s and %s", new Object[] { type.getSimpleName(), toGetFrom.getSimpleName(), field.getName(), only.getName() });
only = field;
}
}
return only;
}
public static Method getOnlyMethod(Class<?> toGetFrom, Class<?> returnType, Class<?>... paramSpec)
{
Method only = null;
Method[] arrayOfMethod;
int i = (arrayOfMethod = toGetFrom.getDeclaredMethods()).length;
for (int j = 0; j < i; j++) {
Method method = arrayOfMethod[j];
if ((returnType.isAssignableFrom(method.getReturnType())) &&
(isParamsMatchSpec(method.getParameterTypes(), paramSpec))) {
Preconditions.checkArgument(only == null, "More than one method matching spec on %s" + (only.getName().equals(method.getName()) ? "" : new StringBuilder(": ").append(only.getName()).append(" ").append(method.getName()).toString()), new Object[] { toGetFrom.getSimpleName() });
only = method;
}
}
return only;
}
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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment