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.reflection.Reflections;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandMap;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.defaults.BukkitCommand;
|
||||
|
||||
|
@ -23,7 +22,7 @@ public class Command extends BukkitCommand {
|
|||
}
|
||||
|
||||
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()) {
|
||||
if (method.isAnnotationPresent(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 {
|
||||
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) {
|
||||
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 {
|
||||
Object dataWatcher = Reflections.GET_DATA_WATCHER_METHOD.get().invoke(nmsEntity);
|
||||
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) {
|
||||
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<Class<?>[]> parameterTypes = new ArrayList<>();
|
||||
private Class<?> expectType;
|
||||
private boolean strict = true;
|
||||
|
||||
public ReflectionBuilder(String reflectionPackage) {
|
||||
this(reflectionPackage, "", "", null);
|
||||
|
@ -60,6 +61,15 @@ public class ReflectionBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ReflectionBuilder setStrict(boolean strict) {
|
||||
this.strict = strict;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isStrict() {
|
||||
return strict;
|
||||
}
|
||||
|
||||
public Class<?> getExpectType() {
|
||||
return expectType;
|
||||
}
|
||||
|
|
|
@ -3,50 +3,46 @@ package io.github.znetworkw.znpcservers.reflection;
|
|||
import io.github.znetworkw.znpcservers.utility.Utils;
|
||||
import lol.pyr.znpcsplus.ZNPCsPlus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class ReflectionLazyLoader<T> {
|
||||
protected final List<String> possibleClassNames;
|
||||
|
||||
protected Class<?> reflectionClass;
|
||||
|
||||
protected List<Class<?>> reflectionClasses = new ArrayList<>();
|
||||
protected final boolean strict;
|
||||
private T cached;
|
||||
|
||||
private boolean loaded = false;
|
||||
|
||||
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;
|
||||
for (String classes : possibleClassNames) {
|
||||
try {
|
||||
this.reflectionClass = Class.forName(classes);
|
||||
break;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
this.strict = strict;
|
||||
for (String name : possibleClassNames) try {
|
||||
reflectionClasses.add(Class.forName(name));
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
}
|
||||
|
||||
public T get() {
|
||||
return get(false);
|
||||
}
|
||||
|
||||
public T get(boolean missAllowed) {
|
||||
if (this.loaded) return this.cached;
|
||||
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());
|
||||
if (eval == null) throw new NullPointerException();
|
||||
if (eval == null) throw new RuntimeException("Returned value is null");
|
||||
} catch (Throwable throwable) {
|
||||
if (!missAllowed) {
|
||||
warn(getClass().getSimpleName() + " get failed!");
|
||||
if (strict) {
|
||||
warn(" ----- REFLECTION FAILURE DEBUG INFORMATION, REPORT THIS ON OUR GITHUB ----- ");
|
||||
warn(getClass().getSimpleName() + " failed!");
|
||||
warn("Class Names: " + possibleClassNames);
|
||||
warn("Loader Type: " + getClass().getCanonicalName());
|
||||
warn("Reflection Type: " + getClass().getCanonicalName());
|
||||
warn("Bukkit Version: " + Utils.BUKKIT_VERSION + " (" + Utils.getBukkitPackage() + ")");
|
||||
printDebugInfo(this::warn);
|
||||
warn("Exception:");
|
||||
throwable.printStackTrace();
|
||||
warn(" ----- REFLECTION FAILURE DEBUG INFORMATION, REPORT THIS ON OUR GITHUB ----- ");
|
||||
}
|
||||
}
|
||||
this.loaded = true;
|
||||
|
@ -58,4 +54,5 @@ public abstract class ReflectionLazyLoader<T> {
|
|||
}
|
||||
|
||||
protected abstract T load() throws Exception;
|
||||
protected void printDebugInfo(Consumer<String> logger) {}
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
package io.github.znetworkw.znpcservers.reflection;
|
||||
|
||||
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.netty.channel.Channel;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandMap;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
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)
|
||||
.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)
|
||||
.withSubClass("monster")
|
||||
|
@ -120,20 +125,24 @@ public final class Reflections {
|
|||
|
||||
public static final Class<?> ENTITY_TURTLE = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
|
||||
.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)
|
||||
.withSubClass("monster.warden")
|
||||
.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)
|
||||
.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)
|
||||
.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)
|
||||
.withSubClass("animal")
|
||||
|
@ -145,11 +154,13 @@ public final class Reflections {
|
|||
|
||||
public static final Class<?> ENTITY_POLAR_BEAR_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
|
||||
.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)
|
||||
.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)
|
||||
.withSubClass("animal")
|
||||
|
@ -161,7 +172,8 @@ public final class Reflections {
|
|||
|
||||
public static final Class<?> ENTITY_SHULKER_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
|
||||
.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)
|
||||
.withSubClass("monster")
|
||||
|
@ -205,15 +217,18 @@ public final class Reflections {
|
|||
|
||||
public static final Class<?> ENTITY_AXOLOTL_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.ENTITY)
|
||||
.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)
|
||||
.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)
|
||||
.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)
|
||||
.withClassName("EntityTypes")).get();
|
||||
|
@ -222,7 +237,8 @@ public final class Reflections {
|
|||
.withClassName("EnumChatFormat")).get();
|
||||
|
||||
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)
|
||||
.withClassName("IChatBaseComponent")).get();
|
||||
|
@ -231,16 +247,20 @@ public final class Reflections {
|
|||
.withClassName("ItemStack")).get();
|
||||
|
||||
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)
|
||||
.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)
|
||||
.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)
|
||||
.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)
|
||||
.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)
|
||||
.withClassName("PacketPlayOutPlayerInfo")
|
||||
.withClassName("ClientboundPlayerInfoUpdatePacket"))
|
||||
.get();
|
||||
.withClassName("ClientboundPlayerInfoUpdatePacket")).get();
|
||||
|
||||
public static final Class<?> PACKET_PLAY_OUT_PLAYER_INFO_REMOVE_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
|
||||
.withClassName("ClientboundPlayerInfoRemovePacket"))
|
||||
.get(true);
|
||||
.withClassName("ClientboundPlayerInfoRemovePacket")
|
||||
.setStrict(false)).get();
|
||||
|
||||
public static final Class<?> PACKET_PLAY_OUT_SCOREBOARD_TEAM_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
|
||||
.withClassName("PacketPlayOutScoreboardTeam")).get();
|
||||
|
@ -291,7 +310,8 @@ public final class Reflections {
|
|||
.withClassName("util.CraftChatMessage")).get();
|
||||
|
||||
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)
|
||||
.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)
|
||||
.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)
|
||||
.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)
|
||||
.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)
|
||||
.withClassName("PacketPlayOutEntityMetadata")
|
||||
|
@ -558,7 +580,7 @@ public final class Reflections {
|
|||
.withClassName(ENUM_TAG_VISIBILITY)
|
||||
.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")
|
||||
.withFieldName("commandMap")).valueLoader(Bukkit.getServer());
|
||||
.withFieldName("commandMap")).valueLoader(Bukkit.getServer(), CommandMap.class);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
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.ReflectionLazyLoader;
|
||||
|
||||
public class ClassReflection extends ReflectionLazyLoader<Class<?>> {
|
||||
public ClassReflection(ReflectionBuilder reflectionBuilder) {
|
||||
|
@ -9,6 +9,6 @@ public class ClassReflection extends ReflectionLazyLoader<Class<?>> {
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
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.ReflectionLazyLoader;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ConstructorReflection extends ReflectionLazyLoader<Constructor<?>> {
|
||||
private final ImmutableList<Class<?>[]> parameterTypes;
|
||||
|
@ -16,13 +17,28 @@ public class ConstructorReflection extends ReflectionLazyLoader<Constructor<?>>
|
|||
}
|
||||
|
||||
protected Constructor<?> load() throws NoSuchMethodException {
|
||||
Constructor<?> constructor = null;
|
||||
if (Iterables.size(parameterTypes) > 1) {
|
||||
for (Class<?>[] keyParameters : parameterTypes) try {
|
||||
constructor = this.reflectionClass.getDeclaredConstructor(keyParameters);
|
||||
} catch (NoSuchMethodException ignored) {}
|
||||
} else constructor = (Iterables.size(parameterTypes) > 0) ? this.reflectionClass.getDeclaredConstructor(Iterables.get(parameterTypes, 0)) : this.reflectionClass.getDeclaredConstructor();
|
||||
if (constructor != null) constructor.setAccessible(true);
|
||||
return constructor;
|
||||
for (Class<?> clazz : this.reflectionClasses) {
|
||||
Constructor<?> constructor = load(clazz);
|
||||
if (constructor != null) return constructor;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
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;
|
||||
} 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;
|
||||
|
||||
import io.github.znetworkw.znpcservers.reflection.ReflectionLazyLoader;
|
||||
import io.github.znetworkw.znpcservers.reflection.EnumPropertyCache;
|
||||
import io.github.znetworkw.znpcservers.reflection.ReflectionBuilder;
|
||||
import io.github.znetworkw.znpcservers.reflection.ReflectionLazyLoader;
|
||||
|
||||
public class EnumReflection extends ReflectionLazyLoader<Enum<?>[]> {
|
||||
public EnumReflection(ReflectionBuilder reflectionBuilder) {
|
||||
|
@ -10,8 +10,9 @@ public class EnumReflection extends ReflectionLazyLoader<Enum<?>[]> {
|
|||
}
|
||||
|
||||
protected Enum<?>[] load() {
|
||||
Enum<?>[] enums = (Enum<?>[]) this.reflectionClass.getEnumConstants();
|
||||
for (Enum<?> enumConstant : enums) EnumPropertyCache.register(enumConstant.name(), enumConstant, this.reflectionClass);
|
||||
if (reflectionClasses.size() == 0) return null;
|
||||
Enum<?>[] enums = (Enum<?>[]) this.reflectionClasses.get(0).getEnumConstants();
|
||||
for (Enum<?> enumConstant : enums) EnumPropertyCache.register(enumConstant.name(), enumConstant, this.reflectionClasses.get(0));
|
||||
return enums;
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import io.github.znetworkw.znpcservers.reflection.ReflectionBuilder;
|
|||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class FieldReflection extends ReflectionLazyLoader<Field> {
|
||||
private final String fieldName;
|
||||
|
@ -17,39 +18,64 @@ public class FieldReflection extends ReflectionLazyLoader<Field> {
|
|||
}
|
||||
|
||||
protected Field load() throws NoSuchFieldException {
|
||||
if (expectType != null)
|
||||
for (Field field1 : this.reflectionClass.getDeclaredFields()) {
|
||||
if (field1.getType() == expectType) {
|
||||
field1.setAccessible(true);
|
||||
return field1;
|
||||
}
|
||||
}
|
||||
Field field = this.reflectionClass.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
for (Class<?> clazz : this.reflectionClasses) {
|
||||
Field field = load(clazz);
|
||||
if (field != null) return field;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public FieldValueReflection staticValueLoader() {
|
||||
return new FieldValueReflection(this, possibleClassNames, null);
|
||||
private Field load(Class<?> clazz) {
|
||||
if (expectType != null) for (Field field : clazz.getDeclaredFields()) if (field.getType() == expectType) {
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
}
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
} catch (NoSuchFieldException ignored) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
public FieldValueReflection valueLoader(Object obj) {
|
||||
return new FieldValueReflection(this, possibleClassNames, obj);
|
||||
@Override
|
||||
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 FieldReflection fieldReflection;
|
||||
|
||||
public FieldValueReflection(FieldReflection fieldReflection, List<String> className, Object obj) {
|
||||
super(className);
|
||||
public FieldValueReflection(FieldReflection fieldReflection, List<String> className, Object obj, boolean strict) {
|
||||
super(className, strict);
|
||||
this.obj = obj;
|
||||
this.fieldReflection = fieldReflection;
|
||||
}
|
||||
|
||||
protected Object load() throws IllegalAccessException, NoSuchFieldException {
|
||||
Field field = this.fieldReflection.get();
|
||||
return field.get(obj);
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T load() throws IllegalAccessException, NoSuchFieldException, ClassCastException {
|
||||
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;
|
||||
|
||||
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.ReflectionLazyLoader;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MethodReflection extends ReflectionLazyLoader<Method> {
|
||||
private final ImmutableList<String> methods;
|
||||
|
@ -20,17 +21,43 @@ public class MethodReflection extends ReflectionLazyLoader<Method> {
|
|||
}
|
||||
|
||||
protected Method load() {
|
||||
Method methodThis = null;
|
||||
boolean hasExpectedType = (expectType != null);
|
||||
if (methods.isEmpty() && hasExpectedType) for (Method method : this.reflectionClass.getDeclaredMethods()) if (method.getReturnType() == expectType) return method;
|
||||
for (String methodName : methods) try {
|
||||
Method maybeGet;
|
||||
if (!Iterables.isEmpty(parameterTypes)) maybeGet = this.reflectionClass.getDeclaredMethod(methodName, Iterables.get(parameterTypes, 0));
|
||||
else maybeGet = this.reflectionClass.getDeclaredMethod(methodName);
|
||||
if (expectType != null && expectType != maybeGet.getReturnType()) continue;
|
||||
maybeGet.setAccessible(true);
|
||||
methodThis = maybeGet;
|
||||
} catch (NoSuchMethodException ignored) {}
|
||||
return methodThis;
|
||||
Map<Integer, List<Method>> imperfectMatches = new HashMap<>();
|
||||
for (Class<?> clazz : this.reflectionClasses) {
|
||||
Method method = load(clazz, imperfectMatches);
|
||||
if (method != null) return method;
|
||||
}
|
||||
for (int i = 2; i > 0; i--) if (imperfectMatches.containsKey(i)) {
|
||||
return imperfectMatches.get(i).get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
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