From ad74ed28547a636aca3ecaecce969bc9631d5ebc Mon Sep 17 00:00:00 2001 From: Marc Baloup Date: Thu, 17 Feb 2022 22:59:50 +0100 Subject: [PATCH] Refactor pandalib-paper ReflectRegistry + fix some issues in Reflect util class --- .../fr/pandacube/lib/core/util/Reflect.java | 51 ++- .../lib/core/util/ThrowableUtil.java | 53 ++++ .../fr/pandacube/lib/paper/PandaLibPaper.java | 6 + .../lib/paper/reflect/NMSReflect.java | 8 +- .../lib/paper/reflect/ReflectRegistry.java | 297 +++++++++++------- 5 files changed, 264 insertions(+), 151 deletions(-) diff --git a/Core/src/main/java/fr/pandacube/lib/core/util/Reflect.java b/Core/src/main/java/fr/pandacube/lib/core/util/Reflect.java index ae23179..7d82cd9 100644 --- a/Core/src/main/java/fr/pandacube/lib/core/util/Reflect.java +++ b/Core/src/main/java/fr/pandacube/lib/core/util/Reflect.java @@ -195,13 +195,16 @@ public class Reflect { - public static abstract class ReflectMember { + public static abstract class ReflectMember { ReflectClass reflectClass; + protected ID identifier; + protected EL cached; - protected ReflectMember(ReflectClass c, boolean bypassFilter) throws EX { + protected ReflectMember(ReflectClass c, ID id, boolean bypassFilter) throws EX { reflectClass = c; - cached = (bypassFilter) ? fetchFiltered() : get(); + identifier = id; + cached = (bypassFilter) ? fetchFiltered() : fetch(); } @@ -300,17 +303,15 @@ public class Reflect { - public static class ReflectField extends ReflectMember { - String elementName; + public static class ReflectField extends ReflectMember { /* package */ ReflectField(ReflectClass c, String name, boolean bypassFilter) throws NoSuchFieldException { - super(c, bypassFilter); - elementName = name; + super(c, name, bypassFilter); } - @Override protected Field fetchFromClass(Class clazz) throws NoSuchFieldException { return clazz.getDeclaredField(elementName); }; - @Override protected Field fetchFromReflectClass(ReflectClass rc) throws NoSuchFieldException { return rc.field(elementName).get(); }; - @Override protected boolean isEqualOurElement(Field el) { return elementName.equals(el.getName()); }; + @Override protected Field fetchFromClass(Class clazz) throws NoSuchFieldException { return clazz.getDeclaredField(identifier); }; + @Override protected Field fetchFromReflectClass(ReflectClass rc) throws NoSuchFieldException { return rc.field(identifier).get(); }; + @Override protected boolean isEqualOurElement(Field el) { return identifier.equals(el.getName()); }; @Override protected String internalMethodNameElementArray() { return "getDeclaredFields0"; }; @Override protected String internalMethodNameCopyElement() { return "copyField"; }; @Override protected void setAccessible(Field el) { el.setAccessible(true); } @@ -367,22 +368,15 @@ public class Reflect { - public static class ReflectMethod extends ReflectMember { - String elementName; - - MethodIdentifier methodId; - Class[] parameterTypes; + public static class ReflectMethod extends ReflectMember { /* package */ ReflectMethod(ReflectClass c, MethodIdentifier methodId, boolean bypassFilter) throws NoSuchMethodException { - super(c, bypassFilter); - this.elementName = methodId.methodName; - this.methodId = methodId; - parameterTypes = methodId.parameters; + super(c, methodId, bypassFilter); } - @Override protected Method fetchFromClass(Class clazz) throws NoSuchMethodException { return clazz.getDeclaredMethod(elementName, parameterTypes); }; - @Override protected Method fetchFromReflectClass(ReflectClass rc) throws NoSuchMethodException { return rc.method(methodId, false).get(); }; - @Override protected boolean isEqualOurElement(Method el) { return elementName.equals(el.getName()) && Arrays.equals(parameterTypes, el.getParameterTypes()); }; + @Override protected Method fetchFromClass(Class clazz) throws NoSuchMethodException { return clazz.getDeclaredMethod(identifier.methodName, identifier.parameters); }; + @Override protected Method fetchFromReflectClass(ReflectClass rc) throws NoSuchMethodException { return rc.method(identifier, false).get(); }; + @Override protected boolean isEqualOurElement(Method el) { return identifier.methodName.equals(el.getName()) && Arrays.equals(identifier.parameters, el.getParameterTypes()); }; @Override protected String internalMethodNameElementArray() { return "getDeclaredMethods0"; }; @Override protected String internalMethodNameCopyElement() { return "copyMethod"; }; @Override protected void setAccessible(Method el) { el.setAccessible(true); } @@ -401,15 +395,10 @@ public class Reflect { - public static class ReflectConstructor extends ReflectMember, NoSuchMethodException> { - - ConstructorIdentifier constructorId; - Class[] parameterTypes; + public static class ReflectConstructor extends ReflectMember, NoSuchMethodException> { /* package */ ReflectConstructor(ReflectClass c, ConstructorIdentifier constructorId, boolean bypassFilter) throws NoSuchMethodException { - super(c, bypassFilter); - this.constructorId = constructorId; - parameterTypes = constructorId.parameters; + super(c, constructorId, bypassFilter); } // Override since we don't want to recursively search for a constructor @@ -421,9 +410,9 @@ public class Reflect { return el; } - @Override protected Constructor fetchFromClass(Class clazz) throws NoSuchMethodException { return clazz.getDeclaredConstructor(parameterTypes); }; + @Override protected Constructor fetchFromClass(Class clazz) throws NoSuchMethodException { return clazz.getDeclaredConstructor(identifier.parameters); }; @Override protected Constructor fetchFromReflectClass(ReflectClass rc) throws NoSuchMethodException { throw new UnsupportedOperationException(); }; - @Override protected boolean isEqualOurElement(Constructor el) { return Arrays.equals(parameterTypes, el.getParameterTypes()); }; + @Override protected boolean isEqualOurElement(Constructor el) { return Arrays.equals(identifier.parameters, el.getParameterTypes()); }; @Override protected String internalMethodNameElementArray() { return "getDeclaredConstructors0"; }; @Override protected String internalMethodNameCopyElement() { return "copyConstructor"; }; @Override protected void setAccessible(Constructor el) { el.setAccessible(true); } diff --git a/Core/src/main/java/fr/pandacube/lib/core/util/ThrowableUtil.java b/Core/src/main/java/fr/pandacube/lib/core/util/ThrowableUtil.java index 6c237ac..515762e 100644 --- a/Core/src/main/java/fr/pandacube/lib/core/util/ThrowableUtil.java +++ b/Core/src/main/java/fr/pandacube/lib/core/util/ThrowableUtil.java @@ -20,4 +20,57 @@ public class ThrowableUtil { } } + + + + + + + + + /** + * A supplier that can possibly throw a checked exception + */ + @FunctionalInterface + public interface SupplierException { + public T get() throws Exception; + } + + /** + * Wraps a {@link SupplierException} into a try catch. + * @param supp the {@link SupplierException} to run and get the value from. + * @return the value returned by the provided supplier. + * @throws RuntimeException if the provided {@link SupplierException} throws an exception. + */ + public static T wrapEx(SupplierException supp) { + try { + return supp.get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + + + /** + * A runnable that can possibly throw a checked exception + */ + @FunctionalInterface + public interface RunnableException { + public void run() throws Exception; + } + + /** + * Wraps a {@link RunnableException} into a try catch. + * @param run the {@link RunnableException} to run. + * @throws RuntimeException if the provided {@link RunnableException} throws an exception. + */ + public static void wrapEx(RunnableException run) { + try { + run.run(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } diff --git a/Paper/src/main/java/fr/pandacube/lib/paper/PandaLibPaper.java b/Paper/src/main/java/fr/pandacube/lib/paper/PandaLibPaper.java index 558b222..55b6ec4 100644 --- a/Paper/src/main/java/fr/pandacube/lib/paper/PandaLibPaper.java +++ b/Paper/src/main/java/fr/pandacube/lib/paper/PandaLibPaper.java @@ -2,12 +2,18 @@ package fr.pandacube.lib.paper; import org.bukkit.plugin.Plugin; +import fr.pandacube.lib.paper.reflect.ReflectRegistry; + public class PandaLibPaper { private static Plugin plugin; public static void init(Plugin plugin) { PandaLibPaper.plugin = plugin; + + ReflectRegistry.init(); + + } public static Plugin getPlugin() { diff --git a/Paper/src/main/java/fr/pandacube/lib/paper/reflect/NMSReflect.java b/Paper/src/main/java/fr/pandacube/lib/paper/reflect/NMSReflect.java index 148cf36..c0d4e88 100644 --- a/Paper/src/main/java/fr/pandacube/lib/paper/reflect/NMSReflect.java +++ b/Paper/src/main/java/fr/pandacube/lib/paper/reflect/NMSReflect.java @@ -46,6 +46,11 @@ public class NMSReflect { OBF_NAMESPACE = (String) PAPER_OBFHELPER_CLASS.field("SPIGOT_NAMESPACE").getStaticValue(); MOJ_NAMESPACE = (String) PAPER_OBFHELPER_CLASS.field("MOJANG_PLUS_YARN_NAMESPACE").getStaticValue(); + } catch (ReflectiveOperationException e) { + throw new RuntimeException("Unable to find the Paper ofbuscation mapping class or class members.", e); + } + + try { List mappings = loadMappings(); for (ClassMapping clazz : mappings) { @@ -119,8 +124,7 @@ public class NMSReflect { private static List loadMappings() { try (final InputStream mappingsInputStream = PAPER_OBFHELPER_CLASS.get().getClassLoader().getResourceAsStream("META-INF/mappings/reobf.tiny")) { if (mappingsInputStream == null) { - Log.severe("Unable to find the ofbuscation mapping file in the Paper jar."); - return Collections.emptyList(); + throw new RuntimeException("Unable to find the ofbuscation mapping file in the Paper jar."); } MemoryMappingTree tree = new MemoryMappingTree(); diff --git a/Paper/src/main/java/fr/pandacube/lib/paper/reflect/ReflectRegistry.java b/Paper/src/main/java/fr/pandacube/lib/paper/reflect/ReflectRegistry.java index 6771ad7..aed1a59 100644 --- a/Paper/src/main/java/fr/pandacube/lib/paper/reflect/ReflectRegistry.java +++ b/Paper/src/main/java/fr/pandacube/lib/paper/reflect/ReflectRegistry.java @@ -1,11 +1,14 @@ package fr.pandacube.lib.paper.reflect; +import static fr.pandacube.lib.core.util.ThrowableUtil.wrapEx; + import org.bukkit.NamespacedKey; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import com.mojang.brigadier.tree.CommandNode; +import fr.pandacube.lib.core.util.Log; import fr.pandacube.lib.core.util.Reflect; import fr.pandacube.lib.core.util.Reflect.ReflectClass; import fr.pandacube.lib.core.util.Reflect.ReflectConstructor; @@ -13,131 +16,189 @@ import fr.pandacube.lib.core.util.Reflect.ReflectField; import fr.pandacube.lib.core.util.Reflect.ReflectMethod; import fr.pandacube.lib.paper.reflect.NMSReflect.ClassMapping; +/** + * Collection of static properties to ease access to commonly used server internals and private class members. + */ public class ReflectRegistry { + + + public static final class NMS { + + public static final class SharedConstants { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.SharedConstants")); + public static final ReflectMethod getCurrentVersion = wrapEx(() -> MAPPING.mojMethod("getCurrentVersion")); + } + + public static final class WorldVersion { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.WorldVersion")); + public static final ReflectMethod getProtocolVersion = wrapEx(() -> MAPPING.runtimeReflect().method("getProtocolVersion")); + } + + public static final class DedicatedServer { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.dedicated.DedicatedServer")); + public static final ReflectField vanillaCommandDispatcher = wrapEx(() -> MAPPING.runtimeReflect().field("vanillaCommandDispatcher")); + } + + public static final class Commands { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.Commands")); + public static final ReflectField dispatcher = wrapEx(() -> DedicatedServer.MAPPING.mojField("dispatcher")); // TODO vérifier + } + + public static final class Vec3 { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.phys.Vec3")); + } + + public static final class Component { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.network.chat.Component")); + } + + public static final class CommandSourceStack { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.CommandSourceStack")); + } + + public static final class EntityArgument { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.EntityArgument")); + public static final ReflectConstructor CONSTRUCTOR = wrapEx(() -> MAPPING.runtimeReflect().constructor(boolean.class, boolean.class)); + } - public static final ClassMapping NMS_SHAREDCONSTANTS = wrapEx(() -> NMSReflect.mojClass("net.minecraft.SharedConstants")); - public static final ReflectMethod NMS_SHAREDCONSTANTS_GETCURRENTVERSION = wrapEx(() -> NMS_SHAREDCONSTANTS.mojMethod("getCurrentVersion")); - - - public static final ClassMapping NMS_WORLDVERSION = wrapEx(() -> NMSReflect.mojClass("net.minecraft.WorldVersion")); - public static final ReflectMethod NMS_WORLDVERSION_GETPROTOCOLVERSION = wrapEx(() -> NMS_WORLDVERSION.runtimeReflect().method("getProtocolVersion")); - - - public static final ClassMapping NMS_DEDICATEDSERVER = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.dedicated.DedicatedServer")); - public static final ReflectField NMS_DEDICATEDSERVER_VANILLACOMMANDDISPATCHER = wrapEx(() -> NMS_DEDICATEDSERVER.runtimeReflect().field("vanillaCommandDispatcher")); - - - public static final ClassMapping NMS_COMMANDS = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.Commands")); - public static final ReflectField NMS_COMMANDS_DISPATCHER = wrapEx(() -> NMS_DEDICATEDSERVER.mojField("dispatcher")); - + public static final class EntitySelector { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.selector.EntitySelector")); + public static final ReflectMethod findEntities = wrapEx(() -> MAPPING.mojMethod("findEntities", CommandSourceStack.MAPPING)); + public static final ReflectMethod findPlayers = wrapEx(() -> MAPPING.mojMethod("findPlayers", CommandSourceStack.MAPPING)); + public static final ReflectMethod findSingleEntity = wrapEx(() -> MAPPING.mojMethod("findSingleEntity", CommandSourceStack.MAPPING)); + public static final ReflectMethod findSinglePlayer = wrapEx(() -> MAPPING.mojMethod("findSinglePlayer", CommandSourceStack.MAPPING)); + } + + public static final class Entity { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.entity.Entity")); + public static final ReflectMethod getBukkitEntity = wrapEx(() -> MAPPING.runtimeReflect().method("getBukkitEntity")); + } - public static final ClassMapping NMS_VEC3 = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.phys.Vec3")); - - - public static final ClassMapping NMS_COMPONENT = wrapEx(() -> NMSReflect.mojClass("net.minecraft.network.chat.Component")); - + public static final class ComponentArgument { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.ComponentArgument")); + public static final ReflectConstructor CONSTRUCTOR = wrapEx(() -> MAPPING.runtimeReflect().constructor()); + } + + public static final class BlockStateArgument { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.blocks.BlockStateArgument")); + public static final ReflectConstructor CONSTRUCTOR = wrapEx(() -> MAPPING.runtimeReflect().constructor()); + } + + public static final class Vec3Argument { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.Vec3Argument")); + public static final ReflectMethod vec3 = wrapEx(() -> MAPPING.mojMethod("vec3", boolean.class)); + } - public static final ClassMapping NMS_COMMANDSOURCESTACK = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.CommandSourceStack")); - - - public static final ClassMapping NMS_ENTITYARGUMENT = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.EntityArgument")); - public static final ReflectConstructor NMS_ENTITYARGUMENT_CONSTRUCTOR = wrapEx(() -> NMS_ENTITYARGUMENT.runtimeReflect().constructor(boolean.class, boolean.class)); - - - public static final ClassMapping NMS_ENTITYSELECTOR = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.selector.EntitySelector")); - public static final ReflectMethod NMS_ENTITYSELECTOR_FINDENTITIES = wrapEx(() -> NMS_ENTITYSELECTOR.mojMethod("findEntities", NMS_COMMANDSOURCESTACK)); - public static final ReflectMethod NMS_ENTITYSELECTOR_FINDPLAYERS = wrapEx(() -> NMS_ENTITYSELECTOR.mojMethod("findPlayers", NMS_COMMANDSOURCESTACK)); - public static final ReflectMethod NMS_ENTITYSELECTOR_FINDSINGLEENTITY = wrapEx(() -> NMS_ENTITYSELECTOR.mojMethod("findSingleEntity", NMS_COMMANDSOURCESTACK)); - public static final ReflectMethod NMS_ENTITYSELECTOR_FINDSINGLEPLAYER = wrapEx(() -> NMS_ENTITYSELECTOR.mojMethod("findSinglePlayer", NMS_COMMANDSOURCESTACK)); - - - public static final ClassMapping NMS_ENTITY = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.entity.Entity")); - public static final ReflectMethod NMS_ENTITY_GETBUKKITENTITY = wrapEx(() -> NMS_ENTITY.runtimeReflect().method("getBukkitEntity")); - - - - public static final ClassMapping NMS_COMPONENTARGUMENT = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.ComponentArgument")); - public static final ReflectConstructor NMS_COMPONENTARGUMENT_CONSTRUCTOR = wrapEx(() -> NMS_COMPONENTARGUMENT.runtimeReflect().constructor()); - - - public static final ClassMapping NMS_BLOCKSTATEARGUMENT = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.blocks.BlockStateArgument")); - public static final ReflectConstructor NMS_BLOCKSTATEARGUMENT_CONSTRUCTOR = wrapEx(() -> NMS_BLOCKSTATEARGUMENT.runtimeReflect().constructor()); - - - public static final ClassMapping NMS_VEC3ARGUMENT = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.Vec3Argument")); - public static final ReflectMethod NMS_VEC3ARGUMENT_VEC3 = wrapEx(() -> NMS_VEC3ARGUMENT.mojMethod("vec3", boolean.class)); - - - public static final ClassMapping NMS_COORDINATES = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.Coordinates")); - public static final ReflectMethod NMS_COORDINATES_GETPOSITION = wrapEx(() -> NMS_COORDINATES.mojMethod("getPosition", NMS_COMMANDSOURCESTACK)); - public static final ReflectMethod NMS_COORDINATES_GETBLOCKPOS = wrapEx(() -> NMS_COORDINATES.mojMethod("getBlockPos", NMS_COMMANDSOURCESTACK)); - - - public static final ClassMapping NMS_BLOCKPOSARGUMENT = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.BlockPosArgument")); - public static final ReflectMethod NMS_BLOCKPOSARGUMENT_BLOCKPOS = wrapEx(() -> NMS_BLOCKPOSARGUMENT.mojMethod("blockPos")); - - - public static final ClassMapping NMS_BLOCKPOS = wrapEx(() -> NMSReflect.mojClass("net.minecraft.core.BlockPos")); - public static final ReflectMethod NMS_BLOCKPOS_GETX = wrapEx(() -> NMS_BLOCKPOS.mojMethod("getX")); - public static final ReflectMethod NMS_BLOCKPOS_GETY = wrapEx(() -> NMS_BLOCKPOS.mojMethod("getY")); - public static final ReflectMethod NMS_BLOCKPOS_GETZ = wrapEx(() -> NMS_BLOCKPOS.mojMethod("getZ")); - - - public static final ClassMapping NMS_RESOURCELOCATIONARGUMENT = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.ResourceLocationArgument")); - public static final ReflectConstructor NMS_RESOURCELOCATIONARGUMENT_CONSTRUCTOR = wrapEx(() -> NMS_RESOURCELOCATIONARGUMENT.runtimeReflect().constructor()); - - - public static final ClassMapping NMS_RESOURCELOCATION = wrapEx(() -> NMSReflect.mojClass("net.minecraft.resources.ResourceLocation")); - - - public static final ClassMapping NMS_GAMEPROFILEARGUMENT = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.GameProfileArgument")); - public static final ReflectConstructor NMS_GAMEPROFILEARGUMENT_CONSTRUCTOR = wrapEx(() -> NMS_GAMEPROFILEARGUMENT.runtimeReflect().constructor()); - - - - public static final ReflectClass OBC_CRAFTSERVER = wrapEx(() -> OBCReflect.ofClass("CraftServer")); - public static final ReflectMethod OBC_CRAFTSERVER_GETSERVER = wrapEx(() -> OBC_CRAFTSERVER.method("getServer")); - - - public static final ReflectClass OBC_VANILLACOMMANDWRAPPER = wrapEx(() -> OBCReflect.ofClass("command.VanillaCommandWrapper")); - @SuppressWarnings("unchecked") - public static final ReflectConstructor OBC_VANILLACOMMANDWRAPPER_CONSTRUCTOR = - (ReflectConstructor) wrapEx(() -> OBC_VANILLACOMMANDWRAPPER.constructor( - NMS_COMMANDS.runtimeClass(), - CommandNode.class - )); - public static final ReflectField OBC_VANILLACOMMANDWRAPPER_VANILLACOMMAND = wrapEx(() -> OBC_VANILLACOMMANDWRAPPER.field("vanillaCommand")); - public static final ReflectMethod OBC_VANILLACOMMANDWRAPPER_GETLISTENER = wrapEx(() -> OBC_VANILLACOMMANDWRAPPER.method("getListener", CommandSender.class)); - - - public static final ReflectClass OBC_CRAFTNAMESPACEDKEY = wrapEx(() -> OBCReflect.ofClass("util.CraftNamespacedKey")); - public static final ReflectMethod OBC_CRAFTNAMESPACEDKEY_TOMINECRAFT = wrapEx(() -> OBC_CRAFTNAMESPACEDKEY.method("toMinecraft", NamespacedKey.class)); - public static final ReflectMethod OBC_CRAFTNAMESPACEDKEY_FROMMINECRAFT = wrapEx(() -> OBC_CRAFTNAMESPACEDKEY.method("fromMinecraft", NMS_RESOURCELOCATION.runtimeClass())); - - - public static final ReflectClass OBC_CRAFTVECTOR = wrapEx(() -> OBCReflect.ofClass("util.CraftVector")); - public static final ReflectMethod OBC_CRAFTVECTOR_TOBUKKIT_VEC3 = wrapEx(() -> OBC_VANILLACOMMANDWRAPPER.method("toBukkit", NMS_VEC3.runtimeClass())); - - - public static final ReflectClass PAPER_PAPERADVENTURE = wrapEx(() -> Reflect.ofClass("io.papermc.paper.adventure.PaperAdventure")); - public static final ReflectMethod PAPER_PAPERADVENTURE_ASADVENTURE = wrapEx(() -> PAPER_PAPERADVENTURE.method("asAdventure", NMS_COMPONENT.runtimeClass())); - - - public static final ReflectClass BRIGADIER_COMMANDNODE = Reflect.ofClass(CommandNode.class); - public static final ReflectMethod BRIGADIER_COMMANDNODE_REMOVECOMMAND = wrapEx(() -> BRIGADIER_COMMANDNODE.method("removeCommand", String.class)); - - - - - private interface SupplierException { - public T get() throws Exception; + public static final class Coordinates { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.Coordinates")); + public static final ReflectMethod getPosition = wrapEx(() -> MAPPING.mojMethod("getPosition", CommandSourceStack.MAPPING)); + public static final ReflectMethod getBlockPos = wrapEx(() -> MAPPING.mojMethod("getBlockPos", CommandSourceStack.MAPPING)); + } + + public static final class BlockPosArgument { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.BlockPosArgument")); + public static final ReflectMethod blockPos = wrapEx(() -> MAPPING.mojMethod("blockPos")); + } + + public static final class BlockPos { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.core.BlockPos")); + public static final ReflectMethod BLOCKPOS_GETX = wrapEx(() -> MAPPING.mojMethod("getX")); + public static final ReflectMethod BLOCKPOS_GETY = wrapEx(() -> MAPPING.mojMethod("getY")); + public static final ReflectMethod BLOCKPOS_GETZ = wrapEx(() -> MAPPING.mojMethod("getZ")); + } + + public static final class ResourceLocationArgument { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.ResourceLocationArgument")); + public static final ReflectConstructor CONSTRUCTOR = wrapEx(() -> MAPPING.runtimeReflect().constructor()); + } + + public static final class ResourceLocation { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.resources.ResourceLocation")); + } + + public static final class GameProfileArgument { + public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.GameProfileArgument")); + public static final ReflectConstructor CONSTRUCTOR = wrapEx(() -> MAPPING.runtimeReflect().constructor()); + } + } - private static T wrapEx(SupplierException prv) { + + public static final class OBC { + + public static final class CraftServer { + public static final ReflectClass REFLECT = wrapEx(() -> OBCReflect.ofClass("CraftServer")); + public static final ReflectMethod getServer = wrapEx(() -> REFLECT.method("getServer")); + } + + public static final class VanillaCommandWrapper { + public static final ReflectClass REFLECT = wrapEx(() -> OBCReflect.ofClass("command.VanillaCommandWrapper")); + @SuppressWarnings("unchecked") + public static final ReflectConstructor CONSTRUTOR = + (ReflectConstructor) wrapEx(() -> REFLECT.constructor( + NMS.Commands.MAPPING.runtimeClass(), + CommandNode.class + )); + public static final ReflectField vanillaCommand = wrapEx(() -> REFLECT.field("vanillaCommand")); + public static final ReflectMethod getListener = wrapEx(() -> REFLECT.method("getListener", CommandSender.class)); + } + + public static final class CraftNamespacedKey { + public static final ReflectClass REFLECT = wrapEx(() -> OBCReflect.ofClass("util.CraftNamespacedKey")); + public static final ReflectMethod toMinecraft = wrapEx(() -> REFLECT.method("toMinecraft", NamespacedKey.class)); + public static final ReflectMethod fromMinecraft = wrapEx(() -> REFLECT.method("fromMinecraft", NMS.ResourceLocation.MAPPING.runtimeClass())); + } + + public static final class CraftVector { + public static final ReflectClass REFLECT = wrapEx(() -> OBCReflect.ofClass("util.CraftVector")); + public static final ReflectMethod toBukkit_vec3 = wrapEx(() -> REFLECT.method("toBukkit", NMS.Vec3.MAPPING.runtimeClass())); + } + + } + + + public static final class Paper { + + public static final class PaperAdventure { + public static final ReflectClass REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.adventure.PaperAdventure")); + public static final ReflectMethod asAdventure = wrapEx(() -> REFLECT.method("asAdventure", NMS.Component.MAPPING.runtimeClass())); + } + + } + + + public static final class Brigadier { + + public static final class CommandNode { + public static final ReflectClass REFLECT = Reflect.ofClass(com.mojang.brigadier.tree.CommandNode.class); + public static final ReflectMethod removeCommand = wrapEx(() -> REFLECT.method("removeCommand", String.class)); + } + + } + + + + /* + * Initialization stuff + */ + + public static void init() { + initRecursively(ReflectRegistry.class); + } + + private static void initRecursively(Class cl) { try { - return prv.get(); - } catch (Exception e) { - throw new RuntimeException(e); + Class.forName(cl.getName()); // force initializing the member classes + } catch (ExceptionInInitializerError e) { + Log.severe("Error while initilizing a ReflectRegistry entry at " + cl.getName(), e.getCause()); + } catch (NoClassDefFoundError e) { + // if a previously initialized class failed to actually initialize + Log.severe("Error while initilizing a ReflectRegistry entry at " + cl.getName() + " due to a previously failed initialization (" + e.getMessage() + ")"); + } catch (ClassNotFoundException e) { + Log.severe("Wut? (should not append)", e); + } + for (Class declaredClass : cl.getDeclaredClasses()) { + initRecursively(declaredClass); } }