From 1d276aa356ad8c39b7d76e20707896ac87eeba52 Mon Sep 17 00:00:00 2001 From: NichtStudioCode <51272202+NichtStudioCode@users.noreply.github.com> Date: Mon, 12 Jun 2023 20:19:21 +0200 Subject: [PATCH] Find plugin instance when loaded through PaperPluginClassLoader --- .../util/ReflectionRegistry.java | 8 ++ .../inventoryaccess/util/ReflectionUtils.java | 77 +++++++++---------- .../main/java/xyz/xenondevs/invui/InvUI.java | 22 +++++- 3 files changed, 65 insertions(+), 42 deletions(-) diff --git a/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/util/ReflectionRegistry.java b/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/util/ReflectionRegistry.java index df3987d..2d9dfb5 100644 --- a/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/util/ReflectionRegistry.java +++ b/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/util/ReflectionRegistry.java @@ -17,10 +17,12 @@ public class ReflectionRegistry { // Classes public static final Class PLUGIN_CLASS_LOADER_CLASS = getBukkitClass("plugin.java.PluginClassLoader"); + public static final Class PAPER_PLUGIN_CLASS_LOADER_CLASS = getClassOrNull("io.papermc.paper.plugin.entrypoint.classloader.PaperPluginClassLoader"); public static final Class CB_CRAFT_META_SKULL_CLASS = getCBClass("inventory.CraftMetaSkull"); public static final Class CB_CRAFT_META_ITEM_CLASS = getCBClass("inventory.CraftMetaItem"); // Methods + public static final Method PAPER_PLUGIN_CLASS_LOADER_GET_LOADED_JAVA_PLUGIN_METHOD; public static final Method CB_CRAFT_META_SKULL_SET_PROFILE_METHOD = getMethod(CB_CRAFT_META_SKULL_CLASS, true, "setProfile", GameProfile.class); // Fields @@ -28,4 +30,10 @@ public class ReflectionRegistry { public static final Field CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD = getField(CB_CRAFT_META_ITEM_CLASS, true, "displayName"); public static final Field CB_CRAFT_META_ITEM_LORE_FIELD = getField(CB_CRAFT_META_ITEM_CLASS, true, "lore"); + static { + Method getPlugin = getMethodOrNull(PAPER_PLUGIN_CLASS_LOADER_CLASS, false, "getLoadedJavaPlugin"); + if (getPlugin == null) getPlugin = getMethodOrNull(PAPER_PLUGIN_CLASS_LOADER_CLASS, false, "getPlugin"); + PAPER_PLUGIN_CLASS_LOADER_GET_LOADED_JAVA_PLUGIN_METHOD = getPlugin; + } + } diff --git a/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/util/ReflectionUtils.java b/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/util/ReflectionUtils.java index 146d17a..6034376 100644 --- a/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/util/ReflectionUtils.java +++ b/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/util/ReflectionUtils.java @@ -5,7 +5,6 @@ import xyz.xenondevs.inventoryaccess.version.InventoryAccessRevision; import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @SuppressWarnings({"unchecked", "unused"}) @@ -26,11 +25,9 @@ public class ReflectionUtils { public static Class getImplClass(String path) { try { return (Class) Class.forName("xyz.xenondevs.inventoryaccess." + InventoryAccessRevision.REQUIRED_REVISION.getPackageName() + "." + path); - } catch (ClassNotFoundException e) { - e.printStackTrace(); + } catch (Throwable t) { + throw new RuntimeException(t); } - - return null; } public static Class getBukkitClass(String path) { @@ -44,11 +41,17 @@ public class ReflectionUtils { public static Class getClass(String path) { try { return (Class) Class.forName(path); - } catch (ClassNotFoundException e) { - e.printStackTrace(); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + public static Class getClassOrNull(String path) { + try { + return (Class) Class.forName(path); + } catch (Throwable t) { + return null; } - - return null; } public static Field getField(Class clazz, boolean declared, String name) { @@ -56,11 +59,9 @@ public class ReflectionUtils { Field field = declared ? clazz.getDeclaredField(name) : clazz.getField(name); if (declared) field.setAccessible(true); return field; - } catch (NoSuchFieldException e) { - e.printStackTrace(); + } catch (Throwable t) { + throw new RuntimeException(t); } - - return null; } public static Constructor getConstructor(Class clazz, boolean declared, Class... parameterTypes) { @@ -68,31 +69,25 @@ public class ReflectionUtils { Constructor constructor = declared ? clazz.getDeclaredConstructor(parameterTypes) : clazz.getConstructor(parameterTypes); if (declared) constructor.setAccessible(true); return constructor; - } catch (NoSuchMethodException e) { - e.printStackTrace(); + } catch (Throwable t) { + throw new RuntimeException(t); } - - return null; } public static T constructEmpty(Class clazz) { try { return (T) getConstructor(clazz, true).newInstance(); - } catch (ReflectiveOperationException e) { - e.printStackTrace(); + } catch (Throwable t) { + throw new RuntimeException(t); } - - return null; } public static T construct(Constructor constructor, Object... args) { try { return constructor.newInstance(args); - } catch (ReflectiveOperationException e) { - e.printStackTrace(); + } catch (Throwable t) { + throw new RuntimeException(t); } - - return null; } public static Method getMethod(Class clazz, boolean declared, String name, Class... parameterTypes) { @@ -100,28 +95,34 @@ public class ReflectionUtils { Method method = declared ? clazz.getDeclaredMethod(name, parameterTypes) : clazz.getMethod(name, parameterTypes); if (declared) method.setAccessible(true); return method; - } catch (NoSuchMethodException e) { - e.printStackTrace(); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + public static Method getMethodOrNull(Class clazz, boolean declared, String name, Class... parameterTypes) { + try { + Method method = declared ? clazz.getDeclaredMethod(name, parameterTypes) : clazz.getMethod(name, parameterTypes); + if (declared) method.setAccessible(true); + return method; + } catch (Throwable t) { + return null; } - - return null; } public static T invokeMethod(Method method, Object obj, Object... args) { try { return (T) method.invoke(obj, args); - } catch (IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); + } catch (Throwable t) { + throw new RuntimeException(t); } - - return null; } public static void setFieldValue(Field field, Object obj, Object value) { try { field.set(obj, value); - } catch (IllegalAccessException e) { - e.printStackTrace(); + } catch (Throwable t) { + throw new RuntimeException(t); } } @@ -129,11 +130,9 @@ public class ReflectionUtils { public static T getFieldValue(Field field, Object obj) { try { return (T) field.get(obj); - } catch (IllegalAccessException e) { - e.printStackTrace(); + } catch (Throwable t) { + throw new RuntimeException(t); } - - return null; } } diff --git a/invui-core/src/main/java/xyz/xenondevs/invui/InvUI.java b/invui-core/src/main/java/xyz/xenondevs/invui/InvUI.java index 294f5cd..8f579d3 100644 --- a/invui-core/src/main/java/xyz/xenondevs/invui/InvUI.java +++ b/invui-core/src/main/java/xyz/xenondevs/invui/InvUI.java @@ -6,12 +6,15 @@ import org.bukkit.event.Listener; import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.xenondevs.inventoryaccess.util.ReflectionRegistry; import xyz.xenondevs.inventoryaccess.util.ReflectionUtils; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; +import static xyz.xenondevs.inventoryaccess.util.ReflectionRegistry.PAPER_PLUGIN_CLASS_LOADER_GET_LOADED_JAVA_PLUGIN_METHOD; import static xyz.xenondevs.inventoryaccess.util.ReflectionRegistry.PLUGIN_CLASS_LOADER_PLUGIN_FIELD; public class InvUI implements Listener { @@ -30,14 +33,27 @@ public class InvUI implements Listener { public @NotNull Plugin getPlugin() { if (plugin == null) { - // get plugin from class loader if it wasn't set manually - plugin = ReflectionUtils.getFieldValue(PLUGIN_CLASS_LOADER_PLUGIN_FIELD, getClass().getClassLoader()); - Bukkit.getPluginManager().registerEvents(this, plugin); + plugin = tryFindPlugin(); + + if (plugin == null) + throw new IllegalStateException("Plugin is not set. Set it using InvUI.getInstance().setPlugin(plugin);"); } return plugin; } + private @Nullable Plugin tryFindPlugin() { + ClassLoader loader = getClass().getClassLoader(); + + if (ReflectionRegistry.PLUGIN_CLASS_LOADER_CLASS.isInstance(loader)) { + return ReflectionUtils.getFieldValue(PLUGIN_CLASS_LOADER_PLUGIN_FIELD, loader); + } else if (ReflectionRegistry.PAPER_PLUGIN_CLASS_LOADER_CLASS.isInstance(loader)) { + return ReflectionUtils.invokeMethod(PAPER_PLUGIN_CLASS_LOADER_GET_LOADED_JAVA_PLUGIN_METHOD, loader); + } + + return null; + } + public void setPlugin(@NotNull Plugin plugin) { if (this.plugin != null) throw new IllegalStateException("Plugin is already set");