From 84e31d032b55588e5efe98787e2565b93e46b604 Mon Sep 17 00:00:00 2001 From: Dan Mulloy Date: Wed, 30 Oct 2019 12:02:15 -0400 Subject: [PATCH] Fix villager data breaking versions below 1.14 --- .../protocol/utility/MinecraftReflection.java | 2 +- .../wrappers/WrappedVillagerData.java | 31 +++++++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java b/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java index bc31fc88..33698974 100644 --- a/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java +++ b/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java @@ -2025,7 +2025,7 @@ public class MinecraftReflection { .orElseThrow(() -> new RuntimeException("Failed to find NMS class: " + className)); } - static Class getNullableNMS(String className) { + public static Class getNullableNMS(String className) { if (minecraftPackage == null) minecraftPackage = new CachedPackage(getMinecraftPackage(), getClassSource()); return minecraftPackage.getPackageClass(className).orElse(null); diff --git a/src/main/java/com/comphenix/protocol/wrappers/WrappedVillagerData.java b/src/main/java/com/comphenix/protocol/wrappers/WrappedVillagerData.java index 4b3316d7..425286e5 100644 --- a/src/main/java/com/comphenix/protocol/wrappers/WrappedVillagerData.java +++ b/src/main/java/com/comphenix/protocol/wrappers/WrappedVillagerData.java @@ -3,24 +3,32 @@ package com.comphenix.protocol.wrappers; import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.accessors.Accessors; +import com.comphenix.protocol.reflect.accessors.ConstructorAccessor; import com.comphenix.protocol.utility.MinecraftReflection; public class WrappedVillagerData extends AbstractWrapper implements ClonableWrapper { - private static final Class NMS_CLASS = MinecraftReflection.getMinecraftClass("VillagerData"); - private static final Class TYPE_CLASS = MinecraftReflection.getMinecraftClass("VillagerType"); - private static final Class PROF_CLASS = MinecraftReflection.getMinecraftClass("VillagerProfession"); + private static final Class NMS_CLASS = MinecraftReflection.getNullableNMS("VillagerData"); + private static final Class TYPE_CLASS = MinecraftReflection.getNullableNMS("VillagerType"); + private static final Class PROF_CLASS = MinecraftReflection.getNullableNMS("VillagerProfession"); - private static final EquivalentConverter TYPE_CONVERTER = new EnumWrappers.FauxEnumConverter<>(Type.class, TYPE_CLASS); - private static final EquivalentConverter PROF_CONVERTER = new EnumWrappers.FauxEnumConverter<>(Profession.class, PROF_CLASS); + private static EquivalentConverter TYPE_CONVERTER; + private static EquivalentConverter PROF_CONVERTER; + + static { + if (NMS_CLASS != null) { + TYPE_CONVERTER = new EnumWrappers.FauxEnumConverter<>(Type.class, TYPE_CLASS); + PROF_CONVERTER = new EnumWrappers.FauxEnumConverter<>(Profession.class, PROF_CLASS); + } + } public enum Type { - DESERT, JUNGLE, PLAINS, SAVANNA, SNOW, SWAMP, TAIGA; + DESERT, JUNGLE, PLAINS, SAVANNA, SNOW, SWAMP, TAIGA } public enum Profession { NONE, ARMORER, BUTCHER, CARTOGRAPHER, CLERIC, FARMER, FISHERMAN, FLETCHER, LEATHERWORKER, LIBRARIAN, MASON, NITWIT, SHEPHERD, - TOOLSMITH, WEAPONSMITH; + TOOLSMITH, WEAPONSMITH } private StructureModifier modifier; @@ -36,12 +44,17 @@ public class WrappedVillagerData extends AbstractWrapper implements ClonableWrap return new WrappedVillagerData(handle); } + private static ConstructorAccessor CONSTRUCTOR; + public static WrappedVillagerData fromValues(Type type, Profession profession, int level) { Object genericType = TYPE_CONVERTER.getGeneric(type); Object genericProf = PROF_CONVERTER.getGeneric(profession); - Object handle = Accessors.getConstructorAccessor(NMS_CLASS, TYPE_CLASS, PROF_CLASS, int.class) - .invoke(genericType, genericProf, level); + if (CONSTRUCTOR == null) { + CONSTRUCTOR = Accessors.getConstructorAccessor(NMS_CLASS, TYPE_CLASS, PROF_CLASS, int.class); + } + + Object handle = CONSTRUCTOR.invoke(genericType, genericProf, level); return fromHandle(handle); }