Archiviert
13
0

Ensure that the new read packet feature is supported in Spigot.

Dieser Commit ist enthalten in:
Kristian S. Stangeland 2013-07-17 07:27:03 +02:00
Ursprung 6527c0a7f5
Commit 6554a34752
8 geänderte Dateien mit 134 neuen und 7 gelöschten Zeilen

Datei anzeigen

@ -216,10 +216,19 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
// Use the correct injection type // Use the correct injection type
if (builder.isNettyEnabled()) { if (builder.isNettyEnabled()) {
spigotInjector = new SpigotPacketInjector(classLoader, reporter, this, server); this.spigotInjector = new SpigotPacketInjector(classLoader, reporter, this, server);
this.playerInjection = spigotInjector.getPlayerHandler(); this.playerInjection = spigotInjector.getPlayerHandler();
this.packetInjector = spigotInjector.getPacketInjector(); this.packetInjector = spigotInjector.getPacketInjector();
// Set real injector, in case we need it
spigotInjector.setProxyPacketInjector(PacketInjectorBuilder.newBuilder().
invoker(this).
reporter(reporter).
classLoader(classLoader).
playerInjection(playerInjection).
buildInjector()
);
} else { } else {
// Initialize standard injection mangers // Initialize standard injection mangers
this.playerInjection = PlayerInjectorBuilder.newBuilder(). this.playerInjection = PlayerInjectorBuilder.newBuilder().
@ -231,7 +240,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
injectionFilter(isInjectionNecessary). injectionFilter(isInjectionNecessary).
version(builder.getMinecraftVersion()). version(builder.getMinecraftVersion()).
buildHandler(); buildHandler();
this.packetInjector = PacketInjectorBuilder.newBuilder(). this.packetInjector = PacketInjectorBuilder.newBuilder().
invoker(this). invoker(this).
reporter(reporter). reporter(reporter).
@ -376,6 +385,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
} }
// Update it // Update it
this.inputBufferedPackets = updated; this.inputBufferedPackets = updated;
this.packetInjector.inputBuffersChanged(updated.toSet());
} }
/** /**

Datei anzeigen

@ -41,6 +41,12 @@ public interface PacketInjector {
*/ */
public abstract boolean hasPacketHandler(int packetID); public abstract boolean hasPacketHandler(int packetID);
/**
* Invoked when input buffers have changed.
* @param set - the new set of packets that require the read buffer.
*/
public abstract void inputBuffersChanged(Set<Integer> set);
/** /**
* Retrieve every intercepted packet ID. * Retrieve every intercepted packet ID.
* @return Every intercepted packet ID. * @return Every intercepted packet ID.

Datei anzeigen

@ -164,7 +164,7 @@ class ProxyPacketInjector implements PacketInjector {
// Determine if the read packet method was found // Determine if the read packet method was found
private boolean readPacketIntercepted = false; private boolean readPacketIntercepted = false;
public ProxyPacketInjector(ClassLoader classLoader, ListenerInvoker manager, public ProxyPacketInjector(ClassLoader classLoader, ListenerInvoker manager,
PlayerInjectionHandler playerInjection, ErrorReporter reporter) throws FieldAccessException { PlayerInjectionHandler playerInjection, ErrorReporter reporter) throws FieldAccessException {
@ -206,6 +206,11 @@ class ProxyPacketInjector implements PacketInjector {
} }
} }
@Override
public void inputBuffersChanged(Set<Integer> set) {
// No need to do anything
}
@Override @Override
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public boolean addPacketHandler(int packetID) { public boolean addPacketHandler(int packetID) {
@ -321,6 +326,10 @@ class ProxyPacketInjector implements PacketInjector {
// Called from the ReadPacketModified monitor // Called from the ReadPacketModified monitor
public PacketEvent packetRecieved(PacketContainer packet, DataInputStream input, byte[] buffered) { public PacketEvent packetRecieved(PacketContainer packet, DataInputStream input, byte[] buffered) {
if (playerInjection.canRecievePackets()) {
return playerInjection.handlePacketRecieved(packet, input, buffered);
}
try { try {
Player client = playerInjection.getPlayerByConnection(input); Player client = playerInjection.getPlayerByConnection(input);

Datei anzeigen

@ -8,6 +8,7 @@ import org.bukkit.entity.Player;
import com.comphenix.protocol.events.NetworkMarker; import com.comphenix.protocol.events.NetworkMarker;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener; import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.injector.GamePhase; import com.comphenix.protocol.injector.GamePhase;
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks; import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
@ -159,6 +160,21 @@ public interface PlayerInjectionHandler {
*/ */
public abstract Set<Integer> getSendingFilters(); public abstract Set<Integer> getSendingFilters();
/**
* Whether or not this player injection handler can also recieve packets.
* @return TRUE if it can, FALSE otherwise.
*/
public abstract boolean canRecievePackets();
/**
* Invoked if this player injection handler can process recieved packets.
* @param packet - the recieved packet.
* @param input - the input stream.
* @param buffered - the buffered packet.
* @return The packet event.
*/
public abstract PacketEvent handlePacketRecieved(PacketContainer packet, DataInputStream input, byte[] buffered);
/** /**
* Close any lingering proxy injections. * Close any lingering proxy injections.
*/ */

