Make the client packet reader thread-safe.
Dieser Commit ist enthalten in:
Ursprung
01c481dc93
Commit
a60dc3d778
@ -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);
|
||||||
}
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren