major reflection improvements (fixes #12)
This commit is contained in:
		
							parent
							
								
									dfbd9bebce
								
							
						
					
					
						commit
						5395094063
					
				
					 11 changed files with 199 additions and 101 deletions
				
			
		| 
						 | 
					@ -6,7 +6,6 @@ import io.github.znetworkw.znpcservers.commands.exception.CommandExecuteExceptio
 | 
				
			||||||
import io.github.znetworkw.znpcservers.commands.exception.CommandPermissionException;
 | 
					import io.github.znetworkw.znpcservers.commands.exception.CommandPermissionException;
 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.Reflections;
 | 
					import io.github.znetworkw.znpcservers.reflection.Reflections;
 | 
				
			||||||
import org.bukkit.ChatColor;
 | 
					import org.bukkit.ChatColor;
 | 
				
			||||||
import org.bukkit.command.CommandMap;
 | 
					 | 
				
			||||||
import org.bukkit.command.CommandSender;
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
import org.bukkit.command.defaults.BukkitCommand;
 | 
					import org.bukkit.command.defaults.BukkitCommand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +22,7 @@ public class Command extends BukkitCommand {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void load() {
 | 
					    private void load() {
 | 
				
			||||||
        ((CommandMap) Reflections.COMMAND_MAP_FIELD.get()).register(getName(), this);
 | 
					        Reflections.COMMAND_MAP_FIELD.get().register(getName(), this);
 | 
				
			||||||
        for (Method method : getClass().getMethods()) {
 | 
					        for (Method method : getClass().getMethods()) {
 | 
				
			||||||
            if (method.isAnnotationPresent(CommandInformation.class)) {
 | 
					            if (method.isAnnotationPresent(CommandInformation.class)) {
 | 
				
			||||||
                CommandInformation cmdInfo = method.getAnnotation(CommandInformation.class);
 | 
					                CommandInformation cmdInfo = method.getAnnotation(CommandInformation.class);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ public class PacketV19 extends PacketV18 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Object getPlayerPacket(Object nmsWorld, GameProfile gameProfile) throws ReflectiveOperationException {
 | 
					    public Object getPlayerPacket(Object nmsWorld, GameProfile gameProfile) throws ReflectiveOperationException {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            return Reflections.PLAYER_CONSTRUCTOR_NEW_1.get(true).newInstance(Reflections.GET_SERVER_METHOD.get().invoke(Bukkit.getServer()), nmsWorld, gameProfile, null);
 | 
					            return Reflections.PLAYER_CONSTRUCTOR_NEW_1.get().newInstance(Reflections.GET_SERVER_METHOD.get().invoke(Bukkit.getServer()), nmsWorld, gameProfile, null);
 | 
				
			||||||
        } catch (Throwable e) {
 | 
					        } catch (Throwable e) {
 | 
				
			||||||
            return Reflections.PLAYER_CONSTRUCTOR_NEW_2.get().newInstance(Reflections.GET_SERVER_METHOD.get().invoke(Bukkit.getServer()), nmsWorld, gameProfile);
 | 
					            return Reflections.PLAYER_CONSTRUCTOR_NEW_2.get().newInstance(Reflections.GET_SERVER_METHOD.get().invoke(Bukkit.getServer()), nmsWorld, gameProfile);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ public class PacketV8 implements Packet {
 | 
				
			||||||
    public Object getMetadataPacket(int entityId, Object nmsEntity) throws ReflectiveOperationException {
 | 
					    public Object getMetadataPacket(int entityId, Object nmsEntity) throws ReflectiveOperationException {
 | 
				
			||||||
        Object dataWatcher = Reflections.GET_DATA_WATCHER_METHOD.get().invoke(nmsEntity);
 | 
					        Object dataWatcher = Reflections.GET_DATA_WATCHER_METHOD.get().invoke(nmsEntity);
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            return Reflections.PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR.get(true).newInstance(entityId, dataWatcher, true);
 | 
					            return Reflections.PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR.get().newInstance(entityId, dataWatcher, true);
 | 
				
			||||||
        } catch (Exception e2) {
 | 
					        } catch (Exception e2) {
 | 
				
			||||||
            return Reflections.PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR_V1.get().newInstance(entityId, Reflections.GET_DATAWATCHER_B_LIST.get().invoke(dataWatcher));
 | 
					            return Reflections.PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR_V1.get().newInstance(entityId, Reflections.GET_DATAWATCHER_B_LIST.get().invoke(dataWatcher));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@ public class ReflectionBuilder {
 | 
				
			||||||
    private final ArrayList<String> methods = new ArrayList<>();
 | 
					    private final ArrayList<String> methods = new ArrayList<>();
 | 
				
			||||||
    private final ArrayList<Class<?>[]> parameterTypes = new ArrayList<>();
 | 
					    private final ArrayList<Class<?>[]> parameterTypes = new ArrayList<>();
 | 
				
			||||||
    private Class<?> expectType;
 | 
					    private Class<?> expectType;
 | 
				
			||||||
 | 
					    private boolean strict = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ReflectionBuilder(String reflectionPackage) {
 | 
					    public ReflectionBuilder(String reflectionPackage) {
 | 
				
			||||||
        this(reflectionPackage, "", "", null);
 | 
					        this(reflectionPackage, "", "", null);
 | 
				
			||||||
| 
						 | 
					@ -60,6 +61,15 @@ public class ReflectionBuilder {
 | 
				
			||||||
        return this;
 | 
					        return this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public ReflectionBuilder setStrict(boolean strict) {
 | 
				
			||||||
 | 
					        this.strict = strict;
 | 
				
			||||||
 | 
					        return this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public boolean isStrict() {
 | 
				
			||||||
 | 
					        return strict;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Class<?> getExpectType() {
 | 
					    public Class<?> getExpectType() {
 | 
				
			||||||
        return expectType;
 | 
					        return expectType;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,50 +3,46 @@ package io.github.znetworkw.znpcservers.reflection;
 | 
				
			||||||
import io.github.znetworkw.znpcservers.utility.Utils;
 | 
					import io.github.znetworkw.znpcservers.utility.Utils;
 | 
				
			||||||
import lol.pyr.znpcsplus.ZNPCsPlus;
 | 
					import lol.pyr.znpcsplus.ZNPCsPlus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.function.Consumer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public abstract class ReflectionLazyLoader<T> {
 | 
					public abstract class ReflectionLazyLoader<T> {
 | 
				
			||||||
    protected final List<String> possibleClassNames;
 | 
					    protected final List<String> possibleClassNames;
 | 
				
			||||||
 | 
					    protected List<Class<?>> reflectionClasses = new ArrayList<>();
 | 
				
			||||||
    protected Class<?> reflectionClass;
 | 
					    protected final boolean strict;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    private T cached;
 | 
					    private T cached;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    private boolean loaded = false;
 | 
					    private boolean loaded = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected ReflectionLazyLoader(ReflectionBuilder builder) {
 | 
					    protected ReflectionLazyLoader(ReflectionBuilder builder) {
 | 
				
			||||||
        this(builder.getClassNames());
 | 
					        this(builder.getClassNames(), builder.isStrict());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected ReflectionLazyLoader(List<String> possibleClassNames) {
 | 
					    protected ReflectionLazyLoader(List<String> possibleClassNames, boolean strict) {
 | 
				
			||||||
        this.possibleClassNames = possibleClassNames;
 | 
					        this.possibleClassNames = possibleClassNames;
 | 
				
			||||||
        for (String classes : possibleClassNames) {
 | 
					        this.strict = strict;
 | 
				
			||||||
            try {
 | 
					        for (String name : possibleClassNames) try {
 | 
				
			||||||
                this.reflectionClass = Class.forName(classes);
 | 
					            reflectionClasses.add(Class.forName(name));
 | 
				
			||||||
                break;
 | 
					        } catch (ClassNotFoundException ignored) {}
 | 
				
			||||||
            } catch (ClassNotFoundException ignored) {
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public T get() {
 | 
					    public T get() {
 | 
				
			||||||
        return get(false);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public T get(boolean missAllowed) {
 | 
					 | 
				
			||||||
        if (this.loaded) return this.cached;
 | 
					        if (this.loaded) return this.cached;
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            if (this.reflectionClass == null) throw new ClassNotFoundException("No class found: " + possibleClassNames);
 | 
					            if (this.reflectionClasses.size() == 0) throw new ClassNotFoundException("No class found: " + possibleClassNames);
 | 
				
			||||||
            T eval = (this.cached != null) ? this.cached : (this.cached = load());
 | 
					            T eval = (this.cached != null) ? this.cached : (this.cached = load());
 | 
				
			||||||
            if (eval == null) throw new NullPointerException();
 | 
					            if (eval == null) throw new RuntimeException("Returned value is null");
 | 
				
			||||||
        } catch (Throwable throwable) {
 | 
					        } catch (Throwable throwable) {
 | 
				
			||||||
            if (!missAllowed) {
 | 
					            if (strict) {
 | 
				
			||||||
                warn(getClass().getSimpleName() + " get failed!");
 | 
					                warn(" ----- REFLECTION FAILURE DEBUG INFORMATION, REPORT THIS ON OUR GITHUB ----- ");
 | 
				
			||||||
 | 
					                warn(getClass().getSimpleName() + " failed!");
 | 
				
			||||||
                warn("Class Names: " + possibleClassNames);
 | 
					                warn("Class Names: " + possibleClassNames);
 | 
				
			||||||
                warn("Loader Type: " + getClass().getCanonicalName());
 | 
					                warn("Reflection Type: " + getClass().getCanonicalName());
 | 
				
			||||||
                warn("Bukkit Version: " + Utils.BUKKIT_VERSION + " (" + Utils.getBukkitPackage() + ")");
 | 
					                warn("Bukkit Version: " + Utils.BUKKIT_VERSION + " (" + Utils.getBukkitPackage() + ")");
 | 
				
			||||||
 | 
					                printDebugInfo(this::warn);
 | 
				
			||||||
                warn("Exception:");
 | 
					                warn("Exception:");
 | 
				
			||||||
                throwable.printStackTrace();
 | 
					                throwable.printStackTrace();
 | 
				
			||||||
 | 
					                warn(" ----- REFLECTION FAILURE DEBUG INFORMATION, REPORT THIS ON OUR GITHUB ----- ");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        this.loaded = true;
 | 
					        this.loaded = true;
 | 
				
			||||||
| 
						 | 
					@ -58,4 +54,5 @@ public abstract class ReflectionLazyLoader<T> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected abstract T load() throws Exception;
 | 
					    protected abstract T load() throws Exception;
 | 
				
			||||||
 | 
					    protected void printDebugInfo(Consumer<String> logger) {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,14 @@
 | 
				
			||||||
package io.github.znetworkw.znpcservers.reflection;
 | 
					package io.github.znetworkw.znpcservers.reflection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.mojang.authlib.GameProfile;
 | 
					import com.mojang.authlib.GameProfile;
 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.types.*;
 | 
					import io.github.znetworkw.znpcservers.reflection.types.ClassReflection;
 | 
				
			||||||
 | 
					import io.github.znetworkw.znpcservers.reflection.types.ConstructorReflection;
 | 
				
			||||||
 | 
					import io.github.znetworkw.znpcservers.reflection.types.FieldReflection;
 | 
				
			||||||
 | 
					import io.github.znetworkw.znpcservers.reflection.types.MethodReflection;
 | 
				
			||||||
import io.github.znetworkw.znpcservers.utility.Utils;
 | 
					import io.github.znetworkw.znpcservers.utility.Utils;
 | 
				
			||||||
import io.netty.channel.Channel;
 | 
					import io.netty.channel.Channel;
 | 
				
			||||||
import org.bukkit.Bukkit;
 | 
					import org.bukkit.Bukkit;
 | 
				
			||||||
 | 
					import org.bukkit.command.CommandMap;
 | 
				
			||||||
import org.bukkit.inventory.ItemStack;
 | 
					import org.bukkit.inventory.ItemStack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.lang.reflect.Constructor;
 | 
					import java.lang.reflect.Constructor;
 | 
				
			||||||
| 
						 | 
					@ -104,7 +108,8 @@ public final class Reflections {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_LLAMA_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_LLAMA_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("animal.horse")
 | 
					            .withSubClass("animal.horse")
 | 
				
			||||||
            .withClassName("EntityLlama")).get(!Utils.versionNewer(11));
 | 
					            .withClassName("EntityLlama")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(11))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_MAGMA_CUBE_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_MAGMA_CUBE_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("monster")
 | 
					            .withSubClass("monster")
 | 
				
			||||||
| 
						 | 
					@ -120,20 +125,24 @@ public final class Reflections {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_TURTLE = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_TURTLE = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("animal")
 | 
					            .withSubClass("animal")
 | 
				
			||||||
            .withClassName("EntityTurtle")).get(!Utils.versionNewer(13));
 | 
					            .withClassName("EntityTurtle")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(13))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_WARDEN = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_WARDEN = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("monster.warden")
 | 
					            .withSubClass("monster.warden")
 | 
				
			||||||
            .withClassName("EntityWarden")
 | 
					            .withClassName("EntityWarden")
 | 
				
			||||||
            .withClassName("Warden")).get(!Utils.versionNewer(19));
 | 
					            .withClassName("Warden")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(19))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_BEE_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_BEE_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("animal")
 | 
					            .withSubClass("animal")
 | 
				
			||||||
            .withClassName("EntityBee")).get(!Utils.versionNewer(15));
 | 
					            .withClassName("EntityBee")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(15))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_PARROT_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_PARROT_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("animal")
 | 
					            .withSubClass("animal")
 | 
				
			||||||
            .withClassName("EntityParrot")).get(!Utils.versionNewer(12));
 | 
					            .withClassName("EntityParrot")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(12))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_PIG_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_PIG_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("animal")
 | 
					            .withSubClass("animal")
 | 
				
			||||||
| 
						 | 
					@ -145,11 +154,13 @@ public final class Reflections {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_POLAR_BEAR_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_POLAR_BEAR_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("animal")
 | 
					            .withSubClass("animal")
 | 
				
			||||||
            .withClassName("EntityPolarBear")).get(!Utils.versionNewer(10));
 | 
					            .withClassName("EntityPolarBear")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(10))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_PANDA_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_PANDA_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("animal")
 | 
					            .withSubClass("animal")
 | 
				
			||||||
            .withClassName("EntityPanda")).get(!Utils.versionNewer(14));
 | 
					            .withClassName("EntityPanda")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(14))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_SHEEP_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_SHEEP_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("animal")
 | 
					            .withSubClass("animal")
 | 
				
			||||||
| 
						 | 
					@ -161,7 +172,8 @@ public final class Reflections {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_SHULKER_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_SHULKER_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("monster")
 | 
					            .withSubClass("monster")
 | 
				
			||||||
            .withClassName("EntityShulker")).get(!Utils.versionNewer(9));
 | 
					            .withClassName("EntityShulker")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(9))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_SILVERFISH_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_SILVERFISH_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("monster")
 | 
					            .withSubClass("monster")
 | 
				
			||||||
| 
						 | 
					@ -205,15 +217,18 @@ public final class Reflections {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_AXOLOTL_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_AXOLOTL_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("animal.axolotl")
 | 
					            .withSubClass("animal.axolotl")
 | 
				
			||||||
            .withClassName("Axolotl")).get(!Utils.versionNewer(17));
 | 
					            .withClassName("Axolotl")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(17))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_GOAT_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_GOAT_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("animal.goat")
 | 
					            .withSubClass("animal.goat")
 | 
				
			||||||
            .withClassName("Goat")).get(!Utils.versionNewer(17));
 | 
					            .withClassName("Goat")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(17))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_FOX_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_FOX_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withSubClass("animal")
 | 
					            .withSubClass("animal")
 | 
				
			||||||
            .withClassName("EntityFox")).get(!Utils.versionNewer(14));
 | 
					            .withClassName("EntityFox")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(14))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENTITY_TYPES_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENTITY_TYPES_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withClassName("EntityTypes")).get();
 | 
					            .withClassName("EntityTypes")).get();
 | 
				
			||||||
| 
						 | 
					@ -222,7 +237,8 @@ public final class Reflections {
 | 
				
			||||||
            .withClassName("EnumChatFormat")).get();
 | 
					            .withClassName("EnumChatFormat")).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> ENUM_ITEM_SLOT = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
					    public static final Class<?> ENUM_ITEM_SLOT = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
 | 
				
			||||||
            .withClassName("EnumItemSlot")).get(!Utils.versionNewer(9));
 | 
					            .withClassName("EnumItemSlot")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(9))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> I_CHAT_BASE_COMPONENT = new ClassReflection(new ReflectionBuilder(ReflectionPackage.CHAT)
 | 
					    public static final Class<?> I_CHAT_BASE_COMPONENT = new ClassReflection(new ReflectionBuilder(ReflectionPackage.CHAT)
 | 
				
			||||||
            .withClassName("IChatBaseComponent")).get();
 | 
					            .withClassName("IChatBaseComponent")).get();
 | 
				
			||||||
| 
						 | 
					@ -231,16 +247,20 @@ public final class Reflections {
 | 
				
			||||||
            .withClassName("ItemStack")).get();
 | 
					            .withClassName("ItemStack")).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> DATA_WATCHER_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.SYNCHER)
 | 
					    public static final Class<?> DATA_WATCHER_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.SYNCHER)
 | 
				
			||||||
            .withClassName("DataWatcher")).get(!Utils.versionNewer(9));
 | 
					            .withClassName("DataWatcher")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(9))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> DATA_WATCHER_OBJECT = new ClassReflection(new ReflectionBuilder(ReflectionPackage.SYNCHER)
 | 
					    public static final Class<?> DATA_WATCHER_OBJECT = new ClassReflection(new ReflectionBuilder(ReflectionPackage.SYNCHER)
 | 
				
			||||||
            .withClassName("DataWatcherObject")).get(!Utils.versionNewer(9));
 | 
					            .withClassName("DataWatcherObject")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(9))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> DATA_WATCHER_REGISTRY = new ClassReflection(new ReflectionBuilder(ReflectionPackage.SYNCHER)
 | 
					    public static final Class<?> DATA_WATCHER_REGISTRY = new ClassReflection(new ReflectionBuilder(ReflectionPackage.SYNCHER)
 | 
				
			||||||
            .withClassName("DataWatcherRegistry")).get(!Utils.versionNewer(9));
 | 
					            .withClassName("DataWatcherRegistry")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(9))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> DATA_WATCHER_SERIALIZER = new ClassReflection(new ReflectionBuilder(ReflectionPackage.SYNCHER)
 | 
					    public static final Class<?> DATA_WATCHER_SERIALIZER = new ClassReflection(new ReflectionBuilder(ReflectionPackage.SYNCHER)
 | 
				
			||||||
            .withClassName("DataWatcherSerializer")).get(!Utils.versionNewer(9));
 | 
					            .withClassName("DataWatcherSerializer")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(9))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> WORLD_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.WORLD_LEVEL)
 | 
					    public static final Class<?> WORLD_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.WORLD_LEVEL)
 | 
				
			||||||
            .withClassName("World")).get();
 | 
					            .withClassName("World")).get();
 | 
				
			||||||
| 
						 | 
					@ -265,12 +285,11 @@ public final class Reflections {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> PACKET_PLAY_OUT_PLAYER_INFO_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
					    public static final Class<?> PACKET_PLAY_OUT_PLAYER_INFO_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
				
			||||||
            .withClassName("PacketPlayOutPlayerInfo")
 | 
					            .withClassName("PacketPlayOutPlayerInfo")
 | 
				
			||||||
            .withClassName("ClientboundPlayerInfoUpdatePacket"))
 | 
					            .withClassName("ClientboundPlayerInfoUpdatePacket")).get();
 | 
				
			||||||
            .get();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> PACKET_PLAY_OUT_PLAYER_INFO_REMOVE_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
					    public static final Class<?> PACKET_PLAY_OUT_PLAYER_INFO_REMOVE_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
				
			||||||
            .withClassName("ClientboundPlayerInfoRemovePacket"))
 | 
					            .withClassName("ClientboundPlayerInfoRemovePacket")
 | 
				
			||||||
            .get(true);
 | 
					            .setStrict(false)).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> PACKET_PLAY_OUT_SCOREBOARD_TEAM_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
					    public static final Class<?> PACKET_PLAY_OUT_SCOREBOARD_TEAM_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
				
			||||||
            .withClassName("PacketPlayOutScoreboardTeam")).get();
 | 
					            .withClassName("PacketPlayOutScoreboardTeam")).get();
 | 
				
			||||||
