Created
July 17, 2017 21:34
-
-
Save TheMasteredPanda/b8942f658a10c22fd653cb0b83ed4a7c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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