diff --git a/modules/API/src/main/java/com/comphenix/protocol/reflect/cloning/ImmutableDetector.java b/modules/API/src/main/java/com/comphenix/protocol/reflect/cloning/ImmutableDetector.java index 9083253e..ad81b612 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/reflect/cloning/ImmutableDetector.java +++ b/modules/API/src/main/java/com/comphenix/protocol/reflect/cloning/ImmutableDetector.java @@ -96,9 +96,9 @@ public class ImmutableDetector implements Cloner { } } - if (MinecraftReflection.getBlockClass().isAssignableFrom(type) - || MinecraftReflection.getMinecraftClass("Item").isAssignableFrom(type) - || MinecraftReflection.getMinecraftClass("FluidType").isAssignableFrom(type)) { + if (MinecraftReflection.is(MinecraftReflection.getBlockClass(), type) + || MinecraftReflection.is(MinecraftReflection.getItemClass(), type) + || MinecraftReflection.is(MinecraftReflection.getFluidTypeClass(), type)) { return true; } diff --git a/modules/API/src/main/java/com/comphenix/protocol/utility/CachedPackage.java b/modules/API/src/main/java/com/comphenix/protocol/utility/CachedPackage.java index ec6c1870..6d0bd7ba 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/utility/CachedPackage.java +++ b/modules/API/src/main/java/com/comphenix/protocol/utility/CachedPackage.java @@ -17,8 +17,8 @@ package com.comphenix.protocol.utility; import java.util.Map; +import java.util.Optional; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.collect.Maps; @@ -51,7 +51,7 @@ class CachedPackage { */ public void setPackageClass(String className, Class clazz) { if (clazz != null) { - cache.put(className, Optional.> of(clazz)); + cache.put(className, Optional.of(clazz)); } else { cache.remove(className); } @@ -63,32 +63,21 @@ class CachedPackage { * @return Class object. * @throws RuntimeException If we are unable to find the given class. */ - public Class getPackageClass(String className) { + public Optional> getPackageClass(String className) { Preconditions.checkNotNull(className, "className cannot be null!"); - // See if we've already looked it up - if (cache.containsKey(className)) { - Optional> result = cache.get(className); - if (!result.isPresent()) { - throw new RuntimeException("Cannot find class " + className); + Optional> result = cache.get(className); + if (result == null) { + try { + Class clazz = source.loadClass(combine(packageName, className)); + result = Optional.ofNullable(clazz); + cache.put(className, result); + } catch (ClassNotFoundException ex) { + cache.put(className, Optional.empty()); } - - return result.get(); } - try { - // Try looking it up - Class clazz = source.loadClass(combine(packageName, className)); - if (clazz == null) { - throw new IllegalArgumentException("Source " + source + " returned null for " + className); - } - - cache.put(className, Optional.> of(clazz)); - return clazz; - } catch (ClassNotFoundException ex) { - cache.put(className, Optional.> absent()); - throw new RuntimeException("Cannot find class " + className, ex); - } + return result; } /** diff --git a/modules/API/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java b/modules/API/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java index 61917260..d83729b9 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java +++ b/modules/API/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java @@ -428,6 +428,17 @@ public class MinecraftReflection { return clazz.isAssignableFrom(object.getClass()); } + /** + * Equivalent to {@link #is(Class, Object)} but we don't call getClass again + */ + public static boolean is(Class clazz, Class test) { + if (clazz == null || test == null) { + return false; + } + + return clazz.isAssignableFrom(test); + } + /** * Determine if a given object is a ChunkPosition. * @param obj - the object to test. @@ -1137,6 +1148,14 @@ public class MinecraftReflection { } } + public static Class getItemClass() { + return getNullableNMS("Item"); + } + + public static Class getFluidTypeClass() { + return getNullableNMS("FluidType"); + } + /** * Retrieve the WorldType class. * @return The WorldType class. @@ -1985,7 +2004,8 @@ public class MinecraftReflection { public static Class getCraftBukkitClass(String className) { if (craftbukkitPackage == null) craftbukkitPackage = new CachedPackage(getCraftBukkitPackage(), getClassSource()); - return craftbukkitPackage.getPackageClass(className); + return craftbukkitPackage.getPackageClass(className) + .orElseThrow(() -> new RuntimeException("Failed to find CraftBukkit class: " + className)); } /** @@ -1997,7 +2017,14 @@ public class MinecraftReflection { public static Class getMinecraftClass(String className) { if (minecraftPackage == null) minecraftPackage = new CachedPackage(getMinecraftPackage(), getClassSource()); - return minecraftPackage.getPackageClass(className); + return minecraftPackage.getPackageClass(className) + .orElseThrow(() -> new RuntimeException("Failed to find NMS class: " + className)); + } + + private static Class getNullableNMS(String className) { + if (minecraftPackage == null) + minecraftPackage = new CachedPackage(getMinecraftPackage(), getClassSource()); + return minecraftPackage.getPackageClass(className).orElse(null); } /** @@ -2083,7 +2110,8 @@ public class MinecraftReflection { public static Class getMinecraftLibraryClass(String className) { if (libraryPackage == null) libraryPackage = new CachedPackage("", getClassSource()); - return libraryPackage.getPackageClass(className); + return libraryPackage.getPackageClass(className) + .orElseThrow(() -> new RuntimeException("Failed to find class: " + className)); } /**