Advertisement
Guest User

Untitled

a guest
Feb 20th, 2020
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.51 KB | None | 0 0
  1. private static String OBC_PREFIX = Bukkit.getServer().getClass().getPackage().getName();
  2. private static String NMS_PREFIX = OBC_PREFIX.replace("org.bukkit.craftbukkit", "net.minecraft.server");
  3. private static String VERSION = OBC_PREFIX.replace("org.bukkit.craftbukkit", "").replace(".", "");
  4. private static Pattern MATCH_VARIABLE = Pattern.compile("\\{([^}]+)}");
  5.  
  6. private Reflections()
  7. {
  8. }
  9.  
  10. //<editor-fold desc="expandVariables">
  11. private static String expandVariables(String name)
  12. {
  13. StringBuffer output = new StringBuffer();
  14. Matcher matcher = MATCH_VARIABLE.matcher(name);
  15.  
  16. while (matcher.find())
  17. {
  18. String variable = matcher.group(1);
  19. String replacement;
  20.  
  21. if ("nms".equalsIgnoreCase(variable))
  22. replacement = NMS_PREFIX;
  23. else if ("obc".equalsIgnoreCase(variable))
  24. replacement = OBC_PREFIX;
  25. else if ("version".equalsIgnoreCase(variable))
  26. replacement = VERSION;
  27. else
  28. throw new IllegalArgumentException("Unknown variable: " + variable);
  29.  
  30. if (replacement.length() > 0 && matcher.end() < name.length() && name.charAt(matcher.end()) != '.')
  31. replacement += ".";
  32. matcher.appendReplacement(output, Matcher.quoteReplacement(replacement));
  33. }
  34. matcher.appendTail(output);
  35. return output.toString();
  36. }
  37. //</editor-fold>
  38.  
  39. //<editor-fold desc="getCanonicalClass">
  40. private static Class<?> getCanonicalClass(String canonicalName)
  41. {
  42. try
  43. {
  44. return Class.forName(canonicalName);
  45. } catch (ClassNotFoundException e)
  46. {
  47. throw new IllegalArgumentException("Cannot find " + canonicalName, e);
  48. }
  49. }
  50. //</editor-fold>
  51.  
  52. //<editor-fold desc="getClass">
  53. public static Class<?> getClass(String lookupName)
  54. {
  55. return getCanonicalClass(expandVariables(lookupName));
  56. }
  57. //</editor-fold>
  58.  
  59. //<editor-fold desc="getConstructor">
  60. public static ConstructorInvoker getConstructor(String className, Class<?>... params)
  61. {
  62. return getConstructor(getClass(className), params);
  63. }
  64. //</editor-fold>
  65.  
  66. //<editor-fold desc="getConstructor">
  67. public static ConstructorInvoker getConstructor(Class<?> clazz, Class<?>... params)
  68. {
  69. for (final Constructor<?> constructor : clazz.getDeclaredConstructors())
  70. {
  71. if (Arrays.equals(constructor.getParameterTypes(), params))
  72. {
  73.  
  74. constructor.setAccessible(true);
  75. return new ConstructorInvoker() {
  76. @Override
  77. public Object invoke(Object... arguments)
  78. {
  79. try
  80. {
  81. return constructor.newInstance(arguments);
  82. } catch (Exception e)
  83. {
  84. throw new RuntimeException("Cannot invoke constructor " + constructor, e);
  85. }
  86. }
  87. };
  88. }
  89. }
  90. throw new IllegalStateException(String.format(
  91. "Unable to find constructor for %s (%s).", clazz, Arrays.asList(params)));
  92. }
  93. //</editor-fold>
  94.  
  95. //<editor-fold desc="getCraftBukkitClass">
  96. public static Class<?> getCraftBukkitClass(String name)
  97. {
  98. return getCanonicalClass(OBC_PREFIX + "." + name);
  99. }
  100. //</editor-fold>
  101.  
  102. //<editor-fold desc="getField">
  103. public static <T> FieldAccessor<T> getField(Class<?> target, String name, Class<T> fieldType)
  104. {
  105. return getField(target, name, fieldType, 0);
  106. }
  107. //</editor-fold>
  108.  
  109. //<editor-fold desc="getField">
  110. public static <T> FieldAccessor<T> getField(String className, String name, Class<T> fieldType)
  111. {
  112. return getField(getClass(className), name, fieldType, 0);
  113. }
  114. //</editor-fold>
  115.  
  116. //<editor-fold desc="getField">
  117. public static <T> FieldAccessor<T> getField(Class<?> target, Class<T> fieldType, int index)
  118. {
  119. return getField(target, null, fieldType, index);
  120. }
  121. //</editor-fold>
  122.  
  123. //<editor-fold desc="getField">
  124. public static <T> FieldAccessor<T> getField(String className, Class<T> fieldType, int index)
  125. {
  126. return getField(getClass(className), fieldType, index);
  127. }
  128. //</editor-fold>
  129.  
  130. //<editor-fold desc="getField">
  131. private static <T> FieldAccessor<T> getField(Class<?> target, String name, Class<T> fieldType, int index)
  132. {
  133. for (final Field field : target.getDeclaredFields())
  134. {
  135. if ((name == null || field.getName().equals(name)) && fieldType.isAssignableFrom(field.getType()) && index-- <= 0)
  136. {
  137. field.setAccessible(true);
  138.  
  139. return new FieldAccessor<T>() {
  140. @SuppressWarnings("unchecked")
  141. @Override
  142. public T get(Object target)
  143. {
  144. try
  145. {
  146. return (T) field.get(target);
  147. } catch (IllegalAccessException e)
  148. {
  149. throw new RuntimeException("Cannot access reflection.", e);
  150. }
  151. }
  152.  
  153. @Override
  154. public void set(Object target, Object value)
  155. {
  156. try
  157. {
  158. field.set(target, value);
  159. } catch (IllegalAccessException e)
  160. {
  161. throw new RuntimeException("Cannot access reflection.", e);
  162. }
  163. }
  164.  
  165. @Override
  166. public boolean hasField(Object target)
  167. {
  168. return field.getDeclaringClass().isAssignableFrom(target.getClass());
  169. }
  170. };
  171. }
  172. }
  173.  
  174. if (target.getSuperclass() != null)
  175. return getField(target.getSuperclass(), name, fieldType, index);
  176. throw new IllegalArgumentException("Cannot find field with type " + fieldType);
  177. }
  178. //</editor-fold>
  179.  
  180. //<editor-fold desc="getMethod">
  181. public static MethodInvoker getMethod(String className, String methodName, Class<?>... params)
  182. {
  183. return getTypedMethod(getClass(className), methodName, null, params);
  184. }
  185. //</editor-fold>
  186.  
  187. //<editor-fold desc="getMethod">
  188. public static MethodInvoker getMethod(Class<?> clazz, String methodName, Class<?>... params)
  189. {
  190. return getTypedMethod(clazz, methodName, null, params);
  191. }
  192. //</editor-fold>
  193.  
  194. //<editor-fold desc="getMethodSimply">
  195. public static Method getMethodSimply(Class<?> clazz, String method)
  196. {
  197. for (Method m : clazz.getMethods()) if (m.getName().equals(method)) return m;
  198. return null;
  199. }
  200. //</editor-fold>
  201.  
  202. //<editor-fold desc="getMinecraftClass">
  203. public static Class<?> getMinecraftClass(String name)
  204. {
  205. return getCanonicalClass(NMS_PREFIX + "." + name);
  206. }
  207. //</editor-fold>
  208.  
  209. //<editor-fold desc="getTypedMethod">
  210. public static MethodInvoker getTypedMethod(Class<?> clazz, String methodName, Class<?> returnType, Class<?>... params)
  211. {
  212. for (final Method method : clazz.getDeclaredMethods())
  213. {
  214. if ((methodName == null || method.getName().equals(methodName)) &&
  215. (returnType == null) || method.getReturnType().equals(returnType) &&
  216. Arrays.equals(method.getParameterTypes(), params))
  217. {
  218.  
  219. method.setAccessible(true);
  220. return (target, arguments) ->
  221. {
  222. try
  223. {
  224. return method.invoke(target, arguments);
  225. } catch (Exception e)
  226. {
  227. throw new RuntimeException("Cannot invoke method " + method, e);
  228. }
  229. };
  230. }
  231. }
  232.  
  233. if (clazz.getSuperclass() != null)
  234. return getMethod(clazz.getSuperclass(), methodName, params);
  235. throw new IllegalStateException(String.format(
  236. "Unable to find method %s (%s).", methodName, Arrays.asList(params)));
  237. }
  238. //</editor-fold>
  239.  
  240. //<editor-fold desc="getUntypedClass">
  241. public static Class<Object> getUntypedClass(String lookupName)
  242. {
  243. @SuppressWarnings({"rawtypes", "unchecked"})
  244. Class<Object> clazz = (Class<Object>) getClass(lookupName);
  245. return clazz;
  246. }
  247. //</editor-fold>
  248.  
  249. //<editor-fold desc="newInstance">
  250. public static <T> T newInstance(Class<T> type)
  251. {
  252. try
  253. {
  254. return type.newInstance();
  255. } catch (Exception e)
  256. {
  257. e.printStackTrace();
  258. return null;
  259. }
  260. }
  261. //</editor-fold>
  262.  
  263. public interface ConstructorInvoker {
  264.  
  265. Object invoke(Object... arguments);
  266. }
  267.  
  268. public interface MethodInvoker {
  269.  
  270. Object invoke(Object target, Object... arguments);
  271. }
  272.  
  273. public interface FieldAccessor<T> {
  274.  
  275. T get(Object target);
  276.  
  277. void set(Object target, Object value);
  278.  
  279. boolean hasField(Object target);
  280. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement