From 9eda82252f27e38de2a18a094978fd32e521b064 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Tue, 10 Sep 2024 10:12:03 +0200 Subject: [PATCH 01/13] Implement static compression and encryption pipeline --- .../example/ClientSessionListener.java | 2 +- .../network/example/ServerListener.java | 2 +- .../network/example/TestProtocol.java | 8 +-- .../network/NetworkConstants.java | 10 ++++ .../mcprotocollib/network/Session.java | 26 ++++----- .../compression/CompressionConfig.java | 4 ++ .../network/crypt/EncryptionConfig.java | 4 ++ .../network/tcp/TcpClientSession.java | 2 + .../network/tcp/TcpPacketCompression.java | 55 +++++++++++-------- .../network/tcp/TcpPacketEncryptor.java | 25 ++++++--- .../mcprotocollib/network/tcp/TcpServer.java | 2 + .../mcprotocollib/network/tcp/TcpSession.java | 37 +++++-------- .../protocol/ClientListener.java | 7 ++- .../protocol/MinecraftProtocol.java | 8 +-- .../protocol/ServerListener.java | 6 +- 15 files changed, 114 insertions(+), 84 deletions(-) create mode 100644 protocol/src/main/java/org/geysermc/mcprotocollib/network/NetworkConstants.java create mode 100644 protocol/src/main/java/org/geysermc/mcprotocollib/network/compression/CompressionConfig.java create mode 100644 protocol/src/main/java/org/geysermc/mcprotocollib/network/crypt/EncryptionConfig.java diff --git a/example/src/main/java/org/geysermc/mcprotocollib/network/example/ClientSessionListener.java b/example/src/main/java/org/geysermc/mcprotocollib/network/example/ClientSessionListener.java index 029e6365c..ac42ccf38 100644 --- a/example/src/main/java/org/geysermc/mcprotocollib/network/example/ClientSessionListener.java +++ b/example/src/main/java/org/geysermc/mcprotocollib/network/example/ClientSessionListener.java @@ -39,7 +39,7 @@ public void packetSent(Session session, Packet packet) { public void connected(ConnectedEvent event) { log.info("CLIENT Connected"); - event.getSession().enableEncryption(((TestProtocol) event.getSession().getPacketProtocol()).getEncryption()); + event.getSession().setEncryption(((TestProtocol) event.getSession().getPacketProtocol()).getEncryption()); event.getSession().send(new PingPacket("hello")); } diff --git a/example/src/main/java/org/geysermc/mcprotocollib/network/example/ServerListener.java b/example/src/main/java/org/geysermc/mcprotocollib/network/example/ServerListener.java index 13e8b5eb8..f654d41a4 100644 --- a/example/src/main/java/org/geysermc/mcprotocollib/network/example/ServerListener.java +++ b/example/src/main/java/org/geysermc/mcprotocollib/network/example/ServerListener.java @@ -38,7 +38,7 @@ public void serverClosed(ServerClosedEvent event) { public void sessionAdded(SessionAddedEvent event) { log.info("SERVER Session Added: {}:{}", event.getSession().getHost(), event.getSession().getPort()); ((TestProtocol) event.getSession().getPacketProtocol()).setSecretKey(this.key); - event.getSession().enableEncryption(((TestProtocol) event.getSession().getPacketProtocol()).getEncryption()); + event.getSession().setEncryption(((TestProtocol) event.getSession().getPacketProtocol()).getEncryption()); } @Override diff --git a/example/src/main/java/org/geysermc/mcprotocollib/network/example/TestProtocol.java b/example/src/main/java/org/geysermc/mcprotocollib/network/example/TestProtocol.java index 5a7a8a270..cc108fb2c 100644 --- a/example/src/main/java/org/geysermc/mcprotocollib/network/example/TestProtocol.java +++ b/example/src/main/java/org/geysermc/mcprotocollib/network/example/TestProtocol.java @@ -8,7 +8,7 @@ import org.geysermc.mcprotocollib.network.codec.PacketDefinition; import org.geysermc.mcprotocollib.network.codec.PacketSerializer; import org.geysermc.mcprotocollib.network.crypt.AESEncryption; -import org.geysermc.mcprotocollib.network.crypt.PacketEncryption; +import org.geysermc.mcprotocollib.network.crypt.EncryptionConfig; import org.geysermc.mcprotocollib.network.packet.DefaultPacketHeader; import org.geysermc.mcprotocollib.network.packet.PacketHeader; import org.geysermc.mcprotocollib.network.packet.PacketProtocol; @@ -23,7 +23,7 @@ public class TestProtocol extends PacketProtocol { private static final Logger log = LoggerFactory.getLogger(TestProtocol.class); private final PacketHeader header = new DefaultPacketHeader(); private final PacketRegistry registry = new PacketRegistry(); - private AESEncryption encrypt; + private EncryptionConfig encrypt; @SuppressWarnings("unused") public TestProtocol() { @@ -51,7 +51,7 @@ public PingPacket deserialize(ByteBuf buf, PacketCodecHelper helper, PacketDefin }); try { - this.encrypt = new AESEncryption(key); + this.encrypt = new EncryptionConfig(new AESEncryption(key)); } catch (GeneralSecurityException e) { log.error("Failed to create encryption", e); } @@ -67,7 +67,7 @@ public PacketHeader getPacketHeader() { return this.header; } - public PacketEncryption getEncryption() { + public EncryptionConfig getEncryption() { return this.encrypt; } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/NetworkConstants.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/NetworkConstants.java new file mode 100644 index 000000000..6b7cd80de --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/NetworkConstants.java @@ -0,0 +1,10 @@ +package org.geysermc.mcprotocollib.network; + +import io.netty.util.AttributeKey; +import org.geysermc.mcprotocollib.network.compression.CompressionConfig; +import org.geysermc.mcprotocollib.network.crypt.EncryptionConfig; + +public class NetworkConstants { + public static final AttributeKey COMPRESSION_ATTRIBUTE_KEY = AttributeKey.valueOf("compression_threshold"); + public static final AttributeKey ENCRYPTION_ATTRIBUTE_KEY = AttributeKey.valueOf("encryption"); +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java index a4af44e33..1cab08efa 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java @@ -4,7 +4,8 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.mcprotocollib.network.codec.PacketCodecHelper; -import org.geysermc.mcprotocollib.network.crypt.PacketEncryption; +import org.geysermc.mcprotocollib.network.compression.CompressionConfig; +import org.geysermc.mcprotocollib.network.crypt.EncryptionConfig; import org.geysermc.mcprotocollib.network.event.session.SessionEvent; import org.geysermc.mcprotocollib.network.event.session.SessionListener; import org.geysermc.mcprotocollib.network.packet.Packet; @@ -183,28 +184,23 @@ public interface Session { void callPacketSent(Packet packet); /** - * Gets the compression packet length threshold for this session (-1 = disabled). + * Sets compression for this session. * - * @return This session's compression threshold. + * @param compressionConfig the compression to compress with + * or null to disable compression */ - int getCompressionThreshold(); + void setCompression(CompressionConfig compressionConfig); /** - * Sets the compression packet length threshold for this session (-1 = disabled). + * Sets encryption for this session. * - * @param threshold The new compression threshold. - * @param validateDecompression whether to validate that the decompression fits within size checks. - */ - void setCompressionThreshold(int threshold, boolean validateDecompression); - - /** - * Enables encryption for this session. + * @param encryptionConfig the encryption to encrypt with + * or null to disable encryption * - * @param encryption the encryption to encrypt with */ - void enableEncryption(PacketEncryption encryption); + void setEncryption(EncryptionConfig encryptionConfig); - /** + /** * Returns true if the session is connected. * * @return True if the session is connected. diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/compression/CompressionConfig.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/compression/CompressionConfig.java new file mode 100644 index 000000000..20444c22f --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/compression/CompressionConfig.java @@ -0,0 +1,4 @@ +package org.geysermc.mcprotocollib.network.compression; + +public record CompressionConfig(int threshold, PacketCompression compression, boolean validateDecompression) { +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/crypt/EncryptionConfig.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/crypt/EncryptionConfig.java new file mode 100644 index 000000000..ed5c3660f --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/crypt/EncryptionConfig.java @@ -0,0 +1,4 @@ +package org.geysermc.mcprotocollib.network.crypt; + +public record EncryptionConfig(PacketEncryption encryption) { +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpClientSession.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpClientSession.java index a04d0d89d..a430d09bd 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpClientSession.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpClientSession.java @@ -113,7 +113,9 @@ public void initChannel(Channel channel) { pipeline.addLast("read-timeout", new ReadTimeoutHandler(getFlag(BuiltinFlags.READ_TIMEOUT, 30))); pipeline.addLast("write-timeout", new WriteTimeoutHandler(getFlag(BuiltinFlags.WRITE_TIMEOUT, 0))); + pipeline.addLast("encryption", new TcpPacketEncryptor()); pipeline.addLast("sizer", new TcpPacketSizer(protocol.getPacketHeader(), getCodecHelper())); + pipeline.addLast("compression", new TcpPacketCompression(getCodecHelper())); pipeline.addLast("codec", new TcpPacketCodec(TcpClientSession.this, true)); pipeline.addLast("manager", TcpClientSession.this); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpPacketCompression.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpPacketCompression.java index 8a9b928c6..e83ef8f50 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpPacketCompression.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpPacketCompression.java @@ -4,44 +4,49 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.MessageToMessageCodec; -import org.geysermc.mcprotocollib.network.Session; -import org.geysermc.mcprotocollib.network.compression.PacketCompression; +import lombok.RequiredArgsConstructor; +import org.geysermc.mcprotocollib.network.NetworkConstants; +import org.geysermc.mcprotocollib.network.codec.PacketCodecHelper; +import org.geysermc.mcprotocollib.network.compression.CompressionConfig; import java.util.List; +@RequiredArgsConstructor public class TcpPacketCompression extends MessageToMessageCodec { private static final int MAX_UNCOMPRESSED_SIZE = 8 * 1024 * 1024; // 8MiB - - private final Session session; - private final PacketCompression compression; - private final boolean validateDecompression; - - public TcpPacketCompression(Session session, PacketCompression compression, boolean validateDecompression) { - this.session = session; - this.compression = compression; - this.validateDecompression = validateDecompression; - } + private final PacketCodecHelper helper; @Override public void handlerRemoved(ChannelHandlerContext ctx) { - this.compression.close(); + CompressionConfig config = ctx.channel().attr(NetworkConstants.COMPRESSION_ATTRIBUTE_KEY).get(); + if (config == null) { + return; + } + + config.compression().close(); } @Override public void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) { + CompressionConfig config = ctx.channel().attr(NetworkConstants.COMPRESSION_ATTRIBUTE_KEY).get(); + if (config == null) { + out.add(msg.retain()); + return; + } + int uncompressed = msg.readableBytes(); if (uncompressed > MAX_UNCOMPRESSED_SIZE) { throw new IllegalArgumentException("Packet too big (is " + uncompressed + ", should be less than " + MAX_UNCOMPRESSED_SIZE + ")"); } ByteBuf outBuf = ctx.alloc().directBuffer(uncompressed); - if (uncompressed < this.session.getCompressionThreshold()) { + if (uncompressed < config.threshold()) { // Under the threshold, there is nothing to do. - this.session.getCodecHelper().writeVarInt(outBuf, 0); + this.helper.writeVarInt(outBuf, 0); outBuf.writeBytes(msg); } else { - this.session.getCodecHelper().writeVarInt(outBuf, uncompressed); - compression.deflate(msg, outBuf); + this.helper.writeVarInt(outBuf, uncompressed); + config.compression().deflate(msg, outBuf); } out.add(outBuf); @@ -49,15 +54,21 @@ public void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { - int claimedUncompressedSize = this.session.getCodecHelper().readVarInt(in); + CompressionConfig config = ctx.channel().attr(NetworkConstants.COMPRESSION_ATTRIBUTE_KEY).get(); + if (config == null) { + out.add(in.retain()); + return; + } + + int claimedUncompressedSize = this.helper.readVarInt(in); if (claimedUncompressedSize == 0) { out.add(in.retain()); return; } - if (validateDecompression) { - if (claimedUncompressedSize < this.session.getCompressionThreshold()) { - throw new DecoderException("Badly compressed packet - size of " + claimedUncompressedSize + " is below server threshold of " + this.session.getCompressionThreshold()); + if (config.validateDecompression()) { + if (claimedUncompressedSize < config.threshold()) { + throw new DecoderException("Badly compressed packet - size of " + claimedUncompressedSize + " is below server threshold of " + config.threshold()); } if (claimedUncompressedSize > MAX_UNCOMPRESSED_SIZE) { @@ -67,7 +78,7 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { ByteBuf uncompressed = ctx.alloc().directBuffer(claimedUncompressedSize); try { - compression.inflate(in, uncompressed, claimedUncompressedSize); + config.compression().inflate(in, uncompressed, claimedUncompressedSize); out.add(uncompressed); } catch (Exception e) { uncompressed.release(); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpPacketEncryptor.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpPacketEncryptor.java index 2d8d1c21b..819c5c6e9 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpPacketEncryptor.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpPacketEncryptor.java @@ -6,26 +6,27 @@ import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.EncoderException; import io.netty.handler.codec.MessageToMessageCodec; -import org.geysermc.mcprotocollib.network.crypt.PacketEncryption; +import org.geysermc.mcprotocollib.network.NetworkConstants; +import org.geysermc.mcprotocollib.network.crypt.EncryptionConfig; import java.util.List; public class TcpPacketEncryptor extends MessageToMessageCodec { - private final PacketEncryption encryption; - - public TcpPacketEncryptor(PacketEncryption encryption) { - this.encryption = encryption; - } - @Override public void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) { + EncryptionConfig config = ctx.channel().attr(NetworkConstants.ENCRYPTION_ATTRIBUTE_KEY).get(); + if (config == null) { + out.add(msg.retain()); + return; + } + ByteBuf heapBuf = this.ensureHeapBuffer(ctx.alloc(), msg); int inBytes = heapBuf.readableBytes(); int baseOffset = heapBuf.arrayOffset() + heapBuf.readerIndex(); try { - encryption.encrypt(heapBuf.array(), baseOffset, inBytes, heapBuf.array(), baseOffset); + config.encryption().encrypt(heapBuf.array(), baseOffset, inBytes, heapBuf.array(), baseOffset); out.add(heapBuf); } catch (Exception e) { heapBuf.release(); @@ -35,13 +36,19 @@ public void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + EncryptionConfig config = ctx.channel().attr(NetworkConstants.ENCRYPTION_ATTRIBUTE_KEY).get(); + if (config == null) { + out.add(in.retain()); + return; + } + ByteBuf heapBuf = this.ensureHeapBuffer(ctx.alloc(), in).slice(); int inBytes = heapBuf.readableBytes(); int baseOffset = heapBuf.arrayOffset() + heapBuf.readerIndex(); try { - encryption.decrypt(heapBuf.array(), baseOffset, inBytes, heapBuf.array(), baseOffset); + config.encryption().decrypt(heapBuf.array(), baseOffset, inBytes, heapBuf.array(), baseOffset); out.add(heapBuf); } catch (Exception e) { heapBuf.release(); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpServer.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpServer.java index 4d35e9666..b6fdaab32 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpServer.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpServer.java @@ -64,7 +64,9 @@ public void initChannel(Channel channel) { pipeline.addLast("read-timeout", new ReadTimeoutHandler(session.getFlag(BuiltinFlags.READ_TIMEOUT, 30))); pipeline.addLast("write-timeout", new WriteTimeoutHandler(session.getFlag(BuiltinFlags.WRITE_TIMEOUT, 0))); + pipeline.addLast("encryption", new TcpPacketEncryptor()); pipeline.addLast("sizer", new TcpPacketSizer(protocol.getPacketHeader(), session.getCodecHelper())); + pipeline.addLast("compression", new TcpPacketCompression(session.getCodecHelper())); pipeline.addLast("codec", new TcpPacketCodec(session, false)); pipeline.addLast("manager", session); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java index 462f85b4b..4fc778ff9 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java @@ -12,9 +12,10 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.mcprotocollib.network.Flag; +import org.geysermc.mcprotocollib.network.NetworkConstants; import org.geysermc.mcprotocollib.network.Session; -import org.geysermc.mcprotocollib.network.compression.ZlibCompression; -import org.geysermc.mcprotocollib.network.crypt.PacketEncryption; +import org.geysermc.mcprotocollib.network.compression.CompressionConfig; +import org.geysermc.mcprotocollib.network.crypt.EncryptionConfig; import org.geysermc.mcprotocollib.network.event.session.ConnectedEvent; import org.geysermc.mcprotocollib.network.event.session.DisconnectedEvent; import org.geysermc.mcprotocollib.network.event.session.DisconnectingEvent; @@ -47,8 +48,6 @@ public abstract class TcpSession extends SimpleChannelInboundHandler imp private final PacketProtocol protocol; private final EventLoop eventLoop = createEventLoop(); - private int compressionThreshold = -1; - private final Map flags = new HashMap<>(); private final List listeners = new CopyOnWriteArrayList<>(); @@ -188,31 +187,21 @@ public void callPacketSent(Packet packet) { } @Override - public int getCompressionThreshold() { - return this.compressionThreshold; - } - - @Override - public void setCompressionThreshold(int threshold, boolean validateDecompression) { - this.compressionThreshold = threshold; - if (this.channel != null) { - if (this.compressionThreshold >= 0) { - if (this.channel.pipeline().get("compression") == null) { - this.channel.pipeline().addBefore("codec", "compression", - new TcpPacketCompression(this, new ZlibCompression(), validateDecompression)); - } - } else if (this.channel.pipeline().get("compression") != null) { - this.channel.pipeline().remove("compression"); - } + public void setCompression(CompressionConfig compressionConfig) { + if (this.channel == null) { + throw new IllegalStateException("You need to be connected to set the compression!"); } + + channel.attr(NetworkConstants.COMPRESSION_ATTRIBUTE_KEY).set(compressionConfig); } @Override - public void enableEncryption(PacketEncryption encryption) { + public void setEncryption(EncryptionConfig encryptionConfig) { if (channel == null) { - throw new IllegalStateException("Connect the client before initializing encryption!"); + throw new IllegalStateException("You need to connect to enable encryption!"); } - channel.pipeline().addBefore("sizer", "encryption", new TcpPacketEncryptor(encryption)); + + channel.attr(NetworkConstants.ENCRYPTION_ATTRIBUTE_KEY).set(encryptionConfig); } @Override @@ -267,7 +256,7 @@ public void disconnect(@NonNull Component reason, @Nullable Throwable cause) { // daemon threads and their interaction with the runtime. PACKET_EVENT_LOOP = new DefaultEventLoopGroup(new DefaultThreadFactory(this.getClass(), true)); Runtime.getRuntime().addShutdownHook(new Thread( - () -> PACKET_EVENT_LOOP.shutdownGracefully(SHUTDOWN_QUIET_PERIOD_MS, SHUTDOWN_TIMEOUT_MS, TimeUnit.MILLISECONDS))); + () -> PACKET_EVENT_LOOP.shutdownGracefully(SHUTDOWN_QUIET_PERIOD_MS, SHUTDOWN_TIMEOUT_MS, TimeUnit.MILLISECONDS))); } return PACKET_EVENT_LOOP.next(); } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java index 0b6f8e35a..b857348bd 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java @@ -7,6 +7,8 @@ import org.geysermc.mcprotocollib.auth.GameProfile; import org.geysermc.mcprotocollib.auth.SessionService; import org.geysermc.mcprotocollib.network.Session; +import org.geysermc.mcprotocollib.network.compression.CompressionConfig; +import org.geysermc.mcprotocollib.network.compression.ZlibCompression; import org.geysermc.mcprotocollib.network.event.session.ConnectedEvent; import org.geysermc.mcprotocollib.network.event.session.SessionAdapter; import org.geysermc.mcprotocollib.network.packet.Packet; @@ -91,13 +93,14 @@ public void packetReceived(Session session, Packet packet) { } session.send(new ServerboundKeyPacket(helloPacket.getPublicKey(), key, helloPacket.getChallenge())); - session.enableEncryption(protocol.enableEncryption(key)); + session.setEncryption(protocol.enableEncryption(key)); } else if (packet instanceof ClientboundGameProfilePacket) { session.send(new ServerboundLoginAcknowledgedPacket()); } else if (packet instanceof ClientboundLoginDisconnectPacket loginDisconnectPacket) { session.disconnect(loginDisconnectPacket.getReason()); } else if (packet instanceof ClientboundLoginCompressionPacket loginCompressionPacket) { - session.setCompressionThreshold(loginCompressionPacket.getThreshold(), false); + session.setCompression(loginCompressionPacket.getThreshold() >= 0 ? + new CompressionConfig(loginCompressionPacket.getThreshold(), new ZlibCompression(), false) : null); } } else if (protocol.getState() == ProtocolState.STATUS) { if (packet instanceof ClientboundStatusResponsePacket statusResponsePacket) { diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java index cc3bd0e93..ad2200821 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java @@ -10,7 +10,7 @@ import org.geysermc.mcprotocollib.network.Server; import org.geysermc.mcprotocollib.network.Session; import org.geysermc.mcprotocollib.network.crypt.AESEncryption; -import org.geysermc.mcprotocollib.network.crypt.PacketEncryption; +import org.geysermc.mcprotocollib.network.crypt.EncryptionConfig; import org.geysermc.mcprotocollib.network.packet.PacketHeader; import org.geysermc.mcprotocollib.network.packet.PacketProtocol; import org.geysermc.mcprotocollib.network.packet.PacketRegistry; @@ -177,11 +177,11 @@ public PacketRegistry getPacketRegistry() { return this.stateRegistry; } - protected PacketEncryption enableEncryption(Key key) { + protected EncryptionConfig enableEncryption(Key key) { try { - return new AESEncryption(key); + return new EncryptionConfig(new AESEncryption(key)); } catch (GeneralSecurityException e) { - throw new Error("Failed to enable protocol encryption.", e); + throw new IllegalStateException("Failed to enable protocol encryption.", e); } } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java index f63659ce4..d5108566a 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java @@ -8,6 +8,8 @@ import org.geysermc.mcprotocollib.auth.GameProfile; import org.geysermc.mcprotocollib.auth.SessionService; import org.geysermc.mcprotocollib.network.Session; +import org.geysermc.mcprotocollib.network.compression.CompressionConfig; +import org.geysermc.mcprotocollib.network.compression.ZlibCompression; import org.geysermc.mcprotocollib.network.event.session.ConnectedEvent; import org.geysermc.mcprotocollib.network.event.session.DisconnectingEvent; import org.geysermc.mcprotocollib.network.event.session.SessionAdapter; @@ -129,7 +131,7 @@ public void packetReceived(Session session, Packet packet) { } SecretKey key = keyPacket.getSecretKey(privateKey); - session.enableEncryption(protocol.enableEncryption(key)); + session.setEncryption(protocol.enableEncryption(key)); new Thread(new UserAuthTask(session, key)).start(); } else if (packet instanceof ServerboundLoginAcknowledgedPacket) { protocol.setState(ProtocolState.CONFIGURATION); @@ -202,7 +204,7 @@ public void packetReceived(Session session, Packet packet) { @Override public void packetSent(Session session, Packet packet) { if (packet instanceof ClientboundLoginCompressionPacket loginCompressionPacket) { - session.setCompressionThreshold(loginCompressionPacket.getThreshold(), true); + session.setCompression(new CompressionConfig(loginCompressionPacket.getThreshold(), new ZlibCompression(), true)); session.send(new ClientboundGameProfilePacket(session.getFlag(MinecraftConstants.PROFILE_KEY), true)); } } From 57595573546a228f8c7f4640d6a9e2d33ee057ad Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Wed, 11 Sep 2024 21:39:53 +0200 Subject: [PATCH 02/13] Update protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java Co-authored-by: chris --- .../main/java/org/geysermc/mcprotocollib/network/Session.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java index 1cab08efa..c0c39811e 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java @@ -184,7 +184,7 @@ public interface Session { void callPacketSent(Packet packet); /** - * Sets compression for this session. + * Sets the compression config for this session. * * @param compressionConfig the compression to compress with * or null to disable compression From d2fbb273ab4398f9cda7661b9de8ef1c44956470 Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Wed, 11 Sep 2024 21:40:01 +0200 Subject: [PATCH 03/13] Update protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java Co-authored-by: chris --- .../main/java/org/geysermc/mcprotocollib/network/Session.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java index c0c39811e..4479d8709 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java @@ -186,7 +186,7 @@ public interface Session { /** * Sets the compression config for this session. * - * @param compressionConfig the compression to compress with + * @param compressionConfig the compression to compress with, * or null to disable compression */ void setCompression(CompressionConfig compressionConfig); From 9a5a54507f167488910df0e223655dd419e33e50 Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Wed, 11 Sep 2024 21:40:06 +0200 Subject: [PATCH 04/13] Update protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java Co-authored-by: chris --- .../main/java/org/geysermc/mcprotocollib/network/Session.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java index 4479d8709..67968e393 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java @@ -194,7 +194,7 @@ public interface Session { /** * Sets encryption for this session. * - * @param encryptionConfig the encryption to encrypt with + * @param encryptionConfig the encryption to encrypt with, * or null to disable encryption * */ From 706786c8cbd4633192afb7594c458be804a4b1a4 Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Wed, 11 Sep 2024 21:41:11 +0200 Subject: [PATCH 05/13] Update Session.java --- .../main/java/org/geysermc/mcprotocollib/network/Session.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java index 67968e393..9e8c41654 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java @@ -200,7 +200,7 @@ public interface Session { */ void setEncryption(EncryptionConfig encryptionConfig); - /** + /** * Returns true if the session is connected. * * @return True if the session is connected. From 0d613347d8c187f76aaa085cfeb19dc0cf51b2bf Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Fri, 13 Sep 2024 00:55:53 +0200 Subject: [PATCH 06/13] Update protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java Co-authored-by: Konicai <71294714+Konicai@users.noreply.github.com> --- .../java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java index 4fc778ff9..b36fb6d7b 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java @@ -189,7 +189,7 @@ public void callPacketSent(Packet packet) { @Override public void setCompression(CompressionConfig compressionConfig) { if (this.channel == null) { - throw new IllegalStateException("You need to be connected to set the compression!"); + throw new IllegalStateException("You need to connect to set the compression!"); } channel.attr(NetworkConstants.COMPRESSION_ATTRIBUTE_KEY).set(compressionConfig); From 1dc95d8a3266c69b4d899d666d5d8ab8a49e14db Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Fri, 13 Sep 2024 11:46:10 +0200 Subject: [PATCH 07/13] Use temp var --- .../org/geysermc/mcprotocollib/protocol/ClientListener.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java index b857348bd..ee66b2ff4 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java @@ -99,8 +99,9 @@ public void packetReceived(Session session, Packet packet) { } else if (packet instanceof ClientboundLoginDisconnectPacket loginDisconnectPacket) { session.disconnect(loginDisconnectPacket.getReason()); } else if (packet instanceof ClientboundLoginCompressionPacket loginCompressionPacket) { - session.setCompression(loginCompressionPacket.getThreshold() >= 0 ? - new CompressionConfig(loginCompressionPacket.getThreshold(), new ZlibCompression(), false) : null); + int threshold = loginCompressionPacket.getThreshold(); + session.setCompression(threshold >= 0 ? + new CompressionConfig(threshold, new ZlibCompression(), false) : null); } } else if (protocol.getState() == ProtocolState.STATUS) { if (packet instanceof ClientboundStatusResponsePacket statusResponsePacket) { From ff8015faaae933b91bdd094b27ca18addfd26327 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Fri, 13 Sep 2024 11:54:38 +0200 Subject: [PATCH 08/13] Add nullable annotation --- .../java/org/geysermc/mcprotocollib/network/Session.java | 4 ++-- .../org/geysermc/mcprotocollib/network/tcp/TcpSession.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java index 9e8c41654..054c76ff1 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java @@ -189,7 +189,7 @@ public interface Session { * @param compressionConfig the compression to compress with, * or null to disable compression */ - void setCompression(CompressionConfig compressionConfig); + void setCompression(@Nullable CompressionConfig compressionConfig); /** * Sets encryption for this session. @@ -198,7 +198,7 @@ public interface Session { * or null to disable encryption * */ - void setEncryption(EncryptionConfig encryptionConfig); + void setEncryption(@Nullable EncryptionConfig encryptionConfig); /** * Returns true if the session is connected. diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java index b36fb6d7b..4fb7641b8 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java @@ -187,7 +187,7 @@ public void callPacketSent(Packet packet) { } @Override - public void setCompression(CompressionConfig compressionConfig) { + public void setCompression(@Nullable CompressionConfig compressionConfig) { if (this.channel == null) { throw new IllegalStateException("You need to connect to set the compression!"); } @@ -196,9 +196,9 @@ public void setCompression(CompressionConfig compressionConfig) { } @Override - public void setEncryption(EncryptionConfig encryptionConfig) { + public void setEncryption(@Nullable EncryptionConfig encryptionConfig) { if (channel == null) { - throw new IllegalStateException("You need to connect to enable encryption!"); + throw new IllegalStateException("You need to connect to set the encryption!"); } channel.attr(NetworkConstants.ENCRYPTION_ATTRIBUTE_KEY).set(encryptionConfig); From 217ad431ba88c39b7bb53fc5dcce1e1dff611a79 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Fri, 13 Sep 2024 21:33:34 +0200 Subject: [PATCH 09/13] enable -> create --- .../org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java index ad2200821..9ee33f150 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java @@ -181,7 +181,7 @@ protected EncryptionConfig enableEncryption(Key key) { try { return new EncryptionConfig(new AESEncryption(key)); } catch (GeneralSecurityException e) { - throw new IllegalStateException("Failed to enable protocol encryption.", e); + throw new IllegalStateException("Failed to create protocol encryption.", e); } } From 43fbdaa7130fd94ca0713e79401e48d16b4362a6 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Sat, 14 Sep 2024 00:46:11 +0200 Subject: [PATCH 10/13] Rename encryption method --- .../org/geysermc/mcprotocollib/protocol/ClientListener.java | 2 +- .../org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java | 2 +- .../org/geysermc/mcprotocollib/protocol/ServerListener.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java index ee66b2ff4..6b9ead048 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java @@ -93,7 +93,7 @@ public void packetReceived(Session session, Packet packet) { } session.send(new ServerboundKeyPacket(helloPacket.getPublicKey(), key, helloPacket.getChallenge())); - session.setEncryption(protocol.enableEncryption(key)); + session.setEncryption(protocol.createEncryption(key)); } else if (packet instanceof ClientboundGameProfilePacket) { session.send(new ServerboundLoginAcknowledgedPacket()); } else if (packet instanceof ClientboundLoginDisconnectPacket loginDisconnectPacket) { diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java index 9ee33f150..435c0113d 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java @@ -177,7 +177,7 @@ public PacketRegistry getPacketRegistry() { return this.stateRegistry; } - protected EncryptionConfig enableEncryption(Key key) { + protected EncryptionConfig createEncryption(Key key) { try { return new EncryptionConfig(new AESEncryption(key)); } catch (GeneralSecurityException e) { diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java index d5108566a..fd8c85f78 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java @@ -131,7 +131,7 @@ public void packetReceived(Session session, Packet packet) { } SecretKey key = keyPacket.getSecretKey(privateKey); - session.setEncryption(protocol.enableEncryption(key)); + session.setEncryption(protocol.createEncryption(key)); new Thread(new UserAuthTask(session, key)).start(); } else if (packet instanceof ServerboundLoginAcknowledgedPacket) { protocol.setState(ProtocolState.CONFIGURATION); From 3d5ae58a9c3f5698bf6e13eadbaadeb0e482ddcd Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Sat, 14 Sep 2024 00:48:36 +0200 Subject: [PATCH 11/13] Fix compression id --- .../org/geysermc/mcprotocollib/network/NetworkConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/NetworkConstants.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/NetworkConstants.java index 6b7cd80de..c29889051 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/NetworkConstants.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/NetworkConstants.java @@ -5,6 +5,6 @@ import org.geysermc.mcprotocollib.network.crypt.EncryptionConfig; public class NetworkConstants { - public static final AttributeKey COMPRESSION_ATTRIBUTE_KEY = AttributeKey.valueOf("compression_threshold"); + public static final AttributeKey COMPRESSION_ATTRIBUTE_KEY = AttributeKey.valueOf("compression"); public static final AttributeKey ENCRYPTION_ATTRIBUTE_KEY = AttributeKey.valueOf("encryption"); } From f9f0de2f7f2d6d868b93d3b1a9585c62a929b5f4 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Sat, 14 Sep 2024 00:52:34 +0200 Subject: [PATCH 12/13] Fix -1 compression in ServerListener --- .../org/geysermc/mcprotocollib/protocol/ServerListener.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java index fd8c85f78..659c0e6f5 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java @@ -204,7 +204,9 @@ public void packetReceived(Session session, Packet packet) { @Override public void packetSent(Session session, Packet packet) { if (packet instanceof ClientboundLoginCompressionPacket loginCompressionPacket) { - session.setCompression(new CompressionConfig(loginCompressionPacket.getThreshold(), new ZlibCompression(), true)); + int threshold = loginCompressionPacket.getThreshold(); + session.setCompression(threshold >= 0 ? + new CompressionConfig(threshold, new ZlibCompression(), true) : null); session.send(new ClientboundGameProfilePacket(session.getFlag(MinecraftConstants.PROFILE_KEY), true)); } } From 7c48cb7e2041a60639fb2b8d25d2d9587631c90f Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Sat, 14 Sep 2024 12:49:53 +0200 Subject: [PATCH 13/13] Compress and encrypt in unit tests --- .../protocol/example/MinecraftProtocolTest.java | 10 ++++++---- .../mcprotocollib/network/tcp/TcpSession.java | 6 ++++++ .../mcprotocollib/protocol/MinecraftConstants.java | 9 +++++++-- .../mcprotocollib/protocol/ServerListener.java | 11 ++++++----- .../protocol/MinecraftProtocolTest.java | 12 ++++++------ 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/example/src/main/java/org/geysermc/mcprotocollib/protocol/example/MinecraftProtocolTest.java b/example/src/main/java/org/geysermc/mcprotocollib/protocol/example/MinecraftProtocolTest.java index b3e7e93f7..71250757d 100644 --- a/example/src/main/java/org/geysermc/mcprotocollib/protocol/example/MinecraftProtocolTest.java +++ b/example/src/main/java/org/geysermc/mcprotocollib/protocol/example/MinecraftProtocolTest.java @@ -48,7 +48,8 @@ public class MinecraftProtocolTest { private static final Logger log = LoggerFactory.getLogger(MinecraftProtocolTest.class); private static final boolean SPAWN_SERVER = true; - private static final boolean VERIFY_USERS = false; + private static final boolean ENCRYPT_CONNECTION = true; + private static final boolean SHOULD_AUTHENTICATE = false; private static final String HOST = "127.0.0.1"; private static final int PORT = 25565; private static final ProxyInfo PROXY = null; @@ -63,7 +64,8 @@ public static void main(String[] args) { Server server = new TcpServer(HOST, PORT, MinecraftProtocol::new); server.setGlobalFlag(MinecraftConstants.SESSION_SERVICE_KEY, sessionService); - server.setGlobalFlag(MinecraftConstants.VERIFY_USERS_KEY, VERIFY_USERS); + server.setGlobalFlag(MinecraftConstants.ENCRYPT_CONNECTION, ENCRYPT_CONNECTION); + server.setGlobalFlag(MinecraftConstants.SHOULD_AUTHENTICATE, SHOULD_AUTHENTICATE); server.setGlobalFlag(MinecraftConstants.SERVER_INFO_BUILDER_KEY, session -> new ServerStatusInfo( Component.text("Hello world!"), @@ -100,7 +102,7 @@ public static void main(String[] args) { )) ); - server.setGlobalFlag(MinecraftConstants.SERVER_COMPRESSION_THRESHOLD, 100); + server.setGlobalFlag(MinecraftConstants.SERVER_COMPRESSION_THRESHOLD, 256); server.addListener(new ServerAdapter() { @Override public void serverClosed(ServerClosedEvent event) { @@ -177,7 +179,7 @@ private static void status() { private static void login() { MinecraftProtocol protocol; - if (VERIFY_USERS) { + if (SHOULD_AUTHENTICATE) { StepFullJavaSession.FullJavaSession fullJavaSession; try { fullJavaSession = MinecraftAuth.JAVA_CREDENTIALS_LOGIN.getFromInput( diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java index 4fb7641b8..8a1ee37cb 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java @@ -24,6 +24,8 @@ import org.geysermc.mcprotocollib.network.event.session.SessionListener; import org.geysermc.mcprotocollib.network.packet.Packet; import org.geysermc.mcprotocollib.network.packet.PacketProtocol; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.net.SocketAddress; import java.util.Collections; @@ -35,6 +37,8 @@ import java.util.concurrent.TimeoutException; public abstract class TcpSession extends SimpleChannelInboundHandler implements Session { + private static final Logger log = LoggerFactory.getLogger(TcpSession.class); + /** * Controls whether non-priority packets are handled in a separate event loop */ @@ -192,6 +196,7 @@ public void setCompression(@Nullable CompressionConfig compressionConfig) { throw new IllegalStateException("You need to connect to set the compression!"); } + log.debug("Setting compression for session {}", this); channel.attr(NetworkConstants.COMPRESSION_ATTRIBUTE_KEY).set(compressionConfig); } @@ -201,6 +206,7 @@ public void setEncryption(@Nullable EncryptionConfig encryptionConfig) { throw new IllegalStateException("You need to connect to set the encryption!"); } + log.debug("Setting encryption for session {}", this); channel.attr(NetworkConstants.ENCRYPTION_ATTRIBUTE_KEY).set(encryptionConfig); } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java index 19e59e3f2..40b0b3165 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftConstants.java @@ -63,9 +63,14 @@ public final class MinecraftConstants { // Server Key Constants /** - * Session flag for determining whether to verify users. Server only. + * Session flag for determining whether to encrypt the connection. Server only. */ - public static final Flag VERIFY_USERS_KEY = new Flag<>("verify-users", Boolean.class); + public static final Flag ENCRYPT_CONNECTION = new Flag<>("encrypt-connection", Boolean.class); + + /** + * Session flag for determining whether to authenticate users with the session service. Server only. + */ + public static final Flag SHOULD_AUTHENTICATE = new Flag<>("should-authenticate", Boolean.class); /** * Session flag for determining whether to accept transferred connections. Server only. diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java index 659c0e6f5..cd1d7a6c5 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java @@ -118,10 +118,10 @@ public void packetReceived(Session session, Packet packet) { if (packet instanceof ServerboundHelloPacket helloPacket) { this.username = helloPacket.getUsername(); - if (session.getFlag(MinecraftConstants.VERIFY_USERS_KEY, true)) { - session.send(new ClientboundHelloPacket(SERVER_ID, KEY_PAIR.getPublic(), this.challenge, true)); + if (session.getFlag(MinecraftConstants.ENCRYPT_CONNECTION, true)) { + session.send(new ClientboundHelloPacket(SERVER_ID, KEY_PAIR.getPublic(), this.challenge, session.getFlag(MinecraftConstants.SHOULD_AUTHENTICATE, true))); } else { - new Thread(new UserAuthTask(session, null)).start(); + new Thread(new UserAuthTask(session, false, null)).start(); } } else if (packet instanceof ServerboundKeyPacket keyPacket) { PrivateKey privateKey = KEY_PAIR.getPrivate(); @@ -132,7 +132,7 @@ public void packetReceived(Session session, Packet packet) { SecretKey key = keyPacket.getSecretKey(privateKey); session.setEncryption(protocol.createEncryption(key)); - new Thread(new UserAuthTask(session, key)).start(); + new Thread(new UserAuthTask(session, session.getFlag(MinecraftConstants.SHOULD_AUTHENTICATE, true), key)).start(); } else if (packet instanceof ServerboundLoginAcknowledgedPacket) { protocol.setState(ProtocolState.CONFIGURATION); @@ -224,12 +224,13 @@ public void disconnecting(DisconnectingEvent event) { @RequiredArgsConstructor private class UserAuthTask implements Runnable { private final Session session; + private final boolean shouldAuthenticate; private final SecretKey key; @Override public void run() { GameProfile profile; - if (this.key != null) { + if (this.shouldAuthenticate && this.key != null) { SessionService sessionService = this.session.getFlag(MinecraftConstants.SESSION_SERVICE_KEY, new SessionService()); try { profile = sessionService.getProfileByServer(username, SessionService.getServerId(SERVER_ID, KEY_PAIR.getPublic(), this.key)); diff --git a/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocolTest.java b/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocolTest.java index 49a45c0b9..2dff91c35 100644 --- a/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocolTest.java +++ b/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocolTest.java @@ -27,7 +27,6 @@ import java.util.concurrent.CountDownLatch; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.geysermc.mcprotocollib.protocol.MinecraftConstants.*; import static org.junit.jupiter.api.Assertions.*; public class MinecraftProtocolTest { @@ -49,10 +48,11 @@ public class MinecraftProtocolTest { @BeforeAll public static void setupServer() { server = new TcpServer(HOST, PORT, MinecraftProtocol::new); - server.setGlobalFlag(VERIFY_USERS_KEY, false); - server.setGlobalFlag(SERVER_COMPRESSION_THRESHOLD, 100); - server.setGlobalFlag(SERVER_INFO_BUILDER_KEY, session -> SERVER_INFO); - server.setGlobalFlag(SERVER_LOGIN_HANDLER_KEY, session -> { + server.setGlobalFlag(MinecraftConstants.ENCRYPT_CONNECTION, true); + server.setGlobalFlag(MinecraftConstants.SHOULD_AUTHENTICATE, false); + server.setGlobalFlag(MinecraftConstants.SERVER_COMPRESSION_THRESHOLD, 256); + server.setGlobalFlag(MinecraftConstants.SERVER_INFO_BUILDER_KEY, session -> SERVER_INFO); + server.setGlobalFlag(MinecraftConstants.SERVER_LOGIN_HANDLER_KEY, session -> { // Seems like in this setup the server can reply too quickly to ServerboundFinishConfigurationPacket // before the client can transition CONFIGURATION -> GAME. There is probably something wrong here and this is just a band-aid. try { @@ -79,7 +79,7 @@ public void testStatus() throws InterruptedException { Session session = new TcpClientSession(HOST, PORT, new MinecraftProtocol()); try { ServerInfoHandlerTest handler = new ServerInfoHandlerTest(); - session.setFlag(SERVER_INFO_HANDLER_KEY, handler); + session.setFlag(MinecraftConstants.SERVER_INFO_HANDLER_KEY, handler); session.addListener(new DisconnectListener()); session.connect();