Prevent exception when connecting using an older client

This commit is contained in:
themode 2021-01-06 03:16:46 +01:00
parent 2634105ad1
commit 7347c8df68
3 changed files with 35 additions and 14 deletions

View File

@ -51,27 +51,32 @@ public final class PacketProcessor {
}
public void process(@NotNull ChannelHandlerContext channel, @NotNull InboundPacket packet) {
final SocketChannel socketChannel = (SocketChannel) channel.channel();
// Create the netty player connection object if not existing
PlayerConnection playerConnection = connectionPlayerConnectionMap.computeIfAbsent(
channel, c -> new NettyPlayerConnection((SocketChannel) channel.channel())
channel, c -> new NettyPlayerConnection(socketChannel)
);
// Prevent the client from sending packets when disconnected (kick)
if (!playerConnection.isOnline()) {
if (!playerConnection.isOnline() || !socketChannel.isActive()) {
playerConnection.disconnect();
return;
}
if (MinecraftServer.getRateLimit() > 0)
// Increment packet count (checked in PlayerConnection#update)
if (MinecraftServer.getRateLimit() > 0) {
playerConnection.getPacketCounter().incrementAndGet();
}
final ConnectionState connectionState = playerConnection.getConnectionState();
BinaryReader binaryReader = new BinaryReader(packet.body);
final int packetId = packet.getPacketId();
BinaryReader binaryReader = new BinaryReader(packet.getBody());
if (connectionState == ConnectionState.UNKNOWN) {
// Should be handshake packet
if (packet.packetId == 0) {
if (packetId == 0) {
HandshakePacket handshakePacket = new HandshakePacket();
safeRead(playerConnection, handshakePacket, binaryReader);
handshakePacket.process(playerConnection);
@ -82,17 +87,18 @@ public final class PacketProcessor {
switch (connectionState) {
case PLAY:
final Player player = playerConnection.getPlayer();
ClientPlayPacket playPacket = (ClientPlayPacket) playPacketsHandler.getPacketInstance(packet.packetId);
ClientPlayPacket playPacket = (ClientPlayPacket) playPacketsHandler.getPacketInstance(packetId);
safeRead(playerConnection, playPacket, binaryReader);
assert player != null;
player.addPacketToQueue(playPacket);
break;
case LOGIN:
final ClientPreplayPacket loginPacket = (ClientPreplayPacket) loginPacketsHandler.getPacketInstance(packet.packetId);
final ClientPreplayPacket loginPacket = (ClientPreplayPacket) loginPacketsHandler.getPacketInstance(packetId);
safeRead(playerConnection, loginPacket, binaryReader);
loginPacket.process(playerConnection);
break;
case STATUS:
final ClientPreplayPacket statusPacket = (ClientPreplayPacket) statusPacketsHandler.getPacketInstance(packet.packetId);
final ClientPreplayPacket statusPacket = (ClientPreplayPacket) statusPacketsHandler.getPacketInstance(packetId);
safeRead(playerConnection, statusPacket, binaryReader);
statusPacket.process(playerConnection);
break;

View File

@ -1,5 +1,6 @@
package net.minestom.server.network.netty.channel;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import net.minestom.server.MinecraftServer;
@ -35,15 +36,21 @@ public class ClientChannel extends SimpleChannelInboundHandler<InboundPacket> {
} catch (Exception e) {
e.printStackTrace();
} finally {
final int availableBytes = packet.body.readableBytes();
// Check remaining
final ByteBuf body = packet.getBody();
final int packetId = packet.getPacketId();
final int availableBytes = body.readableBytes();
if (availableBytes > 0) {
final PlayerConnection playerConnection = packetProcessor.getPlayerConnection(ctx);
LOGGER.warn("WARNING: Packet 0x" + Integer.toHexString(packet.packetId)
+ " not fully read (" + availableBytes + " bytes left), " + playerConnection);
LOGGER.warn("WARNING: Packet 0x{} not fully read ({} bytes left), {}",
Integer.toHexString(packetId),
availableBytes,
playerConnection);
packet.body.skipBytes(availableBytes);
body.skipBytes(availableBytes);
}
}
}

View File

@ -5,12 +5,20 @@ import org.jetbrains.annotations.NotNull;
public class InboundPacket {
public final int packetId;
public final ByteBuf body;
private final int packetId;
private final ByteBuf body;
public InboundPacket(int id, @NotNull ByteBuf body) {
this.packetId = id;
this.body = body;
}
public int getPacketId() {
return packetId;
}
@NotNull
public ByteBuf getBody() {
return body;
}
}