mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 20:05:02 -04:00
connection commands
This commit is contained in:
parent
30bfd53466
commit
f3dc3219a0
@ -19,4 +19,4 @@ abstract class ReaderError(
|
||||
val reader: CommandReader,
|
||||
val start: Int,
|
||||
val end: Int,
|
||||
) : Exception("Error at $start-$end: ${reader.string} (at ${reader.string.substring(start, end)}")
|
||||
) : Exception("Error at $start-$end: ${reader.string} (at ${reader.string.substring(start, end)})")
|
||||
|
@ -83,4 +83,8 @@ abstract class CommandNode(
|
||||
}
|
||||
return suggestions
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
children.clear()
|
||||
}
|
||||
}
|
||||
|
@ -16,14 +16,19 @@ package de.bixilon.minosoft.commands.nodes
|
||||
import de.bixilon.minosoft.commands.nodes.builder.CommandNodeBuilder
|
||||
import de.bixilon.minosoft.commands.stack.CommandStack
|
||||
import de.bixilon.minosoft.commands.util.CommandReader
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||
|
||||
class RootNode : CommandNode {
|
||||
|
||||
constructor() : super(false, null)
|
||||
constructor(builder: CommandNodeBuilder) : super(builder.executable, null)
|
||||
|
||||
fun execute(command: String) {
|
||||
execute(CommandReader(command), CommandStack())
|
||||
fun execute(command: String, connection: PlayConnection? = null) {
|
||||
val stack = CommandStack()
|
||||
if (connection != null) {
|
||||
stack.connection = connection
|
||||
}
|
||||
execute(CommandReader(command), stack)
|
||||
}
|
||||
|
||||
fun getSuggestions(command: String): List<Any?> {
|
||||
|
@ -21,6 +21,7 @@ import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.pro
|
||||
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.rotation.YawRotation
|
||||
import de.bixilon.minosoft.commands.parser.minecraft.target.targets.selector.properties.sort.SortProperty
|
||||
|
||||
// See https://minecraft.fandom.com/wiki/Target_selectors
|
||||
object TargetProperties {
|
||||
val properties: MutableMap<String, TargetPropertyFactory<*>> = mutableMapOf()
|
||||
|
||||
|
@ -15,12 +15,14 @@ package de.bixilon.minosoft.commands.stack
|
||||
|
||||
import de.bixilon.kutil.cast.CastUtil.nullCast
|
||||
import de.bixilon.minosoft.data.entities.entities.Entity
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||
|
||||
class CommandStack {
|
||||
private val stack: MutableList<StackEntry> = mutableListOf()
|
||||
val size: Int get() = stack.size
|
||||
|
||||
var executor: Entity? = null
|
||||
lateinit var connection: PlayConnection
|
||||
|
||||
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
|
||||
inline operator fun <reified T> get(name: String): T? {
|
||||
|
@ -209,7 +209,7 @@ open class CommandReader(val string: String) {
|
||||
return null
|
||||
}
|
||||
val string = string.substring(pointer, string.length)
|
||||
pointer = string.length
|
||||
pointer = this.string.length
|
||||
return string
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ import de.bixilon.minosoft.protocol.packets.c2s.handshaking.HandshakeC2SP
|
||||
import de.bixilon.minosoft.protocol.packets.c2s.login.StartC2SP
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolStates
|
||||
import de.bixilon.minosoft.terminal.RunConfiguration
|
||||
import de.bixilon.minosoft.terminal.cli.CLI
|
||||
import de.bixilon.minosoft.util.ServerAddress
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
@ -119,6 +120,9 @@ class PlayConnection(
|
||||
assetsManager.unload()
|
||||
state = PlayConnectionStates.DISCONNECTED
|
||||
ACTIVE_CONNECTIONS -= this
|
||||
if (CLI.connection === this) {
|
||||
CLI.connection = null
|
||||
}
|
||||
}
|
||||
}
|
||||
network::state.observe(this) {
|
||||
@ -131,6 +135,10 @@ class PlayConnection(
|
||||
ProtocolStates.PLAY -> {
|
||||
state = PlayConnectionStates.JOINING
|
||||
|
||||
if (CLI.connection == null) {
|
||||
CLI.connection = this
|
||||
}
|
||||
|
||||
registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
|
||||
val additionalPrefix = when (it.type.position) {
|
||||
ChatTextPositions.SYSTEM -> "[SYSTEM] "
|
||||
|
@ -14,16 +14,38 @@
|
||||
package de.bixilon.minosoft.terminal.cli
|
||||
|
||||
import de.bixilon.kutil.latch.CountUpAndDownLatch
|
||||
import de.bixilon.kutil.watcher.DataWatcher.Companion.observe
|
||||
import de.bixilon.kutil.watcher.DataWatcher.Companion.watched
|
||||
import de.bixilon.minosoft.ShutdownReasons
|
||||
import de.bixilon.minosoft.commands.nodes.RootNode
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||
import de.bixilon.minosoft.terminal.commands.Commands
|
||||
import de.bixilon.minosoft.terminal.commands.ConnectionCommand
|
||||
import de.bixilon.minosoft.util.ShutdownManager
|
||||
import org.jline.reader.*
|
||||
import org.jline.terminal.Terminal
|
||||
import org.jline.terminal.TerminalBuilder
|
||||
|
||||
object CLI {
|
||||
var connection: PlayConnection? = null
|
||||
var connection: PlayConnection? by watched(null)
|
||||
private val ROOT_NODE = RootNode()
|
||||
|
||||
init {
|
||||
register()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun register() {
|
||||
ROOT_NODE.clear()
|
||||
val connection = this.connection
|
||||
|
||||
for (command in Commands.COMMANDS) {
|
||||
if (command is ConnectionCommand && connection == null) {
|
||||
continue
|
||||
}
|
||||
ROOT_NODE.addChild(command.node)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun startThread(latch: CountUpAndDownLatch) {
|
||||
@ -41,6 +63,9 @@ object CLI {
|
||||
.completer(NodeCompleter)
|
||||
.build()
|
||||
|
||||
this::connection.observe(this) { register() }
|
||||
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
val line: String = reader.readLine().removeDuplicatedWhitespaces()
|
||||
@ -48,7 +73,7 @@ object CLI {
|
||||
continue
|
||||
}
|
||||
terminal.flush()
|
||||
Commands.ROOT_NODE.execute(line)
|
||||
ROOT_NODE.execute(line, connection)
|
||||
} catch (exception: UserInterruptException) {
|
||||
ShutdownManager.shutdown(reason = ShutdownReasons.ALL_FINE)
|
||||
} catch (exception: Throwable) {
|
||||
@ -64,7 +89,7 @@ object CLI {
|
||||
object NodeCompleter : Completer {
|
||||
|
||||
override fun complete(reader: LineReader, line: ParsedLine, candidates: MutableList<Candidate>) {
|
||||
val suggestions = Commands.ROOT_NODE.getSuggestions(line.line())
|
||||
val suggestions = ROOT_NODE.getSuggestions(line.line())
|
||||
for (suggestion in suggestions) {
|
||||
candidates += Candidate(suggestion.toString())
|
||||
}
|
||||
|
@ -16,6 +16,5 @@ package de.bixilon.minosoft.terminal.commands
|
||||
import de.bixilon.minosoft.commands.nodes.LiteralNode
|
||||
|
||||
interface Command {
|
||||
|
||||
fun build(): LiteralNode
|
||||
var node: LiteralNode
|
||||
}
|
||||
|
@ -13,14 +13,9 @@
|
||||
|
||||
package de.bixilon.minosoft.terminal.commands
|
||||
|
||||
import de.bixilon.minosoft.commands.nodes.RootNode
|
||||
|
||||
object Commands {
|
||||
val ROOT_NODE = RootNode()
|
||||
.register(HelpCommand)
|
||||
|
||||
fun RootNode.register(command: Command): RootNode {
|
||||
this.addChild(command.build())
|
||||
return this
|
||||
}
|
||||
val COMMANDS: List<Command> = listOf(
|
||||
HelpCommand,
|
||||
SayCommand,
|
||||
)
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.terminal.commands
|
||||
|
||||
interface ConnectionCommand : Command
|
@ -20,11 +20,8 @@ import de.bixilon.minosoft.commands.nodes.LiteralNode
|
||||
import de.bixilon.minosoft.commands.parser.minosoft.enums.EnumParser
|
||||
|
||||
object HelpCommand : Command {
|
||||
|
||||
override fun build(): LiteralNode {
|
||||
return LiteralNode("help", setOf("?"), executor = { printHelp() })
|
||||
.addChild(ArgumentNode("subcommand", parser = EnumParser(HelpCommands), executor = { printHelp(it["subcommand"]!!) }))
|
||||
}
|
||||
override var node: LiteralNode = LiteralNode("help", setOf("?"), executor = { printHelp() })
|
||||
.addChild(ArgumentNode("subcommand", parser = EnumParser(HelpCommands), executor = { printHelp(it["subcommand"]!!) }))
|
||||
|
||||
fun printHelp() {
|
||||
println("-------------- Minosoft help --------------")
|
||||
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.terminal.commands
|
||||
|
||||
import de.bixilon.minosoft.commands.nodes.ArgumentNode
|
||||
import de.bixilon.minosoft.commands.nodes.LiteralNode
|
||||
import de.bixilon.minosoft.commands.parser.brigadier.string.StringParser
|
||||
|
||||
object SayCommand : ConnectionCommand {
|
||||
override var node = LiteralNode("say", setOf("chat", "send", "write"))
|
||||
.addChild(ArgumentNode("message", StringParser(StringParser.StringModes.GREEDY), executor = {
|
||||
it.connection.util.sendChatMessage(it.get<String>("message")!!)
|
||||
}))
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user