Don't reference classes by name - it is not safe.
Dieser Commit ist enthalten in:
Ursprung
d109506cf2
Commit
58017960c9
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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());
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren