mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2025-01-14 04:01:55 +01:00
Ensure that we don't cache wrong methods in the serialization.
This commit is contained in:
parent
86d3461700
commit
ede60970b9
@ -4,7 +4,7 @@
|
|||||||
<groupId>com.comphenix.protocol</groupId>
|
<groupId>com.comphenix.protocol</groupId>
|
||||||
<artifactId>ProtocolLib</artifactId>
|
<artifactId>ProtocolLib</artifactId>
|
||||||
<name>ProtocolLib</name>
|
<name>ProtocolLib</name>
|
||||||
<version>1.7.1</version>
|
<version>1.7.2-SNAPSHOT</version>
|
||||||
<description>Provides read/write access to the Minecraft protocol.</description>
|
<description>Provides read/write access to the Minecraft protocol.</description>
|
||||||
<url>http://dev.bukkit.org/server-mods/protocollib/</url>
|
<url>http://dev.bukkit.org/server-mods/protocollib/</url>
|
||||||
<developers>
|
<developers>
|
||||||
|
@ -29,6 +29,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.WorldType;
|
import org.bukkit.WorldType;
|
||||||
@ -43,6 +44,7 @@ import com.comphenix.protocol.wrappers.BukkitConverters;
|
|||||||
import com.comphenix.protocol.wrappers.ChunkPosition;
|
import com.comphenix.protocol.wrappers.ChunkPosition;
|
||||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||||
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import net.minecraft.server.Packet;
|
import net.minecraft.server.Packet;
|
||||||
|
|
||||||
@ -63,11 +65,11 @@ public class PacketContainer implements Serializable {
|
|||||||
|
|
||||||
// Current structure modifier
|
// Current structure modifier
|
||||||
protected transient StructureModifier<Object> structureModifier;
|
protected transient StructureModifier<Object> structureModifier;
|
||||||
|
|
||||||
// Support for serialization
|
// Support for serialization
|
||||||
private static Method writeMethod;
|
private static ConcurrentMap<Class<?>, Method> writeMethods = Maps.newConcurrentMap();
|
||||||
private static Method readMethod;
|
private static ConcurrentMap<Class<?>, Method> readMethods = Maps.newConcurrentMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a packet container for a new packet.
|
* Creates a packet container for a new packet.
|
||||||
* @param id - ID of the packet to create.
|
* @param id - ID of the packet to create.
|
||||||
@ -100,6 +102,12 @@ public class PacketContainer implements Serializable {
|
|||||||
this.structureModifier = structure;
|
this.structureModifier = structure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For serialization.
|
||||||
|
*/
|
||||||
|
protected PacketContainer() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the underlying Minecraft packet.
|
* Retrieves the underlying Minecraft packet.
|
||||||
* @return Underlying Minecraft packet.
|
* @return Underlying Minecraft packet.
|
||||||
@ -399,14 +407,12 @@ public class PacketContainer implements Serializable {
|
|||||||
|
|
||||||
// We'll take care of NULL packets as well
|
// We'll take care of NULL packets as well
|
||||||
output.writeBoolean(handle != null);
|
output.writeBoolean(handle != null);
|
||||||
|
|
||||||
// Retrieve the write method by reflection
|
|
||||||
if (writeMethod == null)
|
|
||||||
writeMethod = FuzzyReflection.fromObject(handle).getMethodByParameters("write", DataOutputStream.class);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Call the write-method
|
// Call the write-method
|
||||||
writeMethod.invoke(handle, new DataOutputStream(output));
|
getMethodLazily(writeMethods, handle.getClass(), "write", DataOutputStream.class).
|
||||||
|
invoke(handle, new DataOutputStream(output));
|
||||||
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new IOException("Minecraft packet doesn't support DataOutputStream", e);
|
throw new IOException("Minecraft packet doesn't support DataOutputStream", e);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
@ -429,13 +435,11 @@ public class PacketContainer implements Serializable {
|
|||||||
// Create a default instance of the packet
|
// Create a default instance of the packet
|
||||||
handle = StructureCache.newPacket(id);
|
handle = StructureCache.newPacket(id);
|
||||||
|
|
||||||
// Retrieve the read method by reflection
|
|
||||||
if (readMethod == null)
|
|
||||||
readMethod = FuzzyReflection.fromObject(handle).getMethodByParameters("read", DataInputStream.class);
|
|
||||||
|
|
||||||
// Call the read method
|
// Call the read method
|
||||||
try {
|
try {
|
||||||
readMethod.invoke(handle, new DataInputStream(input));
|
getMethodLazily(readMethods, handle.getClass(), "read", DataInputStream.class).
|
||||||
|
invoke(handle, new DataInputStream(input));
|
||||||
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new IOException("Minecraft packet doesn't support DataInputStream", e);
|
throw new IOException("Minecraft packet doesn't support DataInputStream", e);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
@ -448,4 +452,30 @@ public class PacketContainer implements Serializable {
|
|||||||
structureModifier = structureModifier.withTarget(handle);
|
structureModifier = structureModifier.withTarget(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the cached method concurrently.
|
||||||
|
* @param lookup - a lazy lookup cache.
|
||||||
|
* @param handleClass - class type of the current packet.
|
||||||
|
* @param methodName - name of method to retrieve.
|
||||||
|
* @param parameterClass - the one parameter type in the method.
|
||||||
|
* @return Reflected method.
|
||||||
|
*/
|
||||||
|
private Method getMethodLazily(ConcurrentMap<Class<?>, Method> lookup,
|
||||||
|
Class<?> handleClass, String methodName, Class<?> parameterClass) {
|
||||||
|
Method method = lookup.get(handleClass);
|
||||||
|
|
||||||
|
// Atomic operation
|
||||||
|
if (method == null) {
|
||||||
|
Method initialized = FuzzyReflection.fromClass(handleClass).getMethodByParameters(methodName, parameterClass);
|
||||||
|
method = lookup.putIfAbsent(handleClass, initialized);
|
||||||
|
|
||||||
|
// Use our version if we succeeded
|
||||||
|
if (method == null) {
|
||||||
|
method = initialized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return method;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import com.comphenix.protocol.injector.player.NetworkFieldInjector.FakePacket;
|
|||||||
|
|
||||||
import net.minecraft.server.Packet;
|
import net.minecraft.server.Packet;
|
||||||
import net.sf.cglib.proxy.Enhancer;
|
import net.sf.cglib.proxy.Enhancer;
|
||||||
import net.sf.cglib.proxy.Factory;
|
|
||||||
import net.sf.cglib.proxy.MethodInterceptor;
|
import net.sf.cglib.proxy.MethodInterceptor;
|
||||||
import net.sf.cglib.proxy.MethodProxy;
|
import net.sf.cglib.proxy.MethodProxy;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user