Add the ability to load from the default package as well.

This commit is contained in:
Kristian S. Stangeland 2013-02-09 23:22:33 +01:00
parent 02d0a9afd5
commit 0a3c1b13ed
2 changed files with 54 additions and 26 deletions

View File

@ -58,7 +58,7 @@ class CachedPackage {
if (result == null) { if (result == null) {
// Look up the class dynamically // Look up the class dynamically
result = CachedPackage.class.getClassLoader(). result = CachedPackage.class.getClassLoader().
loadClass(packageName + "." + className); loadClass(combine(packageName, className));
cache.put(className, result); cache.put(className, result);
} }
@ -68,4 +68,16 @@ class CachedPackage {
throw new RuntimeException("Cannot find class " + className, e); throw new RuntimeException("Cannot find class " + className, e);
} }
} }
/**
* Correctly combine a package name and the child class we're looking for.
* @param packageName - name of the package, or an empty string for the default package.
* @param className - the class name.
* @return We full class path.
*/
private String combine(String packageName, String className) {
if (packageName.length() == 0)
return className;
return packageName + "." + className;
}
} }

View File

@ -125,15 +125,15 @@ public class MinecraftReflection {
// This server should have a "getHandle" method that we can use // This server should have a "getHandle" method that we can use
if (craftServer != null) { if (craftServer != null) {
try { try {
Class<?> craftClass = craftServer.getClass();
Method getHandle = craftClass.getMethod("getHandle");
Class<?> returnType = getHandle.getReturnType();
String returnName = returnType.getCanonicalName();
// The return type will tell us the full package, regardless of formating // The return type will tell us the full package, regardless of formating
Class<?> craftClass = craftServer.getClass();
CRAFTBUKKIT_PACKAGE = getPackage(craftClass.getCanonicalName()); CRAFTBUKKIT_PACKAGE = getPackage(craftClass.getCanonicalName());
MINECRAFT_FULL_PACKAGE = getPackage(returnName);
// Next, do the same for CraftEntity.getHandle() in order to get the correct Minecraft package
Class<?> craftEntity = getCraftEntityClass();
Method getHandle = craftEntity.getMethod("getHandle");
MINECRAFT_FULL_PACKAGE = getPackage(getHandle.getReturnType().getCanonicalName());
// Pretty important invariant // Pretty important invariant
if (!MINECRAFT_FULL_PACKAGE.startsWith(MINECRAFT_PREFIX_PACKAGE)) { if (!MINECRAFT_FULL_PACKAGE.startsWith(MINECRAFT_PREFIX_PACKAGE)) {
@ -185,7 +185,8 @@ public class MinecraftReflection {
*/ */
public static String getCraftBukkitPackage() { public static String getCraftBukkitPackage() {
// Ensure it has been initialized // Ensure it has been initialized
getMinecraftPackage(); if (CRAFTBUKKIT_PACKAGE == null)
getMinecraftPackage();
return CRAFTBUKKIT_PACKAGE; return CRAFTBUKKIT_PACKAGE;
} }
@ -491,22 +492,29 @@ public class MinecraftReflection {
try { try {
return getMinecraftClass("MinecraftServer"); return getMinecraftClass("MinecraftServer");
} catch (RuntimeException e) { } catch (RuntimeException e) {
// Get the first constructor that matches CraftServer(MINECRAFT_OBJECT, ANY) useFallbackServer();
Constructor<?> selected = FuzzyReflection.fromClass(getCraftBukkitClass("CraftServer")). return getMinecraftClass("MinecraftServer");
getConstructor(FuzzyMethodContract.newBuilder().
parameterMatches(getMinecraftObjectMatcher(), 0).
parameterCount(2).
build()
);
Class<?>[] params = selected.getParameterTypes();
// Jackpot - two classes at the same time!
setMinecraftClass("MinecraftServer", params[0]);
setMinecraftClass("ServerConfigurationManager", params[1]);
return params[0];
} }
} }
/**
* Fallback method that can determine the MinecraftServer and the ServerConfigurationManager.
*/
private static void useFallbackServer() {
// Get the first constructor that matches CraftServer(MINECRAFT_OBJECT, ANY)
Constructor<?> selected = FuzzyReflection.fromClass(getCraftBukkitClass("CraftServer")).
getConstructor(FuzzyMethodContract.newBuilder().
parameterMatches(getMinecraftObjectMatcher(), 0).
parameterCount(2).
build()
);
Class<?>[] params = selected.getParameterTypes();
// Jackpot - two classes at the same time!
setMinecraftClass("MinecraftServer", params[0]);
setMinecraftClass("ServerConfigurationManager", params[1]);
}
/** /**
* Retrieve the player list class (or ServerConfigurationManager), * Retrieve the player list class (or ServerConfigurationManager),
* @return The player list class. * @return The player list class.
@ -516,7 +524,7 @@ public class MinecraftReflection {
return getMinecraftClass("ServerConfigurationManager", "PlayerList"); return getMinecraftClass("ServerConfigurationManager", "PlayerList");
} catch (RuntimeException e) { } catch (RuntimeException e) {
// Try again // Try again
getMinecraftServerClass(); useFallbackServer();
return getMinecraftClass("ServerConfigurationManager"); return getMinecraftClass("ServerConfigurationManager");
} }
} }
@ -909,6 +917,14 @@ public class MinecraftReflection {
return getCraftBukkitClass("entity.CraftPlayer"); return getCraftBukkitClass("entity.CraftPlayer");
} }
/**
* Retrieve the CraftEntity class.
* @return CraftEntity class.
*/
public static Class<?> getCraftEntityClass() {
return getCraftBukkitClass("entity.CraftEntity");
}
/** /**
* Retrieve a CraftItemStack from a given ItemStack. * Retrieve a CraftItemStack from a given ItemStack.
* @param bukkitItemStack - the Bukkit ItemStack to convert. * @param bukkitItemStack - the Bukkit ItemStack to convert.