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.
This commit is contained in:
Moritz Zwerger 2023-10-24 21:02:28 +02:00
parent 2c732f44d0
commit 5ee928ac87
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 49 additions and 30 deletions

View File

@ -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) {

View File

@ -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)

View File

@ -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<PacketInflater>()
if (inflater == null) {
channel.pipeline().addAfter(LengthDecoder.NAME, PacketInflater.NAME, PacketInflater(connection.version!!.maxPacketLength))
}
val deflater = channel.pipeline()[PacketDeflater.NAME]?.nullCast<PacketDeflater>()
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<C2SPacket> = 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<PacketInflater>()
if (inflater == null) {
channel.pipeline().addAfter(LengthDecoder.NAME, PacketInflater.NAME, PacketInflater(connection.version!!.maxPacketLength))
}
val deflater = channel.pipeline()[PacketDeflater.NAME]?.nullCast<PacketDeflater>()
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<PlayConnection>()?.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
}

View File

@ -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) {

View File

@ -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() {