Datei anzeigen

@ -41,6 +41,7 @@ import com.comphenix.protocol.error.ReportType;
import com.comphenix.protocol.events.NetworkMarker; import com.comphenix.protocol.events.NetworkMarker;
import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener; import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.injector.GamePhase; import com.comphenix.protocol.injector.GamePhase;
import com.comphenix.protocol.injector.ListenerInvoker; import com.comphenix.protocol.injector.ListenerInvoker;
@ -649,6 +650,16 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler {
return null; return null;
} }
@Override
public boolean canRecievePackets() {
return false;
}
@Override
public PacketEvent handlePacketRecieved(PacketContainer packet, DataInputStream input, byte[] buffered) {
throw new UnsupportedOperationException("Proxy injection cannot handle recieved packets.");
}
/** /**
* Determine if the given listeners are valid. * Determine if the given listeners are valid.
* @param listeners - listeners to check. * @param listeners - listeners to check.

Datei anzeigen

@ -4,10 +4,12 @@ import java.util.Set;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import com.comphenix.protocol.Packets;
import com.comphenix.protocol.concurrency.IntegerSet; import com.comphenix.protocol.concurrency.IntegerSet;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.injector.packet.PacketInjector; import com.comphenix.protocol.injector.packet.PacketInjector;
import com.google.common.collect.Sets;
/** /**
* Dummy packet injector that simply delegates to its parent Spigot packet injector or receiving filters. * Dummy packet injector that simply delegates to its parent Spigot packet injector or receiving filters.
@ -17,6 +19,8 @@ import com.comphenix.protocol.injector.packet.PacketInjector;
class DummyPacketInjector implements PacketInjector { class DummyPacketInjector implements PacketInjector {
private SpigotPacketInjector injector; private SpigotPacketInjector injector;
private IntegerSet reveivedFilters; private IntegerSet reveivedFilters;
private IntegerSet lastBufferedPackets = new IntegerSet(Packets.MAXIMUM_PACKET_ID + 1);
public DummyPacketInjector(SpigotPacketInjector injector, IntegerSet reveivedFilters) { public DummyPacketInjector(SpigotPacketInjector injector, IntegerSet reveivedFilters) {
this.injector = injector; this.injector = injector;
@ -27,6 +31,20 @@ class DummyPacketInjector implements PacketInjector {
public void undoCancel(Integer id, Object packet) { public void undoCancel(Integer id, Object packet) {
// Do nothing yet // Do nothing yet
} }
@Override
public void inputBuffersChanged(Set<Integer> set) {
Set<Integer> removed = Sets.difference(lastBufferedPackets.toSet(), set);
Set<Integer> added = Sets.difference(set, lastBufferedPackets.toSet());
// Update the proxy packet injector
for (int packet : removed) {
injector.getProxyPacketInjector().removePacketHandler(packet);
}
for (int packet : added) {
injector.getProxyPacketInjector().addPacketHandler(packet);
}
}
@Override @Override
public boolean addPacketHandler(int packetID) { public boolean addPacketHandler(int packetID) {
@ -52,7 +70,7 @@ class DummyPacketInjector implements PacketInjector {
@Override @Override
public PacketEvent packetRecieved(PacketContainer packet, Player client, byte[] buffered) { public PacketEvent packetRecieved(PacketContainer packet, Player client, byte[] buffered) {
return injector.packetReceived(packet, client); return injector.packetReceived(packet, client, buffered);
} }
@Override @Override

Datei anzeigen

@ -9,6 +9,7 @@ import org.bukkit.entity.Player;
import com.comphenix.protocol.concurrency.IntegerSet; import com.comphenix.protocol.concurrency.IntegerSet;
import com.comphenix.protocol.events.NetworkMarker; import com.comphenix.protocol.events.NetworkMarker;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener; import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.injector.GamePhase; import com.comphenix.protocol.injector.GamePhase;
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks; import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
@ -95,6 +96,20 @@ class DummyPlayerHandler implements PlayerInjectionHandler {
return PlayerInjectHooks.NETWORK_SERVER_OBJECT; return PlayerInjectHooks.NETWORK_SERVER_OBJECT;
} }
@Override
public boolean canRecievePackets() {
return true;
}
@Override
public PacketEvent handlePacketRecieved(PacketContainer packet, DataInputStream input, byte[] buffered) {
// Associate this buffered data
if (buffered != null) {
injector.saveBuffered(packet.getHandle(), buffered);
}
return null;
}
@Override @Override
public PlayerInjectHooks getPlayerHook() { public PlayerInjectHooks getPlayerHook() {
// Pretend that we do // Pretend that we do

Datei anzeigen

@ -4,6 +4,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collections; import java.util.Collections;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
@ -24,6 +25,7 @@ import com.comphenix.protocol.concurrency.IntegerSet;
import com.comphenix.protocol.error.DelegatedErrorReporter; import com.comphenix.protocol.error.DelegatedErrorReporter;
import com.comphenix.protocol.error.ErrorReporter; import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.error.Report; import com.comphenix.protocol.error.Report;
import com.comphenix.protocol.events.ConnectionSide;
import com.comphenix.protocol.events.NetworkMarker; import com.comphenix.protocol.events.NetworkMarker;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.events.PacketEvent;
@ -78,12 +80,18 @@ public class SpigotPacketInjector implements SpigotPacketListener {
// Player to injector // Player to injector
private ConcurrentMap<Player, NetworkObjectInjector> playerInjector = Maps.newConcurrentMap(); private ConcurrentMap<Player, NetworkObjectInjector> playerInjector = Maps.newConcurrentMap();
// For handling read buffered packet data
private Map<Object, byte[]> readBufferedPackets = new MapMaker().weakKeys().makeMap();
// Responsible for informing the PL packet listeners // Responsible for informing the PL packet listeners
private ListenerInvoker invoker; private ListenerInvoker invoker;
private ErrorReporter reporter; private ErrorReporter reporter;
private Server server; private Server server;
private ClassLoader classLoader; private ClassLoader classLoader;
// The proxy packet injector
private PacketInjector proxyPacketInjector;
/** /**
* Create a new spigot injector. * Create a new spigot injector.
*/ */
@ -96,6 +104,30 @@ public class SpigotPacketInjector implements SpigotPacketListener {
this.reveivedFilters = new IntegerSet(Packets.MAXIMUM_PACKET_ID + 1); this.reveivedFilters = new IntegerSet(Packets.MAXIMUM_PACKET_ID + 1);
} }
/**
* Retrieve the underlying listener invoker.
* @return The invoker.
*/
public ListenerInvoker getInvoker() {
return invoker;
}
/**
* Set the real proxy packet injector.
* @param proxyPacketInjector - the real injector.
*/
public void setProxyPacketInjector(PacketInjector proxyPacketInjector) {
this.proxyPacketInjector = proxyPacketInjector;
}
/**
* Retrieve the real proxy packet injector.
* @return The real injector.
*/
public PacketInjector getProxyPacketInjector() {
return proxyPacketInjector;
}
/** /**
* Retrieve the spigot packet listener class. * Retrieve the spigot packet listener class.
* @return The listener class. * @return The listener class.
@ -343,6 +375,15 @@ public class SpigotPacketInjector implements SpigotPacketListener {
return result; return result;
} }
/**
* Save the buffered serialized input packet.
* @param handle - the associated packet.
* @param buffered - the buffere data to save.
*/
public void saveBuffered(Object handle, byte[] buffered) {
readBufferedPackets.put(handle, buffered);
}
@Override @Override
public Object packetReceived(Object networkManager, Object connection, Object packet) { public Object packetReceived(Object networkManager, Object connection, Object packet) {
Integer id = invoker.getPacketID(packet); Integer id = invoker.getPacketID(packet);
@ -355,7 +396,7 @@ public class SpigotPacketInjector implements SpigotPacketListener {
Player sender = getInjector(networkManager, connection).getUpdatedPlayer(); Player sender = getInjector(networkManager, connection).getUpdatedPlayer();
PacketContainer container = new PacketContainer(id, packet); PacketContainer container = new PacketContainer(id, packet);
PacketEvent event = packetReceived(container, sender); PacketEvent event = packetReceived(container, sender, readBufferedPackets.get(packet));
if (!event.isCancelled()) if (!event.isCancelled())
return event.getPacket().getHandle(); return event.getPacket().getHandle();
@ -408,8 +449,9 @@ public class SpigotPacketInjector implements SpigotPacketListener {
* @param sender - the client packet. * @param sender - the client packet.
* @return The packet event that was used. * @return The packet event that was used.
*/ */
PacketEvent packetReceived(PacketContainer packet, Player sender) { PacketEvent packetReceived(PacketContainer packet, Player sender, byte[] buffered) {
PacketEvent event = PacketEvent.fromClient(this, packet, sender); NetworkMarker marker = buffered != null ? new NetworkMarker(ConnectionSide.CLIENT_SIDE, buffered) : null;
PacketEvent event = PacketEvent.fromClient(this, packet, marker, sender);
invoker.invokePacketRecieving(event); invoker.invokePacketRecieving(event);
return event; return event;