From b26c9c45c8749b17e911d5825405b8bc8141104b Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Thu, 31 Jan 2013 22:52:33 +0100 Subject: [PATCH] Make it possible to send and recieve packets during login. --- .../com/comphenix/protocol/CommandPacket.java | 2 +- .../injector/player/InjectedArrayList.java | 18 ++++++++-- .../player/NetworkServerInjector.java | 6 ++-- .../player/PlayerInjectionHandler.java | 34 +++++++++++++++++-- .../protocol/utility/MinecraftReflection.java | 17 ++++++++++ 5 files changed, 68 insertions(+), 9 deletions(-) diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/CommandPacket.java b/ProtocolLib/src/main/java/com/comphenix/protocol/CommandPacket.java index 6c687412..6f098599 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/CommandPacket.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/CommandPacket.java @@ -175,7 +175,7 @@ class CommandPacket extends CommandBase { try { chatter.broadcastMessageSilently(message, permission); } catch (InvocationTargetException e) { - reporter.reportDetailed(this, "Cannot send chat message.", e, message, message); + reporter.reportDetailed(this, "Cannot send chat message.", e, message, permission); } } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/InjectedArrayList.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/InjectedArrayList.java index 60f570b5..57bf8e37 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/InjectedArrayList.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/InjectedArrayList.java @@ -22,6 +22,8 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Set; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.error.ErrorReporter; import com.comphenix.protocol.injector.ListenerInvoker; import com.comphenix.protocol.injector.player.NetworkFieldInjector.FakePacket; @@ -64,7 +66,8 @@ class InjectedArrayList extends ArrayList { if (packet instanceof FakePacket) { return true; } else if (ignoredPackets.contains(packet)) { - ignoredPackets.remove(packet); + // Don't send it to the filters + result = ignoredPackets.remove(packet); } else { result = injector.handlePacketSending(packet); } @@ -82,7 +85,18 @@ class InjectedArrayList extends ArrayList { return true; } catch (InvocationTargetException e) { - throw new RuntimeException("Reverting cancelled packet failed.", e.getTargetException()); + ErrorReporter reporter = ProtocolLibrary.getErrorReporter(); + + // Prefer to report this to the user, instead of risking sending it to Minecraft + if (reporter != null) { + reporter.reportDetailed(this, "Reverting cancelled packet failed.", e, packet); + } else { + System.out.println("[ProtocolLib] Reverting cancelled packet failed."); + e.printStackTrace(); + } + + // Failure + return false; } } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java index d6c6e592..7261547b 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java @@ -150,12 +150,12 @@ public class NetworkServerInjector extends PlayerInjector { @Override public void sendServerPacket(Object packet, boolean filtered) throws InvocationTargetException { - Object serverDeleage = filtered ? serverHandlerRef.getValue() : serverHandlerRef.getOldValue(); + Object serverDelegate = filtered ? serverHandlerRef.getValue() : serverHandlerRef.getOldValue(); - if (serverDeleage != null) { + if (serverDelegate != null) { try { // Note that invocation target exception is a wrapper for a checked exception - sendPacketMethod.invoke(serverDeleage, packet); + sendPacketMethod.invoke(serverDelegate, packet); } catch (IllegalArgumentException e) { throw e; diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java index a59e5772..85420784 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java @@ -38,6 +38,8 @@ import com.comphenix.protocol.injector.GamePhase; import com.comphenix.protocol.injector.ListenerInvoker; import com.comphenix.protocol.injector.PlayerLoggedOutException; import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks; +import com.comphenix.protocol.injector.player.TemporaryPlayerFactory.InjectContainer; +import com.comphenix.protocol.utility.MinecraftReflection; import com.google.common.base.Predicate; import com.google.common.collect.Maps; @@ -483,13 +485,14 @@ public class PlayerInjectionHandler { PlayerInjector injector = getInjector(reciever); // Send the packet, or drop it completely - if (injector != null) + if (injector != null) { injector.sendServerPacket(packet.getHandle(), filters); - else + } else { throw new PlayerLoggedOutException(String.format( "Unable to send packet %s (%s): Player %s has logged out.", packet.getID(), packet, reciever.getName() )); + } } /** @@ -519,7 +522,32 @@ public class PlayerInjectionHandler { * @return The injector, or NULL if not found. */ private PlayerInjector getInjector(Player player) { - return playerInjection.get(player); + PlayerInjector injector = playerInjection.get(player); + + if (injector == null) { + // Try getting it from the player itself + if (player instanceof InjectContainer) + return ((InjectContainer) player).getInjector(); + else + return searchAddressLookup(player); + } else { + return injector; + } + } + + /** + * Find an injector by looking through the address map. + * @param player - player to find. + * @return The injector, or NULL if not found. + */ + private PlayerInjector searchAddressLookup(Player player) { + // See if we can find it anywhere + for (PlayerInjector injector : addressLookup.values()) { + if (player.equals(injector.getUpdatedPlayer())) { + return injector; + } + } + return null; } /** diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java index 03966736..709d7e9c 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java @@ -315,6 +315,15 @@ public class MinecraftReflection { return getItemStackClass().isAssignableFrom(value.getClass()); } + /** + * Determine if the given object is a CraftPlayer class. + * @param value - the given object. + * @return TRUE if it is, FALSE otherwise. + */ + public static boolean isCraftPlayer(Object value) { + return getCraftPlayerClass().isAssignableFrom(value.getClass()); + } + /** * Determine if the given object is a Minecraft player entity. * @param obj - the given object. @@ -882,6 +891,14 @@ public class MinecraftReflection { public static Class getCraftItemStackClass() { return getCraftBukkitClass("inventory.CraftItemStack"); } + + /** + * Retrieve the CraftPlayer class. + * @return CraftPlayer class. + */ + public static Class getCraftPlayerClass() { + return getCraftBukkitClass("entity.CraftPlayer"); + } /** * Retrieve a CraftItemStack from a given ItemStack.