mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-28 13:45:22 +01:00
Attempting to add backwards compatibility for NetworkMarker.
This commit is contained in:
parent
92c8f21d5e
commit
6159507bb4
@ -2,6 +2,7 @@ package com.comphenix.protocol.events;
|
|||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -10,6 +11,9 @@ import java.util.PriorityQueue;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.utility.ByteBufferInputStream;
|
||||||
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||||
import com.comphenix.protocol.utility.StreamSerializer;
|
import com.comphenix.protocol.utility.StreamSerializer;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
@ -20,13 +24,35 @@ import com.google.common.primitives.Ints;
|
|||||||
*
|
*
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class NetworkMarker {
|
public abstract class NetworkMarker {
|
||||||
|
public static class EmptyBufferMarker extends NetworkMarker {
|
||||||
|
public EmptyBufferMarker(@Nonnull ConnectionSide side) {
|
||||||
|
super(side, (ByteBuffer)null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataInputStream skipHeader(DataInputStream input) throws IOException {
|
||||||
|
throw new IllegalStateException("Buffer is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ByteBuffer addHeader(ByteBuffer buffer, PacketType type) {
|
||||||
|
throw new IllegalStateException("Buffer is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataInputStream addHeader(DataInputStream input, PacketType type) {
|
||||||
|
throw new IllegalStateException("Buffer is empty.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Custom network handler
|
// Custom network handler
|
||||||
private PriorityQueue<PacketOutputHandler> outputHandlers;
|
private PriorityQueue<PacketOutputHandler> outputHandlers;
|
||||||
|
|
||||||
// The input buffer
|
// The input buffer
|
||||||
private ByteBuffer inputBuffer;
|
private ByteBuffer inputBuffer;
|
||||||
|
|
||||||
private final ConnectionSide side;
|
private final ConnectionSide side;
|
||||||
|
private final PacketType type;
|
||||||
|
|
||||||
// Cache serializer too
|
// Cache serializer too
|
||||||
private StreamSerializer serializer;
|
private StreamSerializer serializer;
|
||||||
@ -36,9 +62,10 @@ public class NetworkMarker {
|
|||||||
* @param side - whether or not this marker belongs to a client or server packet.
|
* @param side - whether or not this marker belongs to a client or server packet.
|
||||||
* @param inputBuffer - the read serialized packet data.
|
* @param inputBuffer - the read serialized packet data.
|
||||||
*/
|
*/
|
||||||
public NetworkMarker(@Nonnull ConnectionSide side, ByteBuffer inputBuffer) {
|
public NetworkMarker(@Nonnull ConnectionSide side, ByteBuffer inputBuffer, PacketType type) {
|
||||||
this.side = Preconditions.checkNotNull(side, "side cannot be NULL.");
|
this.side = Preconditions.checkNotNull(side, "side cannot be NULL.");
|
||||||
this.inputBuffer = Preconditions.checkNotNull(inputBuffer, "inputBuffer cannot be NULL.");
|
this.inputBuffer = Preconditions.checkNotNull(inputBuffer, "inputBuffer cannot be NULL.");
|
||||||
|
this.type = Preconditions.checkNotNull(type, "type cannot be NULL.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,9 +74,11 @@ public class NetworkMarker {
|
|||||||
* The input buffer is only non-null for client-side packets.
|
* The input buffer is only non-null for client-side packets.
|
||||||
* @param side - whether or not this marker belongs to a client or server packet.
|
* @param side - whether or not this marker belongs to a client or server packet.
|
||||||
* @param inputBuffer - the read serialized packet data.
|
* @param inputBuffer - the read serialized packet data.
|
||||||
|
* @param handler - handle skipping headers.
|
||||||
*/
|
*/
|
||||||
public NetworkMarker(@Nonnull ConnectionSide side, byte[] inputBuffer) {
|
public NetworkMarker(@Nonnull ConnectionSide side, byte[] inputBuffer, PacketType type) {
|
||||||
this.side = Preconditions.checkNotNull(side, "side cannot be NULL.");
|
this.side = Preconditions.checkNotNull(side, "side cannot be NULL.");
|
||||||
|
this.type = Preconditions.checkNotNull(type, "type cannot be NULL.");
|
||||||
|
|
||||||
if (inputBuffer != null) {
|
if (inputBuffer != null) {
|
||||||
this.inputBuffer = ByteBuffer.wrap(inputBuffer);
|
this.inputBuffer = ByteBuffer.wrap(inputBuffer);
|
||||||
@ -75,7 +104,7 @@ public class NetworkMarker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the serialized packet data (excluding the header) from the network input stream.
|
* Retrieve the serialized packet data (excluding the header by default) from the network input stream.
|
||||||
* <p>
|
* <p>
|
||||||
* The returned buffer is read-only. If the parent event is a server side packet this
|
* The returned buffer is read-only. If the parent event is a server side packet this
|
||||||
* method throws {@link IllegalStateException}.
|
* method throws {@link IllegalStateException}.
|
||||||
@ -84,9 +113,49 @@ public class NetworkMarker {
|
|||||||
* @return A byte buffer containing the raw packet data read from the network.
|
* @return A byte buffer containing the raw packet data read from the network.
|
||||||
*/
|
*/
|
||||||
public ByteBuffer getInputBuffer() {
|
public ByteBuffer getInputBuffer() {
|
||||||
|
return getInputBuffer(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the serialized packet data from the network input stream.
|
||||||
|
* <p>
|
||||||
|
* The returned buffer is read-only. If the parent event is a server side packet this
|
||||||
|
* method throws {@link IllegalStateException}.
|
||||||
|
* <p>
|
||||||
|
* It returns NULL if the packet was transmitted by a plugin locally.
|
||||||
|
* @param excludeHeader - whether or not to exclude the packet ID header.
|
||||||
|
* @return A byte buffer containing the raw packet data read from the network.
|
||||||
|
*/
|
||||||
|
public ByteBuffer getInputBuffer(boolean excludeHeader) {
|
||||||
if (side.isForServer())
|
if (side.isForServer())
|
||||||
throw new IllegalStateException("Server-side packets have no input buffer.");
|
throw new IllegalStateException("Server-side packets have no input buffer.");
|
||||||
return inputBuffer != null ? inputBuffer.asReadOnlyBuffer() : null;
|
|
||||||
|
if (inputBuffer != null) {
|
||||||
|
ByteBuffer result = inputBuffer.asReadOnlyBuffer();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (excludeHeader)
|
||||||
|
result = skipHeader(result);
|
||||||
|
else
|
||||||
|
result = addHeader(result, type);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Cannot skip packet header.", e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the serialized packet data (excluding the header by default) as an input stream.
|
||||||
|
* <p>
|
||||||
|
* The data is exactly the same as in {@link #getInputBuffer()}.
|
||||||
|
* @see #getInputBuffer()
|
||||||
|
* @param excludeHeader - whether or not to exclude the packet ID header.
|
||||||
|
* @return The incoming serialized packet data as a stream, or NULL if the packet was transmitted locally.
|
||||||
|
*/
|
||||||
|
public DataInputStream getInputStream() {
|
||||||
|
return getInputStream(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,17 +163,37 @@ public class NetworkMarker {
|
|||||||
* <p>
|
* <p>
|
||||||
* The data is exactly the same as in {@link #getInputBuffer()}.
|
* The data is exactly the same as in {@link #getInputBuffer()}.
|
||||||
* @see #getInputBuffer()
|
* @see #getInputBuffer()
|
||||||
|
* @param excludeHeader - whether or not to exclude the packet ID header.
|
||||||
* @return The incoming serialized packet data as a stream, or NULL if the packet was transmitted locally.
|
* @return The incoming serialized packet data as a stream, or NULL if the packet was transmitted locally.
|
||||||
*/
|
*/
|
||||||
public DataInputStream getInputStream() {
|
@SuppressWarnings("resource")
|
||||||
|
public DataInputStream getInputStream(boolean excludeHeader) {
|
||||||
if (side.isForServer())
|
if (side.isForServer())
|
||||||
throw new IllegalStateException("Server-side packets have no input buffer.");
|
throw new IllegalStateException("Server-side packets have no input buffer.");
|
||||||
if (inputBuffer == null)
|
if (inputBuffer == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return new DataInputStream(
|
DataInputStream input = new DataInputStream(
|
||||||
new ByteArrayInputStream(inputBuffer.array())
|
new ByteArrayInputStream(inputBuffer.array())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (excludeHeader)
|
||||||
|
input = skipHeader(input);
|
||||||
|
else
|
||||||
|
input = addHeader(input, type);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Cannot skip packet header.", e);
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the output handlers have to write a packet header.
|
||||||
|
* @return TRUE if they do, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public boolean requireOutputHeader() {
|
||||||
|
return MinecraftReflection.isUsingNetty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,6 +261,40 @@ public class NetworkMarker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a byte buffer without the header in the current packet.
|
||||||
|
* <p>
|
||||||
|
* It's safe to modify the position of the buffer.
|
||||||
|
* @param buffer - a read-only byte source.
|
||||||
|
*/
|
||||||
|
protected ByteBuffer skipHeader(ByteBuffer buffer) throws IOException {
|
||||||
|
skipHeader(new DataInputStream(new ByteBufferInputStream(buffer)));
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an input stream without the header in the current packet.
|
||||||
|
* <p>
|
||||||
|
* It's safe to modify the input stream.
|
||||||
|
*/
|
||||||
|
protected abstract DataInputStream skipHeader(DataInputStream input) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the byte buffer prepended with the packet header.
|
||||||
|
* @param buffer - the read-only byte buffer.
|
||||||
|
* @param type - the current packet.
|
||||||
|
* @return The byte buffer.
|
||||||
|
*/
|
||||||
|
protected abstract ByteBuffer addHeader(ByteBuffer buffer, PacketType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the input stream prepended with the packet header.
|
||||||
|
* @param input - the input stream.
|
||||||
|
* @param type - the current packet.
|
||||||
|
* @return The byte buffer.
|
||||||
|
*/
|
||||||
|
protected abstract DataInputStream addHeader(DataInputStream input, PacketType type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the given marker has any output handlers.
|
* Determine if the given marker has any output handlers.
|
||||||
* @param marker - the marker to check.
|
* @param marker - the marker to check.
|
||||||
|
@ -207,8 +207,8 @@ public class PacketEvent extends EventObject implements Cancellable {
|
|||||||
public NetworkMarker getNetworkMarker() {
|
public NetworkMarker getNetworkMarker() {
|
||||||
if (networkMarker == null) {
|
if (networkMarker == null) {
|
||||||
if (isServerPacket()) {
|
if (isServerPacket()) {
|
||||||
networkMarker = new NetworkMarker(
|
networkMarker = new NetworkMarker.EmptyBufferMarker(
|
||||||
serverPacket ? ConnectionSide.SERVER_SIDE : ConnectionSide.CLIENT_SIDE, (byte[]) null);
|
serverPacket ? ConnectionSide.SERVER_SIDE : ConnectionSide.CLIENT_SIDE);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Add the option ListenerOptions.INTERCEPT_INPUT_BUFFER to your listener.");
|
throw new IllegalStateException("Add the option ListenerOptions.INTERCEPT_INPUT_BUFFER to your listener.");
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,10 @@ public interface PacketOutputHandler {
|
|||||||
/**
|
/**
|
||||||
* Invoked when a given packet is to be written to the output stream.
|
* Invoked when a given packet is to be written to the output stream.
|
||||||
* <p>
|
* <p>
|
||||||
* Note that the buffer is initially filled with the output from the default write method. This excludes
|
* Note that the buffer is initially filled with the output from the default write method.
|
||||||
* the packet ID header.
|
* <p>
|
||||||
|
* In Minecraft 1.6.4, the header is always excluded, whereas it MUST be included in Minecraft 1.7.2. Call
|
||||||
|
* {@link NetworkMarker#requireOutputHeader()} to determine this.
|
||||||
* @param event - the packet that will be outputted.
|
* @param event - the packet that will be outputted.
|
||||||
* @param buffer - the data that is currently scheduled to be outputted.
|
* @param buffer - the data that is currently scheduled to be outputted.
|
||||||
* @return The modified byte array to write. NULL is not permitted.
|
* @return The modified byte array to write. NULL is not permitted.
|
||||||
|
@ -244,10 +244,6 @@ class ChannelInjector extends ByteToMessageDecoder {
|
|||||||
protected void encode(ChannelHandlerContext ctx, Object packet, ByteBuf output) throws Exception {
|
protected void encode(ChannelHandlerContext ctx, Object packet, ByteBuf output) throws Exception {
|
||||||
ChannelInjector.this.encode(ctx, packet, output);
|
ChannelInjector.this.encode(ctx, packet, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) {
|
|
||||||
throwable.printStackTrace();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Insert our handlers - note that we effectively replace the vanilla encoder/decoder
|
// Insert our handlers - note that we effectively replace the vanilla encoder/decoder
|
||||||
@ -369,7 +365,7 @@ class ChannelInjector extends ByteToMessageDecoder {
|
|||||||
|
|
||||||
if (channelListener.includeBuffer(packetClass)) {
|
if (channelListener.includeBuffer(packetClass)) {
|
||||||
byteBuffer.resetReaderIndex();
|
byteBuffer.resetReaderIndex();
|
||||||
marker = new NetworkMarker(ConnectionSide.CLIENT_SIDE, getBytes(byteBuffer));
|
marker = new NettyNetworkMarker(ConnectionSide.CLIENT_SIDE, getBytes(byteBuffer));
|
||||||
}
|
}
|
||||||
Object output = channelListener.onPacketReceiving(this, input, marker);
|
Object output = channelListener.onPacketReceiving(this, input, marker);
|
||||||
|
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.comphenix.protocol.injector.netty;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.ConnectionSide;
|
||||||
|
import com.comphenix.protocol.events.NetworkMarker;
|
||||||
|
|
||||||
|
class NettyNetworkMarker extends NetworkMarker {
|
||||||
|
public NettyNetworkMarker(@Nonnull ConnectionSide side, byte[] inputBuffer) {
|
||||||
|
super(side, inputBuffer, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NettyNetworkMarker(@Nonnull ConnectionSide side, ByteBuffer inputBuffer) {
|
||||||
|
super(side, inputBuffer, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataInputStream skipHeader(DataInputStream input) throws IOException {
|
||||||
|
// Skip the variable int containing the packet ID
|
||||||
|
getSerializer().deserializeVarInt(input);
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ByteBuffer addHeader(ByteBuffer buffer, PacketType type) {
|
||||||
|
// We don't have to add anything - it's already there
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataInputStream addHeader(DataInputStream input, PacketType type) {
|
||||||
|
// As above
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
}
|
@ -307,7 +307,7 @@ public class NettyProtocolInjector implements ChannelListener {
|
|||||||
return new AbstractPacketInjector(reveivedFilters) {
|
return new AbstractPacketInjector(reveivedFilters) {
|
||||||
@Override
|
@Override
|
||||||
public PacketEvent packetRecieved(PacketContainer packet, Player client, byte[] buffered) {
|
public PacketEvent packetRecieved(PacketContainer packet, Player client, byte[] buffered) {
|
||||||
NetworkMarker marker = buffered != null ? new NetworkMarker(ConnectionSide.CLIENT_SIDE, buffered) : null;
|
NetworkMarker marker = buffered != null ? new NettyNetworkMarker(ConnectionSide.CLIENT_SIDE, buffered) : null;
|
||||||
ChannelInjector.fromPlayer(client, NettyProtocolInjector.this).
|
ChannelInjector.fromPlayer(client, NettyProtocolInjector.this).
|
||||||
saveMarker(packet.getHandle(), marker);
|
saveMarker(packet.getHandle(), marker);
|
||||||
return packetReceived(packet, client, marker);
|
return packetReceived(packet, client, marker);
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.comphenix.protocol.injector.packet;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.ConnectionSide;
|
||||||
|
import com.comphenix.protocol.events.NetworkMarker;
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
import com.google.common.io.InputSupplier;
|
||||||
|
import com.google.common.primitives.Bytes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a network marker for 1.6.4 and earlier.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
public class LegacyNetworkMarker extends NetworkMarker {
|
||||||
|
public LegacyNetworkMarker(@Nonnull ConnectionSide side, byte[] inputBuffer, PacketType type) {
|
||||||
|
super(side, inputBuffer, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LegacyNetworkMarker(@Nonnull ConnectionSide side, ByteBuffer inputBuffer, PacketType type) {
|
||||||
|
super(side, inputBuffer, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataInputStream skipHeader(DataInputStream input) throws IOException {
|
||||||
|
// This has already been done
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ByteBuffer addHeader(ByteBuffer buffer, PacketType type) {
|
||||||
|
return ByteBuffer.wrap(Bytes.concat(new byte[] { (byte) type.getLegacyId() }, buffer.array()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
@Override
|
||||||
|
protected DataInputStream addHeader(final DataInputStream input, final PacketType type) {
|
||||||
|
InputSupplier<InputStream> header = new InputSupplier<InputStream>() {
|
||||||
|
@Override
|
||||||
|
public InputStream getInput() throws IOException {
|
||||||
|
byte[] data = new byte[] { (byte) type.getLegacyId() };
|
||||||
|
return new ByteArrayInputStream(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
InputSupplier<InputStream> data = new InputSupplier<InputStream>() {
|
||||||
|
@Override
|
||||||
|
public InputStream getInput() throws IOException {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Combine them into a single stream
|
||||||
|
try {
|
||||||
|
return new DataInputStream(ByteStreams.join((InputSupplier) header, (InputSupplier) data).getInput());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Cannot add header.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -349,7 +349,7 @@ class ProxyPacketInjector implements PacketInjector {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PacketEvent packetRecieved(PacketContainer packet, Player client, byte[] buffered) {
|
public PacketEvent packetRecieved(PacketContainer packet, Player client, byte[] buffered) {
|
||||||
NetworkMarker marker = buffered != null ? new NetworkMarker(ConnectionSide.CLIENT_SIDE, buffered) : null;
|
NetworkMarker marker = buffered != null ? new LegacyNetworkMarker(ConnectionSide.CLIENT_SIDE, buffered, packet.getType()) : null;
|
||||||
PacketEvent event = PacketEvent.fromClient((Object) manager, packet, marker, client);
|
PacketEvent event = PacketEvent.fromClient((Object) manager, packet, marker, client);
|
||||||
|
|
||||||
manager.invokePacketRecieving(event);
|
manager.invokePacketRecieving(event);
|
||||||
|
@ -35,6 +35,7 @@ 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;
|
||||||
import com.comphenix.protocol.injector.PlayerLoggedOutException;
|
import com.comphenix.protocol.injector.PlayerLoggedOutException;
|
||||||
|
import com.comphenix.protocol.injector.packet.LegacyNetworkMarker;
|
||||||
import com.comphenix.protocol.injector.packet.PacketInjector;
|
import com.comphenix.protocol.injector.packet.PacketInjector;
|
||||||
import com.comphenix.protocol.injector.player.NetworkObjectInjector;
|
import com.comphenix.protocol.injector.player.NetworkObjectInjector;
|
||||||
import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
|
import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
|
||||||
@ -486,7 +487,7 @@ public class SpigotPacketInjector implements SpigotPacketListener {
|
|||||||
* @return The packet event that was used.
|
* @return The packet event that was used.
|
||||||
*/
|
*/
|
||||||
PacketEvent packetReceived(PacketContainer packet, Player sender, byte[] buffered) {
|
PacketEvent packetReceived(PacketContainer packet, Player sender, byte[] buffered) {
|
||||||
NetworkMarker marker = buffered != null ? new NetworkMarker(ConnectionSide.CLIENT_SIDE, buffered) : null;
|
NetworkMarker marker = buffered != null ? new LegacyNetworkMarker(ConnectionSide.CLIENT_SIDE, buffered, packet.getType()) : null;
|
||||||
PacketEvent event = PacketEvent.fromClient(this, packet, marker, sender);
|
PacketEvent event = PacketEvent.fromClient(this, packet, marker, sender);
|
||||||
|
|
||||||
invoker.invokePacketRecieving(event);
|
invoker.invokePacketRecieving(event);
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.comphenix.protocol.utility;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an input stream that delegates to a byte buffer.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
public class ByteBufferInputStream extends InputStream {
|
||||||
|
private ByteBuffer buf;
|
||||||
|
|
||||||
|
public ByteBufferInputStream(ByteBuffer buf) {
|
||||||
|
this.buf = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() throws IOException {
|
||||||
|
if (!buf.hasRemaining()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return buf.get() & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read(byte[] bytes, int off, int len)
|
||||||
|
throws IOException {
|
||||||
|
if (!buf.hasRemaining()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = Math.min(len, buf.remaining());
|
||||||
|
buf.get(bytes, off, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.comphenix.protocol.utility;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an output stream that is backed by a ByteBuffer.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
public class ByteBufferOutputStream extends OutputStream {
|
||||||
|
ByteBuffer buf;
|
||||||
|
|
||||||
|
public ByteBufferOutputStream(ByteBuffer buf) {
|
||||||
|
this.buf = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
buf.put((byte) b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte[] bytes, int off, int len)
|
||||||
|
throws IOException {
|
||||||
|
buf.put(bytes, off, len);
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@ import com.comphenix.protocol.reflect.FuzzyReflection.MethodAccessor;
|
|||||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility methods for reading and writing Minecraft objects to streams.
|
* Utility methods for reading and writing Minecraft objects to streams.
|
||||||
@ -24,6 +25,8 @@ import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
|||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class StreamSerializer {
|
public class StreamSerializer {
|
||||||
|
private static final StreamSerializer DEFAULT = new StreamSerializer();
|
||||||
|
|
||||||
// Cached methods
|
// Cached methods
|
||||||
private static MethodAccessor READ_ITEM_METHOD;
|
private static MethodAccessor READ_ITEM_METHOD;
|
||||||
private static MethodAccessor WRITE_ITEM_METHOD;
|
private static MethodAccessor WRITE_ITEM_METHOD;
|
||||||
@ -34,6 +37,52 @@ public class StreamSerializer {
|
|||||||
private static MethodAccessor READ_STRING_METHOD;
|
private static MethodAccessor READ_STRING_METHOD;
|
||||||
private static MethodAccessor WRITE_STRING_METHOD;
|
private static MethodAccessor WRITE_STRING_METHOD;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a default stream serializer.
|
||||||
|
* @return A serializer.
|
||||||
|
*/
|
||||||
|
public static StreamSerializer getDefault() {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a variable integer from an input stream.
|
||||||
|
* @param source - the source.
|
||||||
|
* @return The integer.
|
||||||
|
* @throws IOException The source stream threw an exception.
|
||||||
|
*/
|
||||||
|
public int deserializeVarInt(@Nonnull DataInputStream source) throws IOException {
|
||||||
|
Preconditions.checkNotNull(source, "source cannot be NULL");
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
int length = 0;
|
||||||
|
byte currentByte;
|
||||||
|
do {
|
||||||
|
currentByte = source.readByte();
|
||||||
|
result |= (currentByte & 0x7F) << length++ * 7;
|
||||||
|
if (length > 5)
|
||||||
|
throw new RuntimeException("VarInt too big");
|
||||||
|
} while ((currentByte & 0x80) == 0x80);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a variable integer to an output stream.
|
||||||
|
* @param destination - the destination.
|
||||||
|
* @param value - the value to write.
|
||||||
|
* @throws IOException The destination stream threw an exception.
|
||||||
|
*/
|
||||||
|
public void serializeVarInt(@Nonnull DataOutputStream destination, int value) throws IOException {
|
||||||
|
Preconditions.checkNotNull(destination, "source cannot be NULL");
|
||||||
|
|
||||||
|
while ((value & 0xFFFFFF80) != 0) {
|
||||||
|
destination.writeByte(value & 0x7F | 0x80);
|
||||||
|
value >>>= 7;
|
||||||
|
}
|
||||||
|
destination.writeByte(value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read or deserialize an item stack from an underlying input stream.
|
* Read or deserialize an item stack from an underlying input stream.
|
||||||
* <p>
|
* <p>
|
||||||
|
Loading…
Reference in New Issue
Block a user