Archiviert
13
0

Make the client packet reader thread-safe.

Dieser Commit ist enthalten in:
Kristian S. Stangeland 2012-10-21 22:39:56 +02:00
Ursprung 01c481dc93
Commit a60dc3d778

Datei anzeigen

@ -20,6 +20,8 @@ package com.comphenix.protocol.injector;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import com.comphenix.protocol.Packets; import com.comphenix.protocol.Packets;
@ -35,12 +37,15 @@ class ReadPacketModifier implements MethodInterceptor {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private static Class[] parameters = { DataInputStream.class }; private static Class[] parameters = { DataInputStream.class };
// A cancel marker
private static final Object CANCEL_MARKER = new Object();
// Common for all packets of the same type // Common for all packets of the same type
private PacketInjector packetInjector; private PacketInjector packetInjector;
private int packetID; private int packetID;
// Whether or not a packet has been cancelled // Whether or not a packet has been cancelled
private static WeakHashMap<Object, Object> override = new WeakHashMap<Object, Object>(); private static Map<Object, Object> override = Collections.synchronizedMap(new WeakHashMap<Object, Object>());
public ReadPacketModifier(int packetID, PacketInjector packetInjector) { public ReadPacketModifier(int packetID, PacketInjector packetInjector) {
this.packetID = packetID; this.packetID = packetID;
@ -75,11 +80,12 @@ class ReadPacketModifier implements MethodInterceptor {
return proxy.invokeSuper(thisObj, args); return proxy.invokeSuper(thisObj, args);
} }
if (override.containsKey(thisObj)) { // Atomic retrieval
Object overridenObject = override.get(thisObj); Object overridenObject = override.get(thisObj);
if (overridenObject != null) {
// This packet has been cancelled // This packet has been cancelled
if (overridenObject == null) { if (overridenObject == CANCEL_MARKER) {
// So, cancel all void methods // So, cancel all void methods
if (method.getReturnType().equals(Void.TYPE)) if (method.getReturnType().equals(Void.TYPE))
return null; return null;
@ -108,7 +114,7 @@ class ReadPacketModifier implements MethodInterceptor {
Packet result = event.getPacket().getHandle(); Packet result = event.getPacket().getHandle();
if (event.isCancelled()) { if (event.isCancelled()) {
override.put(thisObj, null); override.put(thisObj, CANCEL_MARKER);
} else if (!objectEquals(thisObj, result)) { } else if (!objectEquals(thisObj, result)) {
override.put(thisObj, result); override.put(thisObj, result);
} }