From 8a5e5e849bc1e47ff5f440c9a405b691b624222b Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Thu, 4 Oct 2012 00:58:05 +0200 Subject: [PATCH] Attempt to work around existing injected proxies. This didn't work for Orebfuscator though. --- .../protocol/injector/PlayerInjector.java | 60 +++++++++++++++++-- .../protocol/reflect/FuzzyReflection.java | 4 +- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/ProtocolLib/src/com/comphenix/protocol/injector/PlayerInjector.java b/ProtocolLib/src/com/comphenix/protocol/injector/PlayerInjector.java index 2ae2976d..7d88e25f 100644 --- a/ProtocolLib/src/com/comphenix/protocol/injector/PlayerInjector.java +++ b/ProtocolLib/src/com/comphenix/protocol/injector/PlayerInjector.java @@ -22,9 +22,11 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Set; +import java.util.logging.Level; import net.minecraft.server.EntityPlayer; import net.minecraft.server.Packet; +import net.sf.cglib.proxy.Factory; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; @@ -40,7 +42,9 @@ import com.comphenix.protocol.reflect.VolatileField; abstract class PlayerInjector { // Cache previously retrieved fields - protected static Field serverHandlerField; + private static Field serverHandlerField; + private static Field proxyServerField; + protected static Field networkManagerField; protected static Field inputField; protected static Field netHandlerField; @@ -96,17 +100,26 @@ abstract class PlayerInjector { hasInitialized = true; // Retrieve the server handler - if (serverHandlerField == null) + if (serverHandlerField == null) { serverHandlerField = FuzzyReflection.fromObject(notchEntity).getFieldByType(".*NetServerHandler"); - serverHandlerRef = new VolatileField(serverHandlerField, notchEntity); - serverHandler = serverHandlerRef.getValue(); + proxyServerField = getProxyField(notchEntity, serverHandlerField); + } + // Yo dawg + if (proxyServerField != null) { + Object container = FieldUtils.readField(serverHandlerField, notchEntity, true); + serverHandlerRef = new VolatileField(proxyServerField, container); + } else { + serverHandlerRef = new VolatileField(serverHandlerField, notchEntity); + } + serverHandler = serverHandlerRef.getValue(); + // Next, get the network manager if (networkManagerField == null) networkManagerField = FuzzyReflection.fromObject(serverHandler).getFieldByType(".*NetworkManager"); networkManagerRef = new VolatileField(networkManagerField, serverHandler); networkManager = networkManagerRef.getValue(); - + // Create the network manager modifier from the actual object type if (networkManager != null && networkModifier == null) networkModifier = new StructureModifier(networkManager.getClass(), null, false); @@ -123,6 +136,38 @@ abstract class PlayerInjector { } } + private Field getProxyField(EntityPlayer notchEntity, Field serverField) { + + try { + Object handler = FieldUtils.readField(serverHandlerField, notchEntity, true); + + // Is this a Minecraft hook? + if (handler != null && !handler.getClass().getName().startsWith("net.minecraft.server")) { + + // This is our proxy object + if (handler instanceof Factory) + return null; + + // No? Is it a Proxy type? + try { + FuzzyReflection reflection = FuzzyReflection.fromObject(handler, true); + + // It might be + return reflection.getFieldByType(".*NetServerHandler"); + + } catch (RuntimeException e) { + manager.getLogger().log(Level.WARNING, "Server handler is a proxy type.", e); + } + } + + } catch (IllegalAccessException e) { + manager.getLogger().warning("Unable to load server handler from proxy type."); + } + + // Nope, just go with it + return null; + } + /** * Retrieves the current net handler for this player. * @return Current net handler. @@ -246,6 +291,11 @@ abstract class PlayerInjector { * @return The player's input stream. */ public DataInputStream getInputStream(boolean cache) { + if (inputField == null) + throw new IllegalStateException("Input field is NULL."); + if (networkManager == null) + throw new IllegalStateException("Network manager is NULL."); + // Get the associated input stream try { if (cache && cachedInput != null) diff --git a/ProtocolLib/src/com/comphenix/protocol/reflect/FuzzyReflection.java b/ProtocolLib/src/com/comphenix/protocol/reflect/FuzzyReflection.java index 448507f7..d9f0bad7 100644 --- a/ProtocolLib/src/com/comphenix/protocol/reflect/FuzzyReflection.java +++ b/ProtocolLib/src/com/comphenix/protocol/reflect/FuzzyReflection.java @@ -292,7 +292,9 @@ public class FuzzyReflection { // Like above, only here we test the field type for (Field field : getFields()) { - if (match.matcher(field.getType().getName()).matches()) { + String name = field.getType().getName(); + + if (match.matcher(name).matches()) { return field; } }