Make it possible to send and recieve packets during login.

This commit is contained in:
Kristian S. Stangeland 2013-01-31 22:52:33 +01:00
parent ea08696d10
commit b26c9c45c8
5 changed files with 68 additions and 9 deletions

View File

@ -175,7 +175,7 @@ class CommandPacket extends CommandBase {
try { try {
chatter.broadcastMessageSilently(message, permission); chatter.broadcastMessageSilently(message, permission);
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
reporter.reportDetailed(this, "Cannot send chat message.", e, message, message); reporter.reportDetailed(this, "Cannot send chat message.", e, message, permission);
} }
} }

View File

@ -22,6 +22,8 @@ import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Set; 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.ListenerInvoker;
import com.comphenix.protocol.injector.player.NetworkFieldInjector.FakePacket; import com.comphenix.protocol.injector.player.NetworkFieldInjector.FakePacket;
@ -64,7 +66,8 @@ class InjectedArrayList extends ArrayList<Object> {
if (packet instanceof FakePacket) { if (packet instanceof FakePacket) {
return true; return true;
} else if (ignoredPackets.contains(packet)) { } else if (ignoredPackets.contains(packet)) {
ignoredPackets.remove(packet); // Don't send it to the filters
result = ignoredPackets.remove(packet);
} else { } else {
result = injector.handlePacketSending(packet); result = injector.handlePacketSending(packet);
} }
@ -82,7 +85,18 @@ class InjectedArrayList extends ArrayList<Object> {
return true; return true;
} catch (InvocationTargetException e) { } 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;
} }
} }

View File

@ -150,12 +150,12 @@ public class NetworkServerInjector extends PlayerInjector {
@Override @Override
public void sendServerPacket(Object packet, boolean filtered) throws InvocationTargetException { 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 { try {
// Note that invocation target exception is a wrapper for a checked exception // Note that invocation target exception is a wrapper for a checked exception
sendPacketMethod.invoke(serverDeleage, packet); sendPacketMethod.invoke(serverDelegate, packet);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw e; throw e;

View File

@ -38,6 +38,8 @@ import com.comphenix.protocol.injector.GamePhase;
import com.comphenix.protocol.injector.ListenerInvoker; import com.comphenix.protocol.injector.ListenerInvoker;
import com.comphenix.protocol.injector.PlayerLoggedOutException; import com.comphenix.protocol.injector.PlayerLoggedOutException;
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks; 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.base.Predicate;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
@ -483,14 +485,15 @@ public class PlayerInjectionHandler {
PlayerInjector injector = getInjector(reciever); PlayerInjector injector = getInjector(reciever);
// Send the packet, or drop it completely // Send the packet, or drop it completely
if (injector != null) if (injector != null) {
injector.sendServerPacket(packet.getHandle(), filters); injector.sendServerPacket(packet.getHandle(), filters);
else } else {
throw new PlayerLoggedOutException(String.format( throw new PlayerLoggedOutException(String.format(
"Unable to send packet %s (%s): Player %s has logged out.", "Unable to send packet %s (%s): Player %s has logged out.",
packet.getID(), packet, reciever.getName() packet.getID(), packet, reciever.getName()
)); ));
} }
}
/** /**
* Process a packet as if it were sent by the given player. * Process a packet as if it were sent by the given player.
@ -519,7 +522,32 @@ public class PlayerInjectionHandler {
* @return The injector, or NULL if not found. * @return The injector, or NULL if not found.
*/ */
private PlayerInjector getInjector(Player player) { 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;
} }
/** /**

View File

@ -315,6 +315,15 @@ public class MinecraftReflection {
return getItemStackClass().isAssignableFrom(value.getClass()); 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. * Determine if the given object is a Minecraft player entity.
* @param obj - the given object. * @param obj - the given object.
@ -883,6 +892,14 @@ public class MinecraftReflection {
return getCraftBukkitClass("inventory.CraftItemStack"); 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. * Retrieve a CraftItemStack from a given ItemStack.
* @param bukkitItemStack - the Bukkit ItemStack to convert. * @param bukkitItemStack - the Bukkit ItemStack to convert.