From 5ee928ac87150b34ea6d49c52ea97d5fabdc6e7b Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Tue, 24 Oct 2023 21:02:28 +0200 Subject: [PATCH] debug: network detaching This is useful if you want to stop the server or just analyse what is going on without having the server informed over your actions. --- .../network/client/test/TestNetwork.kt | 6 ++ .../network/network/client/ClientNetwork.kt | 4 +- .../network/client/netty/NettyClient.kt | 62 +++++++++++-------- .../packets/s2c/common/CompressionS2CP.kt | 2 +- .../commands/connection/DebugCommand.kt | 5 +- 5 files changed, 49 insertions(+), 30 deletions(-) diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/protocol/network/network/client/test/TestNetwork.kt b/src/integration-test/kotlin/de/bixilon/minosoft/protocol/network/network/client/test/TestNetwork.kt index 2caddf5ab..0e8d26d7b 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/protocol/network/network/client/test/TestNetwork.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/protocol/network/network/client/test/TestNetwork.kt @@ -41,6 +41,12 @@ class TestNetwork : ClientNetwork { encrypted = true } + override fun setupCompression(threshold: Int) { + this.compressionThreshold = threshold + } + + override fun detach() = Unit + override fun pauseSending(pause: Boolean) = Unit override fun send(packet: C2SPacket) { diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/network/client/ClientNetwork.kt b/src/main/java/de/bixilon/minosoft/protocol/network/network/client/ClientNetwork.kt index d96173d63..8f7aa2776 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/network/client/ClientNetwork.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/network/network/client/ClientNetwork.kt @@ -24,12 +24,14 @@ interface ClientNetwork { var state: ProtocolStates var receive: Boolean - var compressionThreshold: Int + val compressionThreshold: Int fun connect(address: ServerAddress, native: Boolean) fun disconnect() + fun detach() fun setupEncryption(encrypt: Cipher, decrypt: Cipher) + fun setupCompression(threshold: Int) fun pauseSending(pause: Boolean) diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/network/client/netty/NettyClient.kt b/src/main/java/de/bixilon/minosoft/protocol/network/network/client/netty/NettyClient.kt index 19470f346..73e8e5614 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/network/client/netty/NettyClient.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/network/network/client/netty/NettyClient.kt @@ -55,37 +55,12 @@ class NettyClient( private set override var state by observed(ProtocolStates.HANDSHAKE) override var compressionThreshold = -1 - set(value) { - field = value - val channel = channel ?: return - val pipeline = channel.pipeline() - if (value < 0) { - // disable - if (pipeline.get(PacketDeflater.NAME) != null) { - channel.pipeline().remove(PacketDeflater.NAME) - } - if (pipeline.get(PacketInflater.NAME) != null) { - channel.pipeline().remove(PacketInflater.NAME) - } - } else { - // enable or update - val inflater = channel.pipeline()[PacketInflater.NAME]?.nullCast() - if (inflater == null) { - channel.pipeline().addAfter(LengthDecoder.NAME, PacketInflater.NAME, PacketInflater(connection.version!!.maxPacketLength)) - } - val deflater = channel.pipeline()[PacketDeflater.NAME]?.nullCast() - if (deflater != null) { - deflater.threshold = value - } else { - channel.pipeline().addAfter(LengthEncoder.NAME, PacketDeflater.NAME, PacketDeflater(value)) - } - } - } override var encrypted: Boolean = false private set private var channel: Channel? = null private val packetQueue: MutableList = mutableListOf() // Used for pause sending private var sendingPaused = false + private var detached = false override var receive = true set(value) { channel?.config()?.isAutoRead = value @@ -119,6 +94,32 @@ class NettyClient( encrypted = true } + override fun setupCompression(threshold: Int) { + val channel = channel ?: return + val pipeline = channel.pipeline() + if (threshold < 0) { + // disable + if (pipeline.get(PacketDeflater.NAME) != null) { + channel.pipeline().remove(PacketDeflater.NAME) + } + if (pipeline.get(PacketInflater.NAME) != null) { + channel.pipeline().remove(PacketInflater.NAME) + } + } else { + // enable or update + val inflater = channel.pipeline()[PacketInflater.NAME]?.nullCast() + if (inflater == null) { + channel.pipeline().addAfter(LengthDecoder.NAME, PacketInflater.NAME, PacketInflater(connection.version!!.maxPacketLength)) + } + val deflater = channel.pipeline()[PacketDeflater.NAME]?.nullCast() + if (deflater != null) { + deflater.threshold = threshold + } else { + channel.pipeline().addAfter(LengthEncoder.NAME, PacketDeflater.NAME, PacketDeflater(threshold)) + } + } + } + override fun disconnect() { channel?.close() encrypted = false @@ -127,6 +128,11 @@ class NettyClient( connected = false } + override fun detach() { + detached = true + channel?.close() + } + override fun pauseSending(pause: Boolean) { this.sendingPaused = pause if (!sendingPaused) { @@ -139,11 +145,12 @@ class NettyClient( } override fun send(packet: C2SPacket) { - val channel = getChannel() ?: return + if (detached) return if (sendingPaused) { packetQueue += packet return } + val channel = getChannel() ?: return packet.log((connection.nullCast()?.profiles?.other ?: OtherProfileManager.selected).log.reducedProtocolLog) channel.writeAndFlush(packet) @@ -165,6 +172,7 @@ class NettyClient( override fun channelInactive(context: ChannelHandlerContext) { Log.log(LogMessageType.NETWORK, LogLevels.VERBOSE) { "Connection closed ($address)" } + if (detached) return connected = false } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/common/CompressionS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/common/CompressionS2CP.kt index c701dee4e..47559a9bd 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/common/CompressionS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/common/CompressionS2CP.kt @@ -24,7 +24,7 @@ class CompressionS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { override fun handle(connection: PlayConnection) { - connection.network.compressionThreshold = threshold + connection.network.setupCompression(threshold) } override fun log(reducedLog: Boolean) { diff --git a/src/main/java/de/bixilon/minosoft/terminal/commands/connection/DebugCommand.kt b/src/main/java/de/bixilon/minosoft/terminal/commands/connection/DebugCommand.kt index 66275c477..86c4d4679 100644 --- a/src/main/java/de/bixilon/minosoft/terminal/commands/connection/DebugCommand.kt +++ b/src/main/java/de/bixilon/minosoft/terminal/commands/connection/DebugCommand.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -22,6 +22,9 @@ import de.bixilon.minosoft.util.KUtil.format object DebugCommand : ConnectionCommand { override var node = LiteralNode("debug") .addChild(LiteralNode("allowFly", executor = { it.fly() }, allowArguments = true).addChild(ArgumentNode("value", BooleanParser, executable = true))) + .addChild(LiteralNode("network").addChild( + LiteralNode("detach", executor = { it.connection.network.detach(); it.connection.util.sendDebugMessage("Now you are alone on the wire...") }), + )) private fun CommandStack.fly() {