Refactor pandalib-paper ReflectRegistry + fix some issues in Reflect util class

This commit is contained in:
Marc Baloup 2022-02-17 22:59:50 +01:00
parent 06b89bd271
commit ad74ed2854
5 changed files with 264 additions and 151 deletions

View File

@ -195,13 +195,16 @@ public class Reflect {
public static abstract class ReflectMember<T, EL, EX extends ReflectiveOperationException> {
public static abstract class ReflectMember<T, ID, EL, EX extends ReflectiveOperationException> {
ReflectClass<T> reflectClass;
protected ID identifier;
protected EL cached;
protected ReflectMember(ReflectClass<T> c, boolean bypassFilter) throws EX {
protected ReflectMember(ReflectClass<T> 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<T> extends ReflectMember<T, Field, NoSuchFieldException> {
String elementName;
public static class ReflectField<T> extends ReflectMember<T, String, Field, NoSuchFieldException> {
/* package */ ReflectField(ReflectClass<T> c, String name, boolean bypassFilter) throws NoSuchFieldException {
super(c, bypassFilter);
elementName = name;
super(c, name, bypassFilter);
}
@Override protected Field fetchFromClass(Class<T> 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<T> 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<T> extends ReflectMember<T, Method, NoSuchMethodException> {
String elementName;
MethodIdentifier methodId;
Class<?>[] parameterTypes;
public static class ReflectMethod<T> extends ReflectMember<T, MethodIdentifier, Method, NoSuchMethodException> {
/* package */ ReflectMethod(ReflectClass<T> 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<T> 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<T> 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<T> extends ReflectMember<T, Constructor<T>, NoSuchMethodException> {
ConstructorIdentifier constructorId;
Class<?>[] parameterTypes;
public static class ReflectConstructor<T> extends ReflectMember<T, ConstructorIdentifier, Constructor<T>, NoSuchMethodException> {
/* package */ ReflectConstructor(ReflectClass<T> 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<T> fetchFromClass(Class<T> clazz) throws NoSuchMethodException { return clazz.getDeclaredConstructor(parameterTypes); };
@Override protected Constructor<T> fetchFromClass(Class<T> clazz) throws NoSuchMethodException { return clazz.getDeclaredConstructor(identifier.parameters); };
@Override protected Constructor<T> fetchFromReflectClass(ReflectClass<?> rc) throws NoSuchMethodException { throw new UnsupportedOperationException(); };
@Override protected boolean isEqualOurElement(Constructor<T> el) { return Arrays.equals(parameterTypes, el.getParameterTypes()); };
@Override protected boolean isEqualOurElement(Constructor<T> 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<T> el) { el.setAccessible(true); }

View File

@ -20,4 +20,57 @@ public class ThrowableUtil {
}
}
/**
* A supplier that can possibly throw a checked exception
*/
@FunctionalInterface
public interface SupplierException<T> {
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> T wrapEx(SupplierException<T> 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);
}
}
}

View File

@ -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() {

View File

@ -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<ClassMapping> mappings = loadMappings();
for (ClassMapping clazz : mappings) {
@ -119,8 +124,7 @@ public class NMSReflect {
private static List<ClassMapping> 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();

View File

@ -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 ClassMapping NMS_SHAREDCONSTANTS = wrapEx(() -> NMSReflect.mojClass("net.minecraft.SharedConstants"));
public static final ReflectMethod<?> NMS_SHAREDCONSTANTS_GETCURRENTVERSION = wrapEx(() -> NMS_SHAREDCONSTANTS.mojMethod("getCurrentVersion"));
public static final class NMS {
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 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 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<? extends Command> OBC_VANILLACOMMANDWRAPPER_CONSTRUCTOR =
(ReflectConstructor<? extends Command>) 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<T> {
public T get() throws Exception;
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"));
}
private static <T> T wrapEx(SupplierException<T> prv) {
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 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 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 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());
}
}
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<? extends Command> CONSTRUTOR =
(ReflectConstructor<? extends Command>) 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);
}
}