Added the ability to intercept serialized input packets on CraftBukkit.
Spigot will be added later.
Dieser Commit ist enthalten in:
Ursprung
8f30199a22
Commit
6527c0a7f5
@ -97,8 +97,11 @@ public class ListeningWhitelist {
|
|||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
this.whitelist = Sets.newHashSet(whitelist);
|
this.whitelist = Sets.newHashSet(whitelist);
|
||||||
this.gamePhase = gamePhase;
|
this.gamePhase = gamePhase;
|
||||||
|
|
||||||
|
if (options != null) {
|
||||||
this.options.addAll(Arrays.asList(options));
|
this.options.addAll(Arrays.asList(options));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not this whitelist has any enabled packets.
|
* Whether or not this whitelist has any enabled packets.
|
||||||
|
@ -130,4 +130,23 @@ public class NetworkMarker {
|
|||||||
public static boolean hasOutputHandlers(NetworkMarker marker) {
|
public static boolean hasOutputHandlers(NetworkMarker marker) {
|
||||||
return marker != null && !marker.getOutputHandlers().isEmpty();
|
return marker != null && !marker.getOutputHandlers().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the byte buffer stored in the given marker.
|
||||||
|
* @param marker - the marker.
|
||||||
|
* @return The byte buffer, or NULL if not found.
|
||||||
|
*/
|
||||||
|
public static byte[] getByteBuffer(NetworkMarker marker) {
|
||||||
|
if (marker != null) {
|
||||||
|
ByteBuffer buffer = marker.getInputBuffer();
|
||||||
|
|
||||||
|
if (buffer != null) {
|
||||||
|
byte[] data = new byte[buffer.remaining()];
|
||||||
|
|
||||||
|
buffer.get(data, 0, data.length);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ import com.comphenix.protocol.injector.GamePhase;
|
|||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public abstract class PacketAdapter implements PacketListener {
|
public abstract class PacketAdapter implements PacketListener {
|
||||||
|
|
||||||
protected Plugin plugin;
|
protected Plugin plugin;
|
||||||
protected ConnectionSide connectionSide;
|
protected ConnectionSide connectionSide;
|
||||||
protected ListeningWhitelist receivingWhitelist = ListeningWhitelist.EMPTY_WHITELIST;
|
protected ListeningWhitelist receivingWhitelist = ListeningWhitelist.EMPTY_WHITELIST;
|
||||||
@ -95,6 +94,17 @@ public abstract class PacketAdapter implements PacketListener {
|
|||||||
this(plugin, connectionSide, listenerPriority, GamePhase.PLAYING, packets);
|
this(plugin, connectionSide, listenerPriority, GamePhase.PLAYING, packets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a packet listener for a single connection side.
|
||||||
|
* @param plugin - the plugin that spawned this listener.
|
||||||
|
* @param connectionSide - the packet type the listener is looking for.
|
||||||
|
* @param options - which listener options to use.
|
||||||
|
* @param packets - the packet IDs the listener is looking for.
|
||||||
|
*/
|
||||||
|
public PacketAdapter(Plugin plugin, ConnectionSide connectionSide, ListenerOptions[] options, Integer... packets) {
|
||||||
|
this(plugin, connectionSide, ListenerPriority.NORMAL, GamePhase.PLAYING, options, packets);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize a packet listener for a single connection side.
|
* Initialize a packet listener for a single connection side.
|
||||||
* @param plugin - the plugin that spawned this listener.
|
* @param plugin - the plugin that spawned this listener.
|
||||||
@ -117,6 +127,23 @@ public abstract class PacketAdapter implements PacketListener {
|
|||||||
* @param packets - the packet IDs the listener is looking for.
|
* @param packets - the packet IDs the listener is looking for.
|
||||||
*/
|
*/
|
||||||
public PacketAdapter(Plugin plugin, ConnectionSide connectionSide, ListenerPriority listenerPriority, GamePhase gamePhase, Integer... packets) {
|
public PacketAdapter(Plugin plugin, ConnectionSide connectionSide, ListenerPriority listenerPriority, GamePhase gamePhase, Integer... packets) {
|
||||||
|
this(plugin, connectionSide, listenerPriority, gamePhase, new ListenerOptions[0], packets);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a packet listener for a single connection side.
|
||||||
|
* <p>
|
||||||
|
* The game phase is used to optmize performance. A listener should only choose BOTH or LOGIN if it's absolutely necessary.
|
||||||
|
* <p>
|
||||||
|
* Listener options must be specified in order for {@link NetworkMarker#getInputBuffer()} to function correctly.
|
||||||
|
* @param plugin - the plugin that spawned this listener.
|
||||||
|
* @param connectionSide - the packet type the listener is looking for.
|
||||||
|
* @param listenerPriority - the event priority.
|
||||||
|
* @param gamePhase - which game phase this listener is active under.
|
||||||
|
* @param options - which listener options to use.
|
||||||
|
* @param packets - the packet IDs the listener is looking for.
|
||||||
|
*/
|
||||||
|
public PacketAdapter(Plugin plugin, ConnectionSide connectionSide, ListenerPriority listenerPriority, GamePhase gamePhase, ListenerOptions[] options, Integer... packets) {
|
||||||
if (plugin == null)
|
if (plugin == null)
|
||||||
throw new IllegalArgumentException("plugin cannot be null");
|
throw new IllegalArgumentException("plugin cannot be null");
|
||||||
if (connectionSide == null)
|
if (connectionSide == null)
|
||||||
@ -127,12 +154,14 @@ public abstract class PacketAdapter implements PacketListener {
|
|||||||
throw new IllegalArgumentException("gamePhase cannot be NULL");
|
throw new IllegalArgumentException("gamePhase cannot be NULL");
|
||||||
if (packets == null)
|
if (packets == null)
|
||||||
throw new IllegalArgumentException("packets cannot be null");
|
throw new IllegalArgumentException("packets cannot be null");
|
||||||
|
if (options == null)
|
||||||
|
throw new IllegalArgumentException("options cannot be null");
|
||||||
|
|
||||||
// Add whitelists
|
// Add whitelists
|
||||||
if (connectionSide.isForServer())
|
if (connectionSide.isForServer())
|
||||||
sendingWhitelist = new ListeningWhitelist(listenerPriority, packets, gamePhase);
|
sendingWhitelist = new ListeningWhitelist(listenerPriority, packets, gamePhase, options);
|
||||||
if (connectionSide.isForClient())
|
if (connectionSide.isForClient())
|
||||||
receivingWhitelist = new ListeningWhitelist(listenerPriority, packets, gamePhase);
|
receivingWhitelist = new ListeningWhitelist(listenerPriority, packets, gamePhase, options);
|
||||||
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.connectionSide = connectionSide;
|
this.connectionSide = connectionSide;
|
||||||
@ -180,7 +209,6 @@ public abstract class PacketAdapter implements PacketListener {
|
|||||||
* @return Name of the given plugin.
|
* @return Name of the given plugin.
|
||||||
*/
|
*/
|
||||||
public static String getPluginName(Plugin plugin) {
|
public static String getPluginName(Plugin plugin) {
|
||||||
|
|
||||||
// Try to get the plugin name
|
// Try to get the plugin name
|
||||||
try {
|
try {
|
||||||
if (plugin == null)
|
if (plugin == null)
|
||||||
|
@ -52,6 +52,13 @@ public interface ListenerInvoker {
|
|||||||
*/
|
*/
|
||||||
public InterceptWritePacket getInterceptWritePacket();
|
public InterceptWritePacket getInterceptWritePacket();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a given packet requires input buffering.
|
||||||
|
* @param packetId - the packet to check.
|
||||||
|
* @return TRUE if it does, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public boolean requireInputBuffer(int packetId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Associate a given class with the given packet ID. Internal method.
|
* Associate a given class with the given packet ID. Internal method.
|
||||||
* @param clazz - class to associate.
|
* @param clazz - class to associate.
|
||||||
|
@ -46,9 +46,11 @@ import org.bukkit.plugin.Plugin;
|
|||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
|
||||||
import com.comphenix.protocol.AsynchronousManager;
|
import com.comphenix.protocol.AsynchronousManager;
|
||||||
|
import com.comphenix.protocol.Packets;
|
||||||
import com.comphenix.protocol.ProtocolManager;
|
import com.comphenix.protocol.ProtocolManager;
|
||||||
import com.comphenix.protocol.async.AsyncFilterManager;
|
import com.comphenix.protocol.async.AsyncFilterManager;
|
||||||
import com.comphenix.protocol.async.AsyncMarker;
|
import com.comphenix.protocol.async.AsyncMarker;
|
||||||
|
import com.comphenix.protocol.concurrency.IntegerSet;
|
||||||
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.error.ReportType;
|
import com.comphenix.protocol.error.ReportType;
|
||||||
@ -138,6 +140,9 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
|||||||
// Intercepting write packet methods
|
// Intercepting write packet methods
|
||||||
private InterceptWritePacket interceptWritePacket;
|
private InterceptWritePacket interceptWritePacket;
|
||||||
|
|
||||||
|
// Whether or not a packet must be input buffered
|
||||||
|
private volatile IntegerSet inputBufferedPackets = new IntegerSet(Packets.MAXIMUM_PACKET_ID + 1);
|
||||||
|
|
||||||
// The two listener containers
|
// The two listener containers
|
||||||
private SortedPacketListenerList recievedListeners;
|
private SortedPacketListenerList recievedListeners;
|
||||||
private SortedPacketListenerList sendingListeners;
|
private SortedPacketListenerList sendingListeners;
|
||||||
@ -323,6 +328,11 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
|||||||
if (hasSending || hasReceiving) {
|
if (hasSending || hasReceiving) {
|
||||||
// Add listeners and hooks
|
// Add listeners and hooks
|
||||||
if (hasSending) {
|
if (hasSending) {
|
||||||
|
// This doesn't make any sense
|
||||||
|
if (sending.getOptions().contains(ListenerOptions.INTERCEPT_INPUT_BUFFER)) {
|
||||||
|
throw new IllegalArgumentException("Sending whitelist cannot require input bufferes to be intercepted.");
|
||||||
|
}
|
||||||
|
|
||||||
verifyWhitelist(listener, sending);
|
verifyWhitelist(listener, sending);
|
||||||
sendingListeners.addListener(listener, sending);
|
sendingListeners.addListener(listener, sending);
|
||||||
enablePacketFilters(listener, ConnectionSide.SERVER_SIDE, sending.getWhitelist());
|
enablePacketFilters(listener, ConnectionSide.SERVER_SIDE, sending.getWhitelist());
|
||||||
@ -344,9 +354,30 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
|||||||
|
|
||||||
// Inform our injected hooks
|
// Inform our injected hooks
|
||||||
packetListeners.add(listener);
|
packetListeners.add(listener);
|
||||||
|
updateRequireInputBuffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked when we need to update the input buffer set.
|
||||||
|
*/
|
||||||
|
private void updateRequireInputBuffers() {
|
||||||
|
IntegerSet updated = new IntegerSet(Packets.MAXIMUM_PACKET_ID + 1);
|
||||||
|
|
||||||
|
for (PacketListener listener : packetListeners) {
|
||||||
|
ListeningWhitelist whitelist = listener.getReceivingWhitelist();
|
||||||
|
|
||||||
|
// We only check the recieving whitelist
|
||||||
|
if (whitelist.getOptions().contains(ListenerOptions.INTERCEPT_INPUT_BUFFER)) {
|
||||||
|
for (int id : whitelist.getWhitelist()) {
|
||||||
|
updated.add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update it
|
||||||
|
this.inputBufferedPackets = updated;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked to handle the different game phases of a added listener.
|
* Invoked to handle the different game phases of a added listener.
|
||||||
* @param phase - listener's game game phase.
|
* @param phase - listener's game game phase.
|
||||||
@ -437,6 +468,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
|||||||
disablePacketFilters(ConnectionSide.SERVER_SIDE, sendingRemoved);
|
disablePacketFilters(ConnectionSide.SERVER_SIDE, sendingRemoved);
|
||||||
if (receivingRemoved != null && receivingRemoved.size() > 0)
|
if (receivingRemoved != null && receivingRemoved.size() > 0)
|
||||||
disablePacketFilters(ConnectionSide.CLIENT_SIDE, receivingRemoved);
|
disablePacketFilters(ConnectionSide.CLIENT_SIDE, receivingRemoved);
|
||||||
|
updateRequireInputBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -468,6 +500,11 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requireInputBuffer(int packetId) {
|
||||||
|
return inputBufferedPackets.contains(packetId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a packet sending or receiving event.
|
* Handle a packet sending or receiving event.
|
||||||
* <p>
|
* <p>
|
||||||
@ -617,7 +654,8 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
|||||||
packetInjector.undoCancel(packet.getID(), mcPacket);
|
packetInjector.undoCancel(packet.getID(), mcPacket);
|
||||||
|
|
||||||
if (filters) {
|
if (filters) {
|
||||||
PacketEvent event = packetInjector.packetRecieved(packet, sender);
|
byte[] data = NetworkMarker.getByteBuffer(marker);
|
||||||
|
PacketEvent event = packetInjector.packetRecieved(packet, sender, data);
|
||||||
|
|
||||||
if (!event.isCancelled())
|
if (!event.isCancelled())
|
||||||
mcPacket = event.getPacket().getHandle();
|
mcPacket = event.getPacket().getHandle();
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.comphenix.protocol.injector.packet;
|
||||||
|
|
||||||
|
import java.io.FilterInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an input stream that stores every read block of bytes in another output stream.
|
||||||
|
*
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
class CaptureInputStream extends FilterInputStream {
|
||||||
|
protected OutputStream out;
|
||||||
|
|
||||||
|
public CaptureInputStream(InputStream in, OutputStream out) {
|
||||||
|
super(in);
|
||||||
|
this.out = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
int value = super.read();
|
||||||
|
|
||||||
|
// Write the byte
|
||||||
|
if (value >= 0)
|
||||||
|
out.write(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
super.close();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b) throws IOException {
|
||||||
|
int count = super.read(b);
|
||||||
|
|
||||||
|
if (count > 0 ) {
|
||||||
|
out.write(b, 0, count);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
|
int count = super.read(b, off, len);
|
||||||
|
|
||||||
|
if (count > 0 ) {
|
||||||
|
out.write(b, off, count);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the output stream that recieves all the read information.
|
||||||
|
* @return The output stream everything is copied to.
|
||||||
|
*/
|
||||||
|
public OutputStream getOutputStream() {
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
@ -51,9 +51,10 @@ public interface PacketInjector {
|
|||||||
* Let the packet listeners process the given packet.
|
* Let the packet listeners process the given packet.
|
||||||
* @param packet - a packet to process.
|
* @param packet - a packet to process.
|
||||||
* @param client - the client that sent the packet.
|
* @param client - the client that sent the packet.
|
||||||
|
* @param buffered - a buffer containing the data that had to be read in order to construct the packet.
|
||||||
* @return The resulting packet event.
|
* @return The resulting packet event.
|
||||||
*/
|
*/
|
||||||
public abstract PacketEvent packetRecieved(PacketContainer packet, Player client);
|
public abstract PacketEvent packetRecieved(PacketContainer packet, Player client, byte[] buffered);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform any necessary cleanup before unloading ProtocolLib.
|
* Perform any necessary cleanup before unloading ProtocolLib.
|
||||||
|
@ -36,6 +36,8 @@ import com.comphenix.protocol.Packets;
|
|||||||
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.error.ReportType;
|
import com.comphenix.protocol.error.ReportType;
|
||||||
|
import com.comphenix.protocol.events.ConnectionSide;
|
||||||
|
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;
|
||||||
import com.comphenix.protocol.injector.ListenerInvoker;
|
import com.comphenix.protocol.injector.ListenerInvoker;
|
||||||
@ -298,6 +300,15 @@ class ProxyPacketInjector implements PacketInjector {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the data a packet read must be buffered.
|
||||||
|
* @param packetId - the packet to check.
|
||||||
|
* @return TRUE if it does, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public boolean requireInputBuffers(int packetId) {
|
||||||
|
return manager.requireInputBuffer(packetId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPacketHandler(int packetID) {
|
public boolean hasPacketHandler(int packetID) {
|
||||||
return PacketRegistry.getPreviousPackets().containsKey(packetID);
|
return PacketRegistry.getPreviousPackets().containsKey(packetID);
|
||||||
@ -309,13 +320,13 @@ class ProxyPacketInjector implements PacketInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Called from the ReadPacketModified monitor
|
// Called from the ReadPacketModified monitor
|
||||||
public PacketEvent packetRecieved(PacketContainer packet, DataInputStream input) {
|
public PacketEvent packetRecieved(PacketContainer packet, DataInputStream input, byte[] buffered) {
|
||||||
try {
|
try {
|
||||||
Player client = playerInjection.getPlayerByConnection(input);
|
Player client = playerInjection.getPlayerByConnection(input);
|
||||||
|
|
||||||
// Never invoke a event if we don't know where it's from
|
// Never invoke a event if we don't know where it's from
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
return packetRecieved(packet, client);
|
return packetRecieved(packet, client, buffered);
|
||||||
} else {
|
} else {
|
||||||
// Hack #2 - Caused by our server socket injector
|
// Hack #2 - Caused by our server socket injector
|
||||||
if (packet.getID() != Packets.Client.GET_INFO)
|
if (packet.getID() != Packets.Client.GET_INFO)
|
||||||
@ -330,15 +341,10 @@ class ProxyPacketInjector implements PacketInjector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Let the packet listeners process the given packet.
|
|
||||||
* @param packet - a packet to process.
|
|
||||||
* @param client - the client that sent the packet.
|
|
||||||
* @return The resulting packet event.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public PacketEvent packetRecieved(PacketContainer packet, Player client) {
|
public PacketEvent packetRecieved(PacketContainer packet, Player client, byte[] buffered) {
|
||||||
PacketEvent event = PacketEvent.fromClient((Object) manager, packet, client);
|
NetworkMarker marker = buffered != null ? new NetworkMarker(ConnectionSide.CLIENT_SIDE, buffered) : null;
|
||||||
|
PacketEvent event = PacketEvent.fromClient((Object) manager, packet, marker, client);
|
||||||
|
|
||||||
manager.invokePacketRecieving(event);
|
manager.invokePacketRecieving(event);
|
||||||
return event;
|
return event;
|
||||||
|
@ -17,7 +17,9 @@
|
|||||||
|
|
||||||
package com.comphenix.protocol.injector.packet;
|
package com.comphenix.protocol.injector.packet;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -89,6 +91,18 @@ class ReadPacketModifier implements MethodInterceptor {
|
|||||||
Object overridenObject = override.get(thisObj);
|
Object overridenObject = override.get(thisObj);
|
||||||
Object returnValue = null;
|
Object returnValue = null;
|
||||||
|
|
||||||
|
ByteArrayOutputStream bufferStream = null;
|
||||||
|
|
||||||
|
// See if we need to buffer the read data
|
||||||
|
if (isReadPacketDataMethod && packetInjector.requireInputBuffers(packetID)) {
|
||||||
|
CaptureInputStream captured = new CaptureInputStream(
|
||||||
|
(InputStream) args[0],
|
||||||
|
bufferStream = new ByteArrayOutputStream());
|
||||||
|
|
||||||
|
// Stash it back
|
||||||
|
args[0] = new DataInputStream(captured);
|
||||||
|
}
|
||||||
|
|
||||||
if (overridenObject != null) {
|
if (overridenObject != null) {
|
||||||
// This packet has been cancelled
|
// This packet has been cancelled
|
||||||
if (overridenObject == CANCEL_MARKER) {
|
if (overridenObject == CANCEL_MARKER) {
|
||||||
@ -109,10 +123,11 @@ class ReadPacketModifier implements MethodInterceptor {
|
|||||||
try {
|
try {
|
||||||
// We need this in order to get the correct player
|
// We need this in order to get the correct player
|
||||||
DataInputStream input = (DataInputStream) args[0];
|
DataInputStream input = (DataInputStream) args[0];
|
||||||
|
byte[] buffer = bufferStream != null ? bufferStream.toByteArray() : null;
|
||||||
|
|
||||||
// Let the people know
|
// Let the people know
|
||||||
PacketContainer container = new PacketContainer(packetID, thisObj);
|
PacketContainer container = new PacketContainer(packetID, thisObj);
|
||||||
PacketEvent event = packetInjector.packetRecieved(container, input);
|
PacketEvent event = packetInjector.packetRecieved(container, input, buffer);
|
||||||
|
|
||||||
// Handle override
|
// Handle override
|
||||||
if (event != null) {
|
if (event != null) {
|
||||||
|
@ -51,7 +51,7 @@ class DummyPacketInjector implements PacketInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PacketEvent packetRecieved(PacketContainer packet, Player client) {
|
public PacketEvent packetRecieved(PacketContainer packet, Player client, byte[] buffered) {
|
||||||
return injector.packetReceived(packet, client);
|
return injector.packetReceived(packet, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren