From 3f1b5d49e928948d1778d8d73c6b8b871d6719ee Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Tue, 2 Oct 2012 23:05:31 +0200 Subject: [PATCH] Ignore offline players when sending overdue packets. --- .../protocol/async/PacketSendingQueue.java | 11 +++++- .../injector/InjectedServerConnection.java | 1 + .../injector/NetworkServerInjector.java | 1 + .../injector/PacketFilterManager.java | 15 +++++++- .../injector/PlayerLoggedOutException.java | 36 +++++++++++++++++++ .../{injector => reflect}/ObjectCloner.java | 6 ++-- 6 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 ProtocolLib/src/com/comphenix/protocol/injector/PlayerLoggedOutException.java rename ProtocolLib/src/com/comphenix/protocol/{injector => reflect}/ObjectCloner.java (88%) diff --git a/ProtocolLib/src/com/comphenix/protocol/async/PacketSendingQueue.java b/ProtocolLib/src/com/comphenix/protocol/async/PacketSendingQueue.java index 027c0931..0899ed58 100644 --- a/ProtocolLib/src/com/comphenix/protocol/async/PacketSendingQueue.java +++ b/ProtocolLib/src/com/comphenix/protocol/async/PacketSendingQueue.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Set; import java.util.concurrent.PriorityBlockingQueue; +import org.bukkit.entity.Player; + import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.reflect.FieldAccessException; @@ -112,7 +114,10 @@ class PacketSendingQueue { if (marker.isProcessed() || marker.hasExpired()) { if (marker.isProcessed() && !current.isCancelled()) { - sendPacket(current); + // Silently skip players that have logged out + if (isOnline(current.getPlayer())) { + sendPacket(current); + } } sendingQueue.poll(); @@ -125,6 +130,10 @@ class PacketSendingQueue { } } + private boolean isOnline(Player player) { + return player != null && player.isOnline(); + } + /** * Send every packet, regardless of the processing state. */ diff --git a/ProtocolLib/src/com/comphenix/protocol/injector/InjectedServerConnection.java b/ProtocolLib/src/com/comphenix/protocol/injector/InjectedServerConnection.java index 2b92a150..ea987263 100644 --- a/ProtocolLib/src/com/comphenix/protocol/injector/InjectedServerConnection.java +++ b/ProtocolLib/src/com/comphenix/protocol/injector/InjectedServerConnection.java @@ -13,6 +13,7 @@ import org.bukkit.Server; import com.comphenix.protocol.reflect.FieldUtils; import com.comphenix.protocol.reflect.FuzzyReflection; +import com.comphenix.protocol.reflect.ObjectCloner; import com.comphenix.protocol.reflect.VolatileField; /** diff --git a/ProtocolLib/src/com/comphenix/protocol/injector/NetworkServerInjector.java b/ProtocolLib/src/com/comphenix/protocol/injector/NetworkServerInjector.java index 8325d659..3c053311 100644 --- a/ProtocolLib/src/com/comphenix/protocol/injector/NetworkServerInjector.java +++ b/ProtocolLib/src/com/comphenix/protocol/injector/NetworkServerInjector.java @@ -18,6 +18,7 @@ import org.bukkit.entity.Player; import com.comphenix.protocol.events.PacketListener; import com.comphenix.protocol.reflect.FieldUtils; import com.comphenix.protocol.reflect.FuzzyReflection; +import com.comphenix.protocol.reflect.ObjectCloner; import com.comphenix.protocol.reflect.instances.CollectionGenerator; import com.comphenix.protocol.reflect.instances.DefaultInstances; import com.comphenix.protocol.reflect.instances.ExistingGenerator; diff --git a/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java b/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java index aac0b9ad..3a3f6ea7 100644 --- a/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java +++ b/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java @@ -403,6 +403,8 @@ public final class PacketFilterManager implements ProtocolManager { if (packet == null) throw new IllegalArgumentException("packet cannot be NULL."); + sender.is + PlayerInjector injector = getInjector(sender); Packet mcPacket = packet.getHandle(); @@ -503,10 +505,21 @@ public final class PacketFilterManager implements ProtocolManager { try { injector = getHookInstance(player, currentHook); injector.injectManager(); + + DataInputStream inputStream = injector.getInputStream(false); + + if (!player.isOnline() || inputStream == null) { + throw new PlayerLoggedOutException(); + } + playerInjection.put(player, injector); - connectionLookup.put(injector.getInputStream(false), player); + connectionLookup.put(inputStream, player); break; + + } catch (PlayerLoggedOutException e) { + throw e; + } catch (Exception e) { // Mark this injection attempt as a failure diff --git a/ProtocolLib/src/com/comphenix/protocol/injector/PlayerLoggedOutException.java b/ProtocolLib/src/com/comphenix/protocol/injector/PlayerLoggedOutException.java new file mode 100644 index 00000000..9d2f0c2b --- /dev/null +++ b/ProtocolLib/src/com/comphenix/protocol/injector/PlayerLoggedOutException.java @@ -0,0 +1,36 @@ +package com.comphenix.protocol.injector; + +/** + * Invoked when attempting to use a player that has already logged out. + * + * @author Kristian + */ +public class PlayerLoggedOutException extends RuntimeException { + + public PlayerLoggedOutException() { + // Default error message + super("Cannot inject a player that has already logged out."); + } + + public PlayerLoggedOutException(String message, Throwable cause) { + super(message, cause); + } + + public PlayerLoggedOutException(String message) { + super(message); + } + + public PlayerLoggedOutException(Throwable cause) { + super(cause); + } + + /** + * Construct an exception from a formatted message. + * @param message - the message to format. + * @param params - parameters. + * @return The formated exception + */ + public static PlayerLoggedOutException fromFormat(String message, Object... params) { + return new PlayerLoggedOutException(String.format(message, params)); + } +} diff --git a/ProtocolLib/src/com/comphenix/protocol/injector/ObjectCloner.java b/ProtocolLib/src/com/comphenix/protocol/reflect/ObjectCloner.java similarity index 88% rename from ProtocolLib/src/com/comphenix/protocol/injector/ObjectCloner.java rename to ProtocolLib/src/com/comphenix/protocol/reflect/ObjectCloner.java index c3cec1a3..65902cbd 100644 --- a/ProtocolLib/src/com/comphenix/protocol/injector/ObjectCloner.java +++ b/ProtocolLib/src/com/comphenix/protocol/reflect/ObjectCloner.java @@ -1,17 +1,15 @@ -package com.comphenix.protocol.injector; +package com.comphenix.protocol.reflect; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import com.comphenix.protocol.reflect.FieldAccessException; -import com.comphenix.protocol.reflect.StructureModifier; /** * Can copy an object field by field. * * @author Kristian */ -class ObjectCloner { +public class ObjectCloner { // Cache structure modifiers @SuppressWarnings("rawtypes")