restore command stack on error

This should fix some errors with broken signature on commands
This commit is contained in:
Bixilon 2023-05-23 19:33:16 +02:00
parent 553084744f
commit 6e2cebf7a6
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 34 additions and 12 deletions

View File

@ -51,7 +51,7 @@ class MsgCommandIT {
fun validateStack() {
var stack: CommandStack? = null
val node = createNode { stack = it.copy() }
val node = createNode { stack = it.fork() }
node.execute("msg Bixilon hi there!")
assertEquals(stack!!["msg"], "msg")
@ -70,7 +70,7 @@ class MsgCommandIT {
fun redirectStack() {
var stack: CommandStack? = null
val node = createNode { stack = it.copy() }
val node = createNode { stack = it.fork() }
node.execute("redirect Bixilon hi there!")

View File

@ -51,7 +51,7 @@ class TPCommandIT {
fun relativeStack() {
var stack: CommandStack? = null
val node = createNode { stack = it.copy() }
val node = createNode { stack = it.fork() }
node.execute("tp @s ~ ~10 ~")

View File

@ -41,7 +41,7 @@ abstract class CommandNode(
val stackSize = stack.size
var childError: Throwable? = null
var errorStack = -1
var errorStack: CommandStack? = null
for (child in (redirect?.children ?: children)) {
reader.pointer = pointer
@ -53,12 +53,13 @@ abstract class CommandNode(
}
return
} catch (error: Throwable) {
if (stack.size > errorStack) {
errorStack = stack.size
if (errorStack == null || stack.size > errorStack.size) {
errorStack = stack.fork()
childError = error
}
}
}
errorStack?.let { stack.join(it) }
throw childError ?: return
}
@ -71,7 +72,7 @@ abstract class CommandNode(
val stackSize = stack.size
var childError: Throwable? = null
var errorStack = -1
var errorStack: CommandStack? = null
var parserSucceeds = 0
for (child in (redirect?.children ?: children)) {
@ -92,8 +93,8 @@ abstract class CommandNode(
return childSuggestions
} catch (error: Throwable) {
if (stack.size > errorStack) {
errorStack = stack.size
if (errorStack == null || stack.size > errorStack.size) {
errorStack = stack.fork()
childError = error
}
}
@ -103,6 +104,8 @@ abstract class CommandNode(
if (!reader.canPeek(pointer) && executable) {
return emptyList()
}
errorStack?.let { stack.join(it) }
throw childError ?: return emptyList()
}

View File

@ -26,11 +26,14 @@ import java.time.Instant
class CommandStack(
connection: PlayConnection? = null,
val print: PrintTarget = SystemPrintTarget,
print: PrintTarget = SystemPrintTarget,
) {
private val stack: MutableList<CommandStackEntry> = mutableListOf()
val size: Int get() = stack.size
var print = print
private set
var executor: Entity? = null
lateinit var connection: PlayConnection
@ -70,7 +73,7 @@ class CommandStack(
}
fun copy(): CommandStack {
fun fork(): CommandStack {
val stack = CommandStack(null, print)
stack.stack += this.stack
stack.executor = this.executor
@ -80,4 +83,14 @@ class CommandStack(
return stack
}
fun join(stack: CommandStack) {
this.stack.clear()
this.stack += stack.stack
this.print = stack.print
this.executor = stack.executor
if (stack::connection.isInitialized) {
this.connection = stack.connection
}
}
}

View File

@ -34,6 +34,7 @@ import de.bixilon.minosoft.protocol.packets.c2s.play.chat.ChatMessageC2SP
import de.bixilon.minosoft.protocol.packets.c2s.play.chat.CommandC2SP
import de.bixilon.minosoft.protocol.packets.c2s.play.chat.SignedChatMessageC2SP
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
import java.security.SecureRandom
import java.time.Instant
@ -72,7 +73,11 @@ class ConnectionUtil(
val keyManagement = connection.player.keyManagement
keyManagement.acquire()
try {
val key = keyManagement.key ?: return connection.sendPacket(SignedChatMessageC2SP(message.encodeNetwork(), time = Instant.EPOCH, salt = 0, signature = null, false, Acknowledgement.EMPTY))
val key = keyManagement.key
if (key == null) {
connection.sendPacket(SignedChatMessageC2SP(message.encodeNetwork(), time = Instant.EPOCH, salt = 0, signature = null, false, Acknowledgement.EMPTY))
return
}
sendSignedMessage(key, trimmed)
} finally {
keyManagement.release()
@ -104,6 +109,7 @@ class ConnectionUtil(
ChatUtil.validateChatMessage(connection, trimmed)
if (stack.size == 0) {
connection.sendPacket(CommandC2SP(trimmed, Instant.EPOCH, 0L, emptyMap(), false, Acknowledgement.EMPTY)) // TODO: remove
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Command $trimmed failed to pars!" }
throw IllegalArgumentException("Empty command stack! Did the command fail to parse?")
}
val time = Instant.now()