From 9a34036d14107481814d3521d5a94a8e911066ac Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Tue, 2 Apr 2013 13:55:18 +0200 Subject: [PATCH] Improve Minecraft class detection --- .../protocol/utility/MinecraftReflection.java | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java index d5bf2329..bb3fed3c 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java @@ -81,6 +81,9 @@ public class MinecraftReflection { private static Constructor craftNMSConstructor; private static Constructor craftBukkitConstructor; + // Matches classes + private static AbstractFuzzyMatcher> fuzzyMatcher; + // New in 1.4.5 private static Method craftNMSMethod; private static Method craftBukkitMethod; @@ -88,7 +91,12 @@ public class MinecraftReflection { // net.minecraft.server private static Class itemStackArrayClass; - + + /** + * Whether or not we're currently initializing the reflection handler. + */ + private static boolean initializing; + private MinecraftReflection() { // No need to make this constructable. } @@ -108,7 +116,9 @@ public class MinecraftReflection { * @return A matcher for Minecraft objects. */ public static AbstractFuzzyMatcher> getMinecraftObjectMatcher() { - return FuzzyMatchers.matchRegex(getMinecraftObjectRegex(), 50); + if (fuzzyMatcher == null) + fuzzyMatcher = FuzzyMatchers.matchRegex(getMinecraftObjectRegex(), 50); + return fuzzyMatcher; } /** @@ -119,6 +129,9 @@ public class MinecraftReflection { // Speed things up if (MINECRAFT_FULL_PACKAGE != null) return MINECRAFT_FULL_PACKAGE; + if (initializing) + throw new IllegalStateException("Already initializing minecraft package!"); + initializing = true; Server craftServer = Bukkit.getServer(); @@ -144,16 +157,16 @@ public class MinecraftReflection { MINECRAFT_PREFIX_PACKAGE = MINECRAFT_FULL_PACKAGE; // The package is usualy flat, so go with that assumtion - DYNAMIC_PACKAGE_MATCHER = + String matcher = (MINECRAFT_PREFIX_PACKAGE.length() > 0 ? Pattern.quote(MINECRAFT_PREFIX_PACKAGE + ".") : "") + "\\w+"; // We'll still accept the default location, however - DYNAMIC_PACKAGE_MATCHER = "(" + DYNAMIC_PACKAGE_MATCHER + ")|(" + MINECRAFT_OBJECT + ")"; + setDynamicPackageMatcher("(" + matcher + ")|(" + MINECRAFT_OBJECT + ")"); } else { // Use the standard matcher - DYNAMIC_PACKAGE_MATCHER = MINECRAFT_OBJECT; + setDynamicPackageMatcher(MINECRAFT_OBJECT); } return MINECRAFT_FULL_PACKAGE; @@ -162,13 +175,27 @@ public class MinecraftReflection { throw new RuntimeException("Security violation. Cannot get handle method.", e); } catch (NoSuchMethodException e) { throw new IllegalStateException("Cannot find getHandle() method on server. Is this a modified CraftBukkit version?", e); + } finally { + initializing = false; } } else { + initializing = false; throw new IllegalStateException("Could not find Bukkit. Is it running?"); } } + /** + * Update the dynamic package matcher. + * @param regex - the Minecraft package regex. + */ + private static void setDynamicPackageMatcher(String regex) { + DYNAMIC_PACKAGE_MATCHER = regex; + + // Ensure that the matcher is regenerated + fuzzyMatcher = null; + } + // Patch for Libigot private static void handleLibigot() { try { @@ -193,7 +220,7 @@ public class MinecraftReflection { CRAFTBUKKIT_PACKAGE = craftBukkitPackage; // Standard matcher - DYNAMIC_PACKAGE_MATCHER = MINECRAFT_OBJECT; + setDynamicPackageMatcher(MINECRAFT_OBJECT); } /** @@ -261,8 +288,7 @@ public class MinecraftReflection { if (clazz == null) throw new IllegalArgumentException("Class cannot be NULL."); - // Doesn't matter if we don't check for the version here - return clazz.getName().startsWith(MINECRAFT_PREFIX_PACKAGE); + return getMinecraftObjectMatcher().isMatch(clazz, null); } /**