package net.shockverse.survivalgames.extras; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Basic various utilities for handling reflection. * @author LegitModern */ public class ReflectionUtil { private ReflectionUtil() { } private static String version; static { String name = Bukkit.getServer().getClass().getPackage().getName(), mcVersion = name.substring(name.lastIndexOf('.') + 1); version = mcVersion + "."; } /** * Get a class in NMS * * @param target Name of class * @return Class in NMS */ public static Class<?> getNMSClass(String target) { String className = "net.minecraft.server." + version + target; Class<?> clazz = null; try { clazz = Class.forName(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } return clazz; } /** * Get a class in CraftBukkit via reflection * * @param target Name of class * @return Class in CraftBukkit */ public static Class<?> getCraftClass(String target) { String className = "org.bukkit.craftbukkit." + version + target; Class<?> clazz = null; try { clazz = Class.forName(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } return clazz; } /** * Get a method with explicit parameters * * @param clazz Class to get method from * @param method Name of method to get * @param params Parameters for method * @return Method from class */ public static Method getMethod(Class<?> clazz, String method, Class<?>... params) { try { return clazz.getMethod(method, params); } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; } /** * Get a declared method with explicit parameters * * @param clazz Class to get method from * @param method Name of method to get * @param params Parameters for method * @return Declared method from class */ public static Method getDeclaredMethod(Class<?> clazz, String method, Class<?>... params) { try { return clazz.getDeclaredMethod(method, params); } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; } /** * Get a field from the class * * @param clazz Class to get method from * @param fieldName Name of field to get * @return Field from class with name */ public static Field getField(Class<?> clazz, String fieldName) { try { return clazz.getField(fieldName); } catch (SecurityException | NoSuchFieldException e) { e.printStackTrace(); } return null; } /** * Get a declared field from the class * * @param clazz Class to get method from * @param fieldName Name of field to get * @return Field from class with name */ public static Field getDeclaredField(Class<?> clazz, String fieldName) { try { return clazz.getDeclaredField(fieldName); } catch (SecurityException | NoSuchFieldException e) { e.printStackTrace(); } return null; } /** * Set the value of a field in a class * * @param instance Instance of object to set * @param fieldName Name of field to set value for * @param value Value to set on field */ public static void setValue(Object instance, String fieldName, Object value) { try { Field field = getDeclaredField(instance.getClass(), fieldName); field.setAccessible(true); field.set(instance, value); field.setAccessible(!field.isAccessible()); } catch (IllegalAccessException e) { e.printStackTrace(); } } /** * Send a packet via reflection * * @param player Player to send packet to * @param packet Packet to send */ public static void sendPacket(Player player, Object packet) { try { Object nmsPlayer = getHandle(player); Field conField = getField(nmsPlayer.getClass(), "playerConnection"); Object connection = conField.get(nmsPlayer); Method packetMethod = getMethod(connection.getClass(), "sendPacket", getNMSClass("Packet")); packetMethod.invoke(connection, packet); } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } /** * Get the NMS handle of an entity * * @param entity Entity to get handle from * @return Entity's NMS handle */ public static Object getHandle(Object entity) { Object nmsEntity = null; Method entityGetHandle = getMethod(entity.getClass(), "getHandle"); try { nmsEntity = entityGetHandle.invoke(entity); } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } return nmsEntity; } }