Archiviert
13
0

Don't reference classes by name - it is not safe.

Dieser Commit ist enthalten in:
Kristian S. Stangeland 2013-01-30 01:45:00 +01:00
Ursprung d109506cf2
Commit 58017960c9
9 geänderte Dateien mit 85 neuen und 14 gelöschten Zeilen

Datei anzeigen

@ -415,7 +415,7 @@ class CommandPacket extends CommandBase {
Class<?> clazz = packet.getClass(); Class<?> clazz = packet.getClass();
// Get the first Minecraft super class // Get the first Minecraft super class
while ((!clazz.getName().startsWith("net.minecraft.server") || while ((!MinecraftReflection.isMinecraftClass(clazz) ||
Factory.class.isAssignableFrom(clazz)) && clazz != Object.class) { Factory.class.isAssignableFrom(clazz)) && clazz != Object.class) {
clazz = clazz.getSuperclass(); clazz = clazz.getSuperclass();
} }

Datei anzeigen

@ -19,7 +19,6 @@ package com.comphenix.protocol;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import java.util.logging.Handler; import java.util.logging.Handler;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.LogRecord; import java.util.logging.LogRecord;
@ -42,7 +41,6 @@ import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
import com.comphenix.protocol.metrics.Statistics; import com.comphenix.protocol.metrics.Statistics;
import com.comphenix.protocol.metrics.Updater; import com.comphenix.protocol.metrics.Updater;
import com.comphenix.protocol.reflect.compiler.BackgroundCompiler; import com.comphenix.protocol.reflect.compiler.BackgroundCompiler;
import com.google.common.collect.Lists;
/** /**
* The main entry point for ProtocolLib. * The main entry point for ProtocolLib.

Datei anzeigen

@ -191,7 +191,7 @@ class EntityUtilities {
// The Minecraft field that's NOT filled in by the constructor // The Minecraft field that's NOT filled in by the constructor
trackedEntitiesField = FuzzyReflection.fromObject(tracker, true). trackedEntitiesField = FuzzyReflection.fromObject(tracker, true).
getFieldByType(MinecraftReflection.MINECRAFT_OBJECT, ignoredTypes); getFieldByType(MinecraftReflection.getMinecraftObjectMatcher(), ignoredTypes);
} }
// Read the entity hashmap // Read the entity hashmap

Datei anzeigen

@ -174,7 +174,7 @@ class MinecraftRegistry {
for (Map.Entry<Class, Integer> entry : getPacketToID().entrySet()) { for (Map.Entry<Class, Integer> entry : getPacketToID().entrySet()) {
if (Objects.equal(entry.getValue(), packetID)) { if (Objects.equal(entry.getValue(), packetID)) {
// Attempt to get the vanilla class here too // Attempt to get the vanilla class here too
if (!forceVanilla || entry.getKey().getName().startsWith("net.minecraft.server")) if (!forceVanilla || MinecraftReflection.isMinecraftClass(entry.getKey()))
return removeEnhancer(entry.getKey(), forceVanilla); return removeEnhancer(entry.getKey(), forceVanilla);
} }
} }

Datei anzeigen

@ -93,7 +93,7 @@ class PacketInjector {
if (intHashMap == null) { if (intHashMap == null) {
// We're looking for the first static field with a Minecraft-object. This should be a IntHashMap. // We're looking for the first static field with a Minecraft-object. This should be a IntHashMap.
Field intHashMapField = FuzzyReflection.fromClass(MinecraftReflection.getPacketClass(), true). Field intHashMapField = FuzzyReflection.fromClass(MinecraftReflection.getPacketClass(), true).
getFieldByType(MinecraftReflection.MINECRAFT_OBJECT); getFieldByType(MinecraftReflection.getMinecraftObjectMatcher());
try { try {
intHashMap = FieldUtils.readField(intHashMapField, (Object) null, true); intHashMap = FieldUtils.readField(intHashMapField, (Object) null, true);

Datei anzeigen

@ -90,7 +90,8 @@ class InjectedServerConnection {
try { try {
if (serverConnectionMethod == null) if (serverConnectionMethod == null)
serverConnectionMethod = FuzzyReflection.fromClass(minecraftServerField.getType()). serverConnectionMethod = FuzzyReflection.fromClass(minecraftServerField.getType()).
getMethodByParameters("getServerConnection", ".*ServerConnection", new String[] {}); getMethodByParameters("getServerConnection",
MinecraftReflection.getServerConnectionClass(), new Class[] {});
// We're using Minecraft 1.3.1 // We're using Minecraft 1.3.1
injectServerConnection(); injectServerConnection();

Datei anzeigen

@ -330,7 +330,7 @@ abstract class PlayerInjector {
Object handler = FieldUtils.readField(serverHandlerField, notchEntity, true); Object handler = FieldUtils.readField(serverHandlerField, notchEntity, true);
// Is this a Minecraft hook? // Is this a Minecraft hook?
if (handler != null && !handler.getClass().getName().startsWith("net.minecraft.server")) { if (handler != null && !MinecraftReflection.isMinecraftObject(handler)) {
// This is our proxy object // This is our proxy object
if (handler instanceof Factory) if (handler instanceof Factory)
@ -380,7 +380,7 @@ abstract class PlayerInjector {
try { try {
// Well, that sucks. Try just Minecraft objects then. // Well, that sucks. Try just Minecraft objects then.
netHandlerField = FuzzyReflection.fromClass(networkManager.getClass(), true). netHandlerField = FuzzyReflection.fromClass(networkManager.getClass(), true).
getFieldByType(MinecraftReflection.MINECRAFT_OBJECT); getFieldByType(MinecraftReflection.getMinecraftObjectMatcher());
} catch (RuntimeException e2) { } catch (RuntimeException e2) {
throw new IllegalAccessException("Cannot locate net handler. " + e2.getMessage()); throw new IllegalAccessException("Cannot locate net handler. " + e2.getMessage());

Datei anzeigen

@ -20,6 +20,7 @@ package com.comphenix.protocol.utility;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.regex.Pattern;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -38,9 +39,17 @@ import com.google.common.base.Joiner;
public class MinecraftReflection { public class MinecraftReflection {
/** /**
* Regular expression that matches a Minecraft object. * Regular expression that matches a Minecraft object.
* <p>
* Replaced by the method {@link #getMinecraftObjectMatcher()}.
*/ */
@Deprecated
public static final String MINECRAFT_OBJECT = "net\\.minecraft(\\.\\w+)+"; public static final String MINECRAFT_OBJECT = "net\\.minecraft(\\.\\w+)+";
/**
* Regular expression computed dynamically.
*/
private static String DYNAMIC_PACKAGE_MATCHER = null;
/** /**
* The package name of all the classes that belongs to the native code in Minecraft. * The package name of all the classes that belongs to the native code in Minecraft.
*/ */
@ -64,6 +73,20 @@ public class MinecraftReflection {
// net.minecraft.server // net.minecraft.server
private static Class<?> itemStackArrayClass; private static Class<?> itemStackArrayClass;
private MinecraftReflection() {
// No need to make this constructable.
}
/**
* Retrieve a regular expression that can match Minecraft package objects.
* @return Minecraft package matcher.
*/
public static String getMinecraftObjectMatcher() {
if (DYNAMIC_PACKAGE_MATCHER == null)
getMinecraftPackage();
return DYNAMIC_PACKAGE_MATCHER;
}
/** /**
* Retrieve the name of the Minecraft server package. * Retrieve the name of the Minecraft server package.
* @return Full canonical name of the Minecraft server package. * @return Full canonical name of the Minecraft server package.
@ -87,6 +110,21 @@ public class MinecraftReflection {
// The return type will tell us the full package, regardless of formating // The return type will tell us the full package, regardless of formating
CRAFTBUKKIT_PACKAGE = getPackage(craftClass.getCanonicalName()); CRAFTBUKKIT_PACKAGE = getPackage(craftClass.getCanonicalName());
MINECRAFT_FULL_PACKAGE = getPackage(returnName); MINECRAFT_FULL_PACKAGE = getPackage(returnName);
// Pretty important invariant
if (!MINECRAFT_FULL_PACKAGE.startsWith(MINECRAFT_PREFIX_PACKAGE)) {
// Assume they're the same instead
MINECRAFT_PREFIX_PACKAGE = MINECRAFT_FULL_PACKAGE;
// The package is usualy flat, so go with that assumtion
DYNAMIC_PACKAGE_MATCHER =
(MINECRAFT_PREFIX_PACKAGE.length() > 0 ?
Pattern.quote(MINECRAFT_PREFIX_PACKAGE + ".") : "") + "\\w+";
} else {
// Use the standard matcher
DYNAMIC_PACKAGE_MATCHER = MINECRAFT_OBJECT;
}
return MINECRAFT_FULL_PACKAGE; return MINECRAFT_FULL_PACKAGE;
} catch (SecurityException e) { } catch (SecurityException e) {
@ -126,7 +164,12 @@ public class MinecraftReflection {
* @return The package name. * @return The package name.
*/ */
private static String getPackage(String fullName) { private static String getPackage(String fullName) {
return fullName.substring(0, fullName.lastIndexOf(".")); int index = fullName.lastIndexOf(".");
if (index > 0)
return fullName.substring(0, index);
else
return ""; // Default package
} }
/** /**
@ -160,6 +203,19 @@ public class MinecraftReflection {
return obj.getClass().getName().startsWith(MINECRAFT_PREFIX_PACKAGE); return obj.getClass().getName().startsWith(MINECRAFT_PREFIX_PACKAGE);
} }
/**
* Determine if the given class is found within the package net.minecraft.server, or any equivalent package.
* @param clazz - the class to test.
* @return TRUE if it can, FALSE otherwise.
*/
public static boolean isMinecraftClass(@Nonnull Class<?> clazz) {
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);
}
/** /**
* Determine if a given object is found in net.minecraft.server, and has the given name. * Determine if a given object is found in net.minecraft.server, and has the given name.
* @param obj - the object to test. * @param obj - the object to test.
@ -289,7 +345,15 @@ public class MinecraftReflection {
} }
/** /**
* Retrieve the NetLoginHandler class. * Retrieve the player list class (or ServerConfigurationManager),
* @return The player list class.
*/
public static Class<?> getPlayerListClass() {
return getMinecraftClass("ServerConfigurationManager", "PlayerList");
}
/**
* Retrieve the NetLoginHandler class (or PendingConnection)
* @return The NetLoginHandler class. * @return The NetLoginHandler class.
*/ */
public static Class<?> getNetLoginHandlerClass() { public static Class<?> getNetLoginHandlerClass() {
@ -297,7 +361,7 @@ public class MinecraftReflection {
} }
/** /**
* Retrieve the NetServerHandler class. * Retrieve the NetServerHandler class (or PlayerConnection)
* @return The NetServerHandler class. * @return The NetServerHandler class.
*/ */
public static Class<?> getNetServerHandlerClass() { public static Class<?> getNetServerHandlerClass() {
@ -313,7 +377,7 @@ public class MinecraftReflection {
} }
/** /**
* Retrieve the NetHandler class. * Retrieve the NetHandler class (or Connection)
* @return The NetHandler class. * @return The NetHandler class.
*/ */
public static Class<?> getNetHandlerClass() { public static Class<?> getNetHandlerClass() {
@ -376,6 +440,14 @@ public class MinecraftReflection {
return getMinecraftClass("WatchableObject"); return getMinecraftClass("WatchableObject");
} }
/**
* Retrieve the ServerConnection abstract class.
* @return The ServerConnection class.
*/
public static Class<?> getServerConnectionClass() {
return getMinecraftClass("ServerConnection");
}
/** /**
* Retrieve the NBT base class. * Retrieve the NBT base class.
* @return The NBT base class. * @return The NBT base class.

Datei anzeigen

@ -574,7 +574,7 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
// Load the get-method // Load the get-method
try { try {
getKeyValueMethod = fuzzy.getMethodByParameters( getKeyValueMethod = fuzzy.getMethodByParameters(
"getWatchableObject", ".*WatchableObject", new String[] { int.class.getName() }); "getWatchableObject", MinecraftReflection.getWatchableObjectClass(), new Class[] { int.class });
getKeyValueMethod.setAccessible(true); getKeyValueMethod.setAccessible(true);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
// Use fallback method // Use fallback method