Archiviert
13
0

Invert the actual packet instance instead of a new instance.

In NetworkFieldInjector, we use a "inverted" packet class to undo the 
data received counter when a packet has been cancelled. 

Previously, we would generate a proxy class that inherits from the 
class of the packet (Packet3Chat, etc.) along with its size() method 
(which is called and added to the counter, cancelling the other packet),
but this doesn't work for packets that are dynamically sized such as
Packet255KickDisconnect. Instead, we now pass the actual instance to
 the proxy class through a weak hash map.
Dieser Commit ist enthalten in:
Kristian S. Stangeland 2013-05-07 23:11:41 +02:00
Ursprung a2b04e055a
Commit 6af440789c
2 geänderte Dateien mit 97 neuen und 74 gelöschten Zeilen

Datei anzeigen

@ -52,8 +52,9 @@ public interface ListenerInvoker {
public abstract void unregisterPacketClass(Class<?> clazz); public abstract void unregisterPacketClass(Class<?> clazz);
/** /**
* Remove a given class from the packet registry. Internal method. * Register a given class in the packet registry. Internal method.
* @param clazz - class to remove. * @param clazz - class to register.
* @param packetID - the the new associated packet ID.
*/ */
public abstract void registerPacketClass(Class<?> clazz, int packetID); public abstract void registerPacketClass(Class<?> clazz, int packetID);

Datei anzeigen

@ -21,12 +21,16 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import com.comphenix.protocol.Packets;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.error.Report; import com.comphenix.protocol.error.Report;
import com.comphenix.protocol.error.ReportType; import com.comphenix.protocol.error.ReportType;
import com.comphenix.protocol.injector.ListenerInvoker; import com.comphenix.protocol.injector.ListenerInvoker;
import com.comphenix.protocol.injector.player.NetworkFieldInjector.FakePacket; import com.comphenix.protocol.injector.player.NetworkFieldInjector.FakePacket;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.google.common.collect.MapMaker;
import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.Enhancer;
@ -46,6 +50,9 @@ class InjectedArrayList extends ArrayList<Object> {
*/ */
private static final long serialVersionUID = -1173865905404280990L; private static final long serialVersionUID = -1173865905404280990L;
// Fake inverted proxy objects
private static ConcurrentMap<Object, Object> delegateLookup = new MapMaker().weakKeys().makeMap();
private transient PlayerInjector injector; private transient PlayerInjector injector;
private transient Set<Object> ignoredPackets; private transient Set<Object> ignoredPackets;
private transient ClassLoader classLoader; private transient ClassLoader classLoader;
@ -108,9 +115,6 @@ class InjectedArrayList extends ArrayList<Object> {
ListenerInvoker invoker = injector.getInvoker(); ListenerInvoker invoker = injector.getInvoker();
int packetID = invoker.getPacketID(source); int packetID = invoker.getPacketID(source);
Class<?> type = invoker.getPacketClassFromID(packetID, true);
System.out.println(type.getName());
// We want to subtract the byte amount that were added to the running // We want to subtract the byte amount that were added to the running
// total of outstanding packets. Otherwise, cancelling too many packets // total of outstanding packets. Otherwise, cancelling too many packets
@ -131,7 +135,7 @@ class InjectedArrayList extends ArrayList<Object> {
// ect. // ect.
// } // }
Enhancer ex = new Enhancer(); Enhancer ex = new Enhancer();
ex.setSuperclass(type); ex.setSuperclass(MinecraftReflection.getPacketClass());
ex.setInterfaces(new Class[] { FakePacket.class } ); ex.setInterfaces(new Class[] { FakePacket.class } );
ex.setUseCache(true); ex.setUseCache(true);
ex.setClassLoader(classLoader); ex.setClassLoader(classLoader);
@ -143,7 +147,10 @@ class InjectedArrayList extends ArrayList<Object> {
try { try {
// Temporarily associate the fake packet class // Temporarily associate the fake packet class
invoker.registerPacketClass(proxyClass, packetID); invoker.registerPacketClass(proxyClass, packetID);
return proxyClass.newInstance(); Object proxy = proxyClass.newInstance();
InjectedArrayList.registerDelegate(proxy, source);
return proxy;
} catch (Exception e) { } catch (Exception e) {
// Don't pollute the throws tree // Don't pollute the throws tree
@ -154,6 +161,15 @@ class InjectedArrayList extends ArrayList<Object> {
} }
} }
/**
* Ensure that the inverted integer proxy uses the given object as source.
* @param proxy - inverted integer proxy.
* @param source - source object.
*/
private static void registerDelegate(Object proxy, Object source) {
delegateLookup.put(proxy, source);
}
/** /**
* Inverts the integer result of every integer method. * Inverts the integer result of every integer method.
* @author Kristian * @author Kristian
@ -161,11 +177,17 @@ class InjectedArrayList extends ArrayList<Object> {
private class InvertedIntegerCallback implements MethodInterceptor { private class InvertedIntegerCallback implements MethodInterceptor {
@Override @Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
final Object delegate = delegateLookup.get(obj);
if (delegate == null) {
throw new IllegalStateException("Unable to find delegate source for " + obj);
}
if (method.getReturnType().equals(int.class) && args.length == 0) { if (method.getReturnType().equals(int.class) && args.length == 0) {
Integer result = (Integer) proxy.invokeSuper(obj, args); Integer result = (Integer) proxy.invoke(delegate, args);
return -result; return -result;
} else { } else {
return proxy.invokeSuper(obj, args); return proxy.invoke(delegate, args);
} }
} }
} }