| 
						 | 
					@ -291,7 +310,8 @@ public final class Reflections {
 | 
				
			||||||
            .withClassName("util.CraftChatMessage")).get();
 | 
					            .withClassName("util.CraftChatMessage")).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final Class<?> PROFILE_PUBLIC_KEY_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.WORLD_ENTITY_PLAYER)
 | 
					    public static final Class<?> PROFILE_PUBLIC_KEY_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.WORLD_ENTITY_PLAYER)
 | 
				
			||||||
            .withClassName("ProfilePublicKey")).get(!Utils.versionNewer(19));
 | 
					            .withClassName("ProfilePublicKey")
 | 
				
			||||||
 | 
					            .setStrict(Utils.versionNewer(19))).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final ReflectionLazyLoader<Constructor<?>> SCOREBOARD_TEAM_CONSTRUCTOR = new ConstructorReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
					    public static final ReflectionLazyLoader<Constructor<?>> SCOREBOARD_TEAM_CONSTRUCTOR = new ConstructorReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
				
			||||||
            .withClassName(SCOREBOARD_TEAM_CLASS)
 | 
					            .withClassName(SCOREBOARD_TEAM_CLASS)
 | 
				
			||||||
| 
						 | 
					@ -307,7 +327,8 @@ public final class Reflections {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final ReflectionLazyLoader<Constructor<?>> PLAYER_CONSTRUCTOR_NEW_1 = new ConstructorReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
					    public static final ReflectionLazyLoader<Constructor<?>> PLAYER_CONSTRUCTOR_NEW_1 = new ConstructorReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
				
			||||||
            .withClassName(ENTITY_PLAYER_CLASS)
 | 
					            .withClassName(ENTITY_PLAYER_CLASS)
 | 
				
			||||||
            .withParameterTypes(MINECRAFT_SERVER_CLASS, WORLD_SERVER_CLASS, GameProfile.class, PROFILE_PUBLIC_KEY_CLASS));
 | 
					            .withParameterTypes(MINECRAFT_SERVER_CLASS, WORLD_SERVER_CLASS, GameProfile.class, PROFILE_PUBLIC_KEY_CLASS)
 | 
				
			||||||
 | 
					            .setStrict(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final ReflectionLazyLoader<Constructor<?>> PLAYER_CONSTRUCTOR_NEW_2 = new ConstructorReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
					    public static final ReflectionLazyLoader<Constructor<?>> PLAYER_CONSTRUCTOR_NEW_2 = new ConstructorReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
				
			||||||
            .withClassName(ENTITY_PLAYER_CLASS)
 | 
					            .withClassName(ENTITY_PLAYER_CLASS)
 | 
				
			||||||
| 
						 | 
					@ -335,7 +356,8 @@ public final class Reflections {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final ReflectionLazyLoader<Constructor<?>> PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR = new ConstructorReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
					    public static final ReflectionLazyLoader<Constructor<?>> PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR = new ConstructorReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
				
			||||||
            .withClassName("PacketPlayOutEntityMetadata")
 | 
					            .withClassName("PacketPlayOutEntityMetadata")
 | 
				
			||||||
            .withParameterTypes(int.class, DATA_WATCHER_CLASS, boolean.class));
 | 
					            .withParameterTypes(int.class, DATA_WATCHER_CLASS, boolean.class)
 | 
				
			||||||
 | 
					            .setStrict(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final ReflectionLazyLoader<Constructor<?>> PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR_V1 = new ConstructorReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
					    public static final ReflectionLazyLoader<Constructor<?>> PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR_V1 = new ConstructorReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
 | 
				
			||||||
            .withClassName("PacketPlayOutEntityMetadata")
 | 
					            .withClassName("PacketPlayOutEntityMetadata")
 | 
				
			||||||
| 
						 | 
					@ -558,7 +580,7 @@ public final class Reflections {
 | 
				
			||||||
            .withClassName(ENUM_TAG_VISIBILITY)
 | 
					            .withClassName(ENUM_TAG_VISIBILITY)
 | 
				
			||||||
            .withFieldName("b")).staticValueLoader();
 | 
					            .withFieldName("b")).staticValueLoader();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final ReflectionLazyLoader<Object> COMMAND_MAP_FIELD = new FieldReflection(new ReflectionBuilder(ReflectionPackage.BUKKIT)
 | 
					    public static final ReflectionLazyLoader<CommandMap> COMMAND_MAP_FIELD = new FieldReflection(new ReflectionBuilder(ReflectionPackage.BUKKIT)
 | 
				
			||||||
            .withClassName("CraftServer")
 | 
					            .withClassName("CraftServer")
 | 
				
			||||||
            .withFieldName("commandMap")).valueLoader(Bukkit.getServer());
 | 
					            .withFieldName("commandMap")).valueLoader(Bukkit.getServer(), CommandMap.class);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
package io.github.znetworkw.znpcservers.reflection.types;
 | 
					package io.github.znetworkw.znpcservers.reflection.types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.ReflectionLazyLoader;
 | 
					 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.ReflectionBuilder;
 | 
					import io.github.znetworkw.znpcservers.reflection.ReflectionBuilder;
 | 
				
			||||||
 | 
					import io.github.znetworkw.znpcservers.reflection.ReflectionLazyLoader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ClassReflection extends ReflectionLazyLoader<Class<?>> {
 | 
					public class ClassReflection extends ReflectionLazyLoader<Class<?>> {
 | 
				
			||||||
    public ClassReflection(ReflectionBuilder reflectionBuilder) {
 | 
					    public ClassReflection(ReflectionBuilder reflectionBuilder) {
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,6 @@ public class ClassReflection extends ReflectionLazyLoader<Class<?>> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected Class<?> load() {
 | 
					    protected Class<?> load() {
 | 
				
			||||||
        return this.reflectionClass;
 | 
					        return this.reflectionClasses.size() > 0 ? this.reflectionClasses.get(0) : null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,12 @@
 | 
				
			||||||
package io.github.znetworkw.znpcservers.reflection.types;
 | 
					package io.github.znetworkw.znpcservers.reflection.types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.google.common.collect.ImmutableList;
 | 
					import com.google.common.collect.ImmutableList;
 | 
				
			||||||
import com.google.common.collect.Iterables;
 | 
					 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.ReflectionLazyLoader;
 | 
					 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.ReflectionBuilder;
 | 
					import io.github.znetworkw.znpcservers.reflection.ReflectionBuilder;
 | 
				
			||||||
 | 
					import io.github.znetworkw.znpcservers.reflection.ReflectionLazyLoader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.lang.reflect.Constructor;
 | 
					import java.lang.reflect.Constructor;
 | 
				
			||||||
 | 
					import java.util.Arrays;
 | 
				
			||||||
 | 
					import java.util.function.Consumer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ConstructorReflection extends ReflectionLazyLoader<Constructor<?>> {
 | 
					public class ConstructorReflection extends ReflectionLazyLoader<Constructor<?>> {
 | 
				
			||||||
    private final ImmutableList<Class<?>[]> parameterTypes;
 | 
					    private final ImmutableList<Class<?>[]> parameterTypes;
 | 
				
			||||||
| 
						 | 
					@ -16,13 +17,28 @@ public class ConstructorReflection extends ReflectionLazyLoader<Constructor<?>>
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected Constructor<?> load() throws NoSuchMethodException {
 | 
					    protected Constructor<?> load() throws NoSuchMethodException {
 | 
				
			||||||
        Constructor<?> constructor = null;
 | 
					        for (Class<?> clazz : this.reflectionClasses) {
 | 
				
			||||||
        if (Iterables.size(parameterTypes) > 1) {
 | 
					            Constructor<?> constructor = load(clazz);
 | 
				
			||||||
            for (Class<?>[] keyParameters : parameterTypes) try {
 | 
					            if (constructor != null) return constructor;
 | 
				
			||||||
                constructor = this.reflectionClass.getDeclaredConstructor(keyParameters);
 | 
					        }
 | 
				
			||||||
            } catch (NoSuchMethodException ignored) {}
 | 
					        return null;
 | 
				
			||||||
        } else constructor = (Iterables.size(parameterTypes) > 0) ? this.reflectionClass.getDeclaredConstructor(Iterables.get(parameterTypes, 0)) : this.reflectionClass.getDeclaredConstructor();
 | 
					    }
 | 
				
			||||||
        if (constructor != null) constructor.setAccessible(true);
 | 
					
 | 
				
			||||||
 | 
					    private Constructor<?> load(Class<?> clazz) {
 | 
				
			||||||
 | 
					        if (parameterTypes != null && parameterTypes.size() > 0) for (Class<?>[] possibleConstructor : parameterTypes) try {
 | 
				
			||||||
 | 
					            Constructor<?> constructor = clazz.getDeclaredConstructor(possibleConstructor);
 | 
				
			||||||
 | 
					            constructor.setAccessible(true);
 | 
				
			||||||
            return constructor;
 | 
					            return constructor;
 | 
				
			||||||
 | 
					        } catch (NoSuchMethodException ignored) {}
 | 
				
			||||||
 | 
					        else try {
 | 
				
			||||||
 | 
					            return clazz.getDeclaredConstructor();
 | 
				
			||||||
 | 
					        } catch (NoSuchMethodException ignored) {}
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    protected void printDebugInfo(Consumer<String> logger) {
 | 
				
			||||||
 | 
					        logger.accept("Possible Parameter Type Combinations:");
 | 
				
			||||||
 | 
					        for (Class<?>[] possible : parameterTypes) logger.accept(Arrays.toString(possible));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,8 @@
 | 
				
			||||||
package io.github.znetworkw.znpcservers.reflection.types;
 | 
					package io.github.znetworkw.znpcservers.reflection.types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.ReflectionLazyLoader;
 | 
					 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.EnumPropertyCache;
 | 
					import io.github.znetworkw.znpcservers.reflection.EnumPropertyCache;
 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.ReflectionBuilder;
 | 
					import io.github.znetworkw.znpcservers.reflection.ReflectionBuilder;
 | 
				
			||||||
 | 
					import io.github.znetworkw.znpcservers.reflection.ReflectionLazyLoader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class EnumReflection extends ReflectionLazyLoader<Enum<?>[]> {
 | 
					public class EnumReflection extends ReflectionLazyLoader<Enum<?>[]> {
 | 
				
			||||||
    public EnumReflection(ReflectionBuilder reflectionBuilder) {
 | 
					    public EnumReflection(ReflectionBuilder reflectionBuilder) {
 | 
				
			||||||
| 
						 | 
					@ -10,8 +10,9 @@ public class EnumReflection extends ReflectionLazyLoader<Enum<?>[]> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected Enum<?>[] load() {
 | 
					    protected Enum<?>[] load() {
 | 
				
			||||||
        Enum<?>[] enums = (Enum<?>[]) this.reflectionClass.getEnumConstants();
 | 
					        if (reflectionClasses.size() == 0) return null;
 | 
				
			||||||
        for (Enum<?> enumConstant : enums) EnumPropertyCache.register(enumConstant.name(), enumConstant, this.reflectionClass);
 | 
					        Enum<?>[] enums = (Enum<?>[]) this.reflectionClasses.get(0).getEnumConstants();
 | 
				
			||||||
 | 
					        for (Enum<?> enumConstant : enums) EnumPropertyCache.register(enumConstant.name(), enumConstant, this.reflectionClasses.get(0));
 | 
				
			||||||
        return enums;
 | 
					        return enums;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@ import io.github.znetworkw.znpcservers.reflection.ReflectionBuilder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.lang.reflect.Field;
 | 
					import java.lang.reflect.Field;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.function.Consumer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class FieldReflection extends ReflectionLazyLoader<Field> {
 | 
					public class FieldReflection extends ReflectionLazyLoader<Field> {
 | 
				
			||||||
    private final String fieldName;
 | 
					    private final String fieldName;
 | 
				
			||||||
| 
						 | 
					@ -17,39 +18,64 @@ public class FieldReflection extends ReflectionLazyLoader<Field> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected Field load() throws NoSuchFieldException {
 | 
					    protected Field load() throws NoSuchFieldException {
 | 
				
			||||||
        if (expectType != null)
 | 
					        for (Class<?> clazz : this.reflectionClasses) {
 | 
				
			||||||
            for (Field field1 : this.reflectionClass.getDeclaredFields()) {
 | 
					            Field field = load(clazz);
 | 
				
			||||||
                if (field1.getType() == expectType) {
 | 
					            if (field != null) return field;
 | 
				
			||||||
                    field1.setAccessible(true);
 | 
					 | 
				
			||||||
                    return field1;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        Field field = this.reflectionClass.getDeclaredField(fieldName);
 | 
					
 | 
				
			||||||
 | 
					    private Field load(Class<?> clazz) {
 | 
				
			||||||
 | 
					        if (expectType != null) for (Field field : clazz.getDeclaredFields()) if (field.getType() == expectType) {
 | 
				
			||||||
            field.setAccessible(true);
 | 
					            field.setAccessible(true);
 | 
				
			||||||
            return field;
 | 
					            return field;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
    public FieldValueReflection staticValueLoader() {
 | 
					            Field field = clazz.getDeclaredField(fieldName);
 | 
				
			||||||
        return new FieldValueReflection(this, possibleClassNames, null);
 | 
					            field.setAccessible(true);
 | 
				
			||||||
 | 
					            return field;
 | 
				
			||||||
 | 
					        } catch (NoSuchFieldException ignored) {}
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public FieldValueReflection valueLoader(Object obj) {
 | 
					    @Override
 | 
				
			||||||
        return new FieldValueReflection(this, possibleClassNames, obj);
 | 
					    protected void printDebugInfo(Consumer<String> logger) {
 | 
				
			||||||
 | 
					        logger.accept("Field Name: " + fieldName);
 | 
				
			||||||
 | 
					        logger.accept("Field Type: " + expectType);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static class FieldValueReflection extends ReflectionLazyLoader<Object> {
 | 
					    public FieldValueReflection<Object> staticValueLoader() {
 | 
				
			||||||
 | 
					        return staticValueLoader(Object.class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @SuppressWarnings("unused")
 | 
				
			||||||
 | 
					    public <T> FieldValueReflection<T> staticValueLoader(Class<T> valueType) {
 | 
				
			||||||
 | 
					        return new FieldValueReflection<>(this, possibleClassNames, null, strict);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @SuppressWarnings("unused")
 | 
				
			||||||
 | 
					    public <T> FieldValueReflection<T> valueLoader(Object obj, Class<T> valueType) {
 | 
				
			||||||
 | 
					        return new FieldValueReflection<>(this, possibleClassNames, obj, strict);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static class FieldValueReflection<T> extends ReflectionLazyLoader<T> {
 | 
				
			||||||
        private final Object obj;
 | 
					        private final Object obj;
 | 
				
			||||||
        private final FieldReflection fieldReflection;
 | 
					        private final FieldReflection fieldReflection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public FieldValueReflection(FieldReflection fieldReflection, List<String> className, Object obj) {
 | 
					        public FieldValueReflection(FieldReflection fieldReflection, List<String> className, Object obj, boolean strict) {
 | 
				
			||||||
            super(className);
 | 
					            super(className, strict);
 | 
				
			||||||
            this.obj = obj;
 | 
					            this.obj = obj;
 | 
				
			||||||
            this.fieldReflection = fieldReflection;
 | 
					            this.fieldReflection = fieldReflection;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected Object load() throws IllegalAccessException, NoSuchFieldException {
 | 
					        @SuppressWarnings("unchecked")
 | 
				
			||||||
            Field field = this.fieldReflection.get();
 | 
					        protected T load() throws IllegalAccessException, NoSuchFieldException, ClassCastException {
 | 
				
			||||||
            return field.get(obj);
 | 
					            return (T) this.fieldReflection.get().get(obj);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
 | 
					        protected void printDebugInfo(Consumer<String> logger) {
 | 
				
			||||||
 | 
					            fieldReflection.printDebugInfo(logger);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,12 @@
 | 
				
			||||||
package io.github.znetworkw.znpcservers.reflection.types;
 | 
					package io.github.znetworkw.znpcservers.reflection.types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.google.common.collect.ImmutableList;
 | 
					import com.google.common.collect.ImmutableList;
 | 
				
			||||||
import com.google.common.collect.Iterables;
 | 
					 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.ReflectionLazyLoader;
 | 
					 | 
				
			||||||
import io.github.znetworkw.znpcservers.reflection.ReflectionBuilder;
 | 
					import io.github.znetworkw.znpcservers.reflection.ReflectionBuilder;
 | 
				
			||||||
 | 
					import io.github.znetworkw.znpcservers.reflection.ReflectionLazyLoader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.lang.reflect.Method;
 | 
					import java.lang.reflect.Method;
 | 
				
			||||||
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					import java.util.function.Consumer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class MethodReflection extends ReflectionLazyLoader<Method> {
 | 
					public class MethodReflection extends ReflectionLazyLoader<Method> {
 | 
				
			||||||
    private final ImmutableList<String> methods;
 | 
					    private final ImmutableList<String> methods;
 | 
				
			||||||
| 
						 | 
					@ -20,17 +21,43 @@ public class MethodReflection extends ReflectionLazyLoader<Method> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected Method load() {
 | 
					    protected Method load() {
 | 
				
			||||||
        Method methodThis = null;
 | 
					        Map<Integer, List<Method>> imperfectMatches = new HashMap<>();
 | 
				
			||||||
        boolean hasExpectedType = (expectType != null);
 | 
					        for (Class<?> clazz : this.reflectionClasses) {
 | 
				
			||||||
        if (methods.isEmpty() && hasExpectedType) for (Method method : this.reflectionClass.getDeclaredMethods()) if (method.getReturnType() == expectType) return method;
 | 
					            Method method = load(clazz, imperfectMatches);
 | 
				
			||||||
        for (String methodName : methods) try {
 | 
					            if (method != null) return method;
 | 
				
			||||||
            Method maybeGet;
 | 
					        }
 | 
				
			||||||
            if (!Iterables.isEmpty(parameterTypes)) maybeGet = this.reflectionClass.getDeclaredMethod(methodName, Iterables.get(parameterTypes, 0));
 | 
					        for (int i = 2; i > 0; i--) if (imperfectMatches.containsKey(i)) {
 | 
				
			||||||
            else maybeGet = this.reflectionClass.getDeclaredMethod(methodName);
 | 
					            return imperfectMatches.get(i).get(0);
 | 
				
			||||||
            if (expectType != null && expectType != maybeGet.getReturnType()) continue;
 | 
					        }
 | 
				
			||||||
            maybeGet.setAccessible(true);
 | 
					        return null;
 | 
				
			||||||
            methodThis = maybeGet;
 | 
					    }
 | 
				
			||||||
        } catch (NoSuchMethodException ignored) {}
 | 
					
 | 
				
			||||||
        return methodThis;
 | 
					    private Method load(Class<?> clazz, Map<Integer, List<Method>> imperfectMatches) {
 | 
				
			||||||
 | 
					        for (Method method : clazz.getDeclaredMethods()) {
 | 
				
			||||||
 | 
					            int matches = 0;
 | 
				
			||||||
 | 
					            if (expectType != null) {
 | 
				
			||||||
 | 
					                if (!method.getReturnType().equals(expectType)) continue;
 | 
				
			||||||
 | 
					                matches++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (parameterTypes.size() > 0) out: for (Class<?>[] possible : parameterTypes) {
 | 
				
			||||||
 | 
					                if (method.getParameterCount() != possible.length) continue;
 | 
				
			||||||
 | 
					                for (int i = 0; i < possible.length; i++) if (!method.getParameterTypes()[i].equals(possible[i])) continue out;
 | 
				
			||||||
 | 
					                matches++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (methods.contains(method.getName())) {
 | 
				
			||||||
 | 
					                matches++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (matches == 3) return method;
 | 
				
			||||||
 | 
					            else imperfectMatches.computeIfAbsent(matches, i -> new ArrayList<>()).add(method);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    protected void printDebugInfo(Consumer<String> logger) {
 | 
				
			||||||
 | 
					        logger.accept("Expected Return Type: " + expectType);
 | 
				
			||||||
 | 
					        logger.accept("Possible method names: " + methods);
 | 
				
			||||||
 | 
					        logger.accept("Possible Parameter Type Combinations:");
 | 
				
			||||||
 | 
					        for (Class<?>[] possible : parameterTypes) logger.accept(Arrays.toString(possible));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in a new issue