Add initial support for wire format packets
Dieser Commit ist enthalten in:
Ursprung
6ddbbfb428
Commit
489c72418d
@ -24,6 +24,7 @@ import org.bukkit.entity.Player;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.NetworkMarker;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.injector.netty.WirePacket;
|
||||
|
||||
/**
|
||||
* Represents a object capable of sending or receiving packets.
|
||||
@ -61,6 +62,22 @@ public interface PacketStream {
|
||||
public void sendServerPacket(Player receiver, PacketContainer packet, NetworkMarker marker, boolean filters)
|
||||
throws InvocationTargetException;
|
||||
|
||||
/**
|
||||
* Send a wire packet to the given player.
|
||||
* @param receiver - the receiver.
|
||||
* @param id - packet id.
|
||||
* @param bytes - packet bytes.
|
||||
* @throws InvocationTargetException if an error occured when sending the packet.
|
||||
*/
|
||||
public void sendWirePacket(Player receiver, int id, byte[] bytes) throws InvocationTargetException;
|
||||
|
||||
/**
|
||||
* Send a wire packet to the given player.
|
||||
* @param receiver - the receiver.
|
||||
* @param packet - packet to send.
|
||||
* @throws InvocationTargetException if an error occured when sending the packet.
|
||||
*/
|
||||
public void sendWirePacket(Player receiver, WirePacket packet) throws InvocationTargetException;
|
||||
|
||||
/**
|
||||
* Simulate recieving a certain packet from a given player.
|
||||
|
@ -27,6 +27,7 @@ import com.comphenix.protocol.events.NetworkMarker;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
|
||||
import com.comphenix.protocol.injector.netty.WirePacket;
|
||||
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
@ -45,6 +46,7 @@ import com.google.common.collect.Sets;
|
||||
public class DelayedPacketManager implements ProtocolManager, InternalManager {
|
||||
// Registering packet IDs that are not supported
|
||||
public static final ReportType REPORT_CANNOT_SEND_QUEUED_PACKET = new ReportType("Cannot send queued packet %s.");
|
||||
public static final ReportType REPORT_CANNOT_SEND_QUEUED_WIRE_PACKET = new ReportType("Cannot send queued wire packet %s.");
|
||||
public static final ReportType REPORT_CANNOT_REGISTER_QUEUED_LISTENER = new ReportType("Cannot register queued listener %s.");
|
||||
|
||||
private volatile InternalManager delegate;
|
||||
@ -207,6 +209,36 @@ public class DelayedPacketManager implements ProtocolManager, InternalManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendWirePacket(Player receiver, int id, byte[] bytes) throws InvocationTargetException {
|
||||
WirePacket packet = new WirePacket(id, bytes);
|
||||
sendWirePacket(receiver, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendWirePacket(final Player receiver, final WirePacket packet) throws InvocationTargetException {
|
||||
if (delegate != null) {
|
||||
delegate.sendWirePacket(receiver, packet);
|
||||
} else {
|
||||
queuedActions.add(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
delegate.sendWirePacket(receiver, packet);
|
||||
} catch (Throwable ex) {
|
||||
// Inform about this plugin error
|
||||
reporter.reportWarning(this, Report.newBuilder(REPORT_CANNOT_SEND_QUEUED_WIRE_PACKET)
|
||||
.callerParam(delegate)
|
||||
.messageParam(packet)
|
||||
.error(ex));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recieveClientPacket(Player sender, PacketContainer packet) throws IllegalAccessException, InvocationTargetException {
|
||||
recieveClientPacket(sender, packet, null, true);
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package com.comphenix.protocol.injector;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
@ -67,6 +69,7 @@ import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.netty.NettyProtocolInjector;
|
||||
import com.comphenix.protocol.injector.netty.WirePacket;
|
||||
import com.comphenix.protocol.injector.packet.InterceptWritePacket;
|
||||
import com.comphenix.protocol.injector.packet.PacketInjector;
|
||||
import com.comphenix.protocol.injector.packet.PacketInjectorBuilder;
|
||||
@ -833,6 +836,22 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
||||
playerInjection.sendServerPacket(receiver, packet, marker, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendWirePacket(Player receiver, int id, byte[] bytes) throws InvocationTargetException {
|
||||
WirePacket packet = new WirePacket(id, bytes);
|
||||
sendWirePacket(receiver, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendWirePacket(Player receiver, WirePacket packet) throws InvocationTargetException {
|
||||
Channel channel = playerInjection.getChannel(receiver);
|
||||
if (channel == null) {
|
||||
throw new InvocationTargetException(new NullPointerException(), "Failed to obtain channel for " + receiver.getName());
|
||||
}
|
||||
|
||||
channel.writeAndFlush(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recieveClientPacket(Player sender, PacketContainer packet) throws IllegalAccessException, InvocationTargetException {
|
||||
recieveClientPacket(sender, packet, null, true);
|
||||
|
@ -223,7 +223,12 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
||||
protocolEncoder = new MessageToByteEncoder<Object>() {
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, Object packet, ByteBuf output) throws Exception {
|
||||
ChannelInjector.this.encode(ctx, packet, output);
|
||||
if (packet instanceof WirePacket) {
|
||||
// Special case for wire format
|
||||
ChannelInjector.this.encodeWirePacket(ctx, (WirePacket) packet, output);
|
||||
} else {
|
||||
ChannelInjector.this.encode(ctx, packet, output);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -381,6 +386,11 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
||||
super.exceptionCaught(ctx, cause);
|
||||
}
|
||||
|
||||
protected void encodeWirePacket(ChannelHandlerContext ctx, WirePacket packet, ByteBuf output) throws Exception {
|
||||
packet.writeId(output);
|
||||
packet.writeBytes(output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a packet to a byte buffer, taking over for the standard Minecraft encoder.
|
||||
* @param ctx - the current context.
|
||||
@ -875,4 +885,8 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
||||
return injector;
|
||||
}
|
||||
}
|
||||
|
||||
public Channel getChannel() {
|
||||
return originalChannel;
|
||||
}
|
||||
}
|
@ -373,6 +373,16 @@ public class NettyProtocolInjector implements ChannelListener {
|
||||
public void handleDisconnect(Player player) {
|
||||
injectionFactory.fromPlayer(player, listener).close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel getChannel(Player player) {
|
||||
Injector injector = injectionFactory.fromPlayer(player, listener);
|
||||
if (injector instanceof ChannelInjector) {
|
||||
return ((ChannelInjector) injector).getChannel();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* (c) 2015 dmulloy2
|
||||
*/
|
||||
package com.comphenix.protocol.injector.netty;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WirePacket {
|
||||
private final int id;
|
||||
private final byte[] bytes;
|
||||
|
||||
public WirePacket(int id, byte[] bytes) {
|
||||
this.id = id;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public void writeId(ByteBuf output) {
|
||||
int i = id;
|
||||
while ((i & -128) != 0) {
|
||||
output.writeByte(i & 127 | 128);
|
||||
i >>>= 7;
|
||||
}
|
||||
|
||||
output.writeByte(i);
|
||||
}
|
||||
|
||||
public void writeBytes(ByteBuf output) {
|
||||
output.writeBytes(bytes);
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package com.comphenix.protocol.injector.player;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -198,4 +200,6 @@ public interface PlayerInjectionHandler {
|
||||
* @return TRUE if we do, FALSE otherwise.
|
||||
*/
|
||||
public abstract boolean hasMainThreadListener(PacketType type);
|
||||
|
||||
public abstract Channel getChannel(Player player);
|
||||
}
|
@ -17,6 +17,8 @@
|
||||
|
||||
package com.comphenix.protocol.injector.player;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
@ -753,4 +755,9 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler {
|
||||
playerInjection.clear();
|
||||
invoker = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel getChannel(Player player) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.comphenix.protocol.injector.spigot;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.InetSocketAddress;
|
||||
@ -82,4 +84,9 @@ class DummyPlayerHandler extends AbstractPlayerHandler {
|
||||
public void updatePlayer(Player player) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel getChannel(Player player) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren