Archiviert
13
0

Asynchronous client packets are handled twice. FIXES 118

This causes wierd artifacts such as double placing of half-slabs and so
on, as Minecraft will process the packets again (except chat packets). 
We correct this by uncancelling the asynchronous packet, and then 
cancelling it again.
Dieser Commit ist enthalten in:
Kristian S. Stangeland 2013-08-15 01:04:56 +02:00
Ursprung ccc123b26f
Commit 3923e05178
6 geänderte Dateien mit 53 neuen und 19 gelöschten Zeilen

Datei anzeigen

@ -669,9 +669,12 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
incrementPhases(GamePhase.PLAYING); incrementPhases(GamePhase.PLAYING);
Object mcPacket = packet.getHandle(); Object mcPacket = packet.getHandle();
boolean cancelled = packetInjector.isCancelled(mcPacket);
// Make sure the packet isn't cancelled // Make sure the packet isn't cancelled
packetInjector.undoCancel(packet.getID(), mcPacket); if (cancelled) {
packetInjector.setCancelled(mcPacket, false);
}
if (filters) { if (filters) {
byte[] data = NetworkMarker.getByteBuffer(marker); byte[] data = NetworkMarker.getByteBuffer(marker);
@ -691,6 +694,11 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
} }
playerInjection.recieveClientPacket(sender, mcPacket); playerInjection.recieveClientPacket(sender, mcPacket);
// Let it stay cancelled
if (cancelled) {
packetInjector.setCancelled(mcPacket, true);
}
} }
@Override @Override

Datei anzeigen

@ -14,12 +14,19 @@ import com.comphenix.protocol.events.PacketEvent;
*/ */
public interface PacketInjector { public interface PacketInjector {
/** /**
* Undo a packet cancel. * Determine if a packet is cancelled or not.
* @param id - the id of the packet. * @param packet - the packet to check.
* @param packet - packet to uncancel. * @return TRUE if it is, FALSE otherwise.
*/ */
public abstract void undoCancel(Integer id, Object packet); public abstract boolean isCancelled(Object packet);
/**
* Set whether or not a packet is cancelled.
* @param packet - the packet to set.
* @param cancelled - TRUE to cancel the packet, FALSE otherwise.
*/
public abstract void setCancelled(Object packet, boolean cancelled);
/** /**
* Start intercepting packets with the given packet ID. * Start intercepting packets with the given packet ID.
* @param packetID - the ID of the packets to start intercepting. * @param packetID - the ID of the packets to start intercepting.

Datei anzeigen

@ -176,15 +176,16 @@ class ProxyPacketInjector implements PacketInjector {
initialize(); initialize();
} }
/**
* Undo a packet cancel.
* @param id - the id of the packet.
* @param packet - packet to uncancel.
*/
@Override @Override
public void undoCancel(Integer id, Object packet) { public boolean isCancelled(Object packet) {
// See if this packet has been cancelled before return ReadPacketModifier.isCancelled(packet);
if (ReadPacketModifier.hasCancelled(packet)) { }
@Override
public void setCancelled(Object packet, boolean cancelled) {
if (cancelled) {
ReadPacketModifier.setOverride(packet, null);
} else {
ReadPacketModifier.removeOverride(packet); ReadPacketModifier.removeOverride(packet);
} }
} }

Datei anzeigen

@ -74,16 +74,27 @@ class ReadPacketModifier implements MethodInterceptor {
public static Object getOverride(Object packet) { public static Object getOverride(Object packet) {
return override.get(packet); return override.get(packet);
} }
/**
* Set the packet instance to delegate to instead, or mark the packet as cancelled.
* <p>
* To undo a override, use {@link #removeOverride(Object)}.
* @param packet - the packet.
* @param override - the override method. NULL to cancel this packet.
*/
public static void setOverride(Object packet, Object overridePacket) {
override.put(packet, overridePacket != null ? overridePacket : CANCEL_MARKER);
}
/** /**
* Determine if the given packet has been cancelled before. * Determine if the given packet has been cancelled before.
* @param packet - the packet to check. * @param packet - the packet to check.
* @return TRUE if it has been cancelled, FALSE otherwise. * @return TRUE if it has been cancelled, FALSE otherwise.
*/ */
public static boolean hasCancelled(Object packet) { public static boolean isCancelled(Object packet) {
return getOverride(packet) == CANCEL_MARKER; return getOverride(packet) == CANCEL_MARKER;
} }
@Override @Override
public Object intercept(Object thisObj, Method method, Object[] args, MethodProxy proxy) throws Throwable { public Object intercept(Object thisObj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// Atomic retrieval // Atomic retrieval
@ -105,7 +116,7 @@ class ReadPacketModifier implements MethodInterceptor {
if (overridenObject != null) { if (overridenObject != null) {
// This packet has been cancelled // This packet has been cancelled
if (overridenObject == CANCEL_MARKER) { 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;

Datei anzeigen

@ -28,8 +28,14 @@ class DummyPacketInjector implements PacketInjector {
} }
@Override @Override
public void undoCancel(Integer id, Object packet) { public boolean isCancelled(Object packet) {
// Do nothing yet // No, it's never cancelled
return false;
}
@Override
public void setCancelled(Object packet, boolean cancelled) {
throw new UnsupportedOperationException();
} }
@Override @Override

Datei anzeigen

@ -38,6 +38,7 @@ import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.MethodInfo; import com.comphenix.protocol.reflect.MethodInfo;
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
import com.google.common.collect.MapMaker; import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;