diff --git a/src/main/java/de/bixilon/minosoft/terminal/commands/Commands.kt b/src/main/java/de/bixilon/minosoft/terminal/commands/Commands.kt
index 111299e9e..b2f8f938a 100644
--- a/src/main/java/de/bixilon/minosoft/terminal/commands/Commands.kt
+++ b/src/main/java/de/bixilon/minosoft/terminal/commands/Commands.kt
@@ -23,5 +23,7 @@ object Commands {
ConnectionManageCommand,
AccountManageCommand,
ReloadCommand,
+
+ PingCommand, ConnectCommand,
)
}
diff --git a/src/main/java/de/bixilon/minosoft/terminal/commands/ConnectCommand.kt b/src/main/java/de/bixilon/minosoft/terminal/commands/ConnectCommand.kt
new file mode 100644
index 000000000..0714752c5
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/terminal/commands/ConnectCommand.kt
@@ -0,0 +1,58 @@
+/*
+ * Minosoft
+ * 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.
+ *
+ * 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.terminal.commands
+
+import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
+import de.bixilon.kutil.observer.DataObserver.Companion.observe
+import de.bixilon.minosoft.commands.nodes.ArgumentNode
+import de.bixilon.minosoft.commands.nodes.LiteralNode
+import de.bixilon.minosoft.commands.parser.brigadier.string.StringParser
+import de.bixilon.minosoft.commands.stack.print.PrintTarget
+import de.bixilon.minosoft.config.profile.profiles.account.AccountProfileManager
+import de.bixilon.minosoft.data.accounts.Account
+import de.bixilon.minosoft.protocol.address.ServerAddress
+import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
+import de.bixilon.minosoft.protocol.network.connection.status.StatusConnection
+import de.bixilon.minosoft.protocol.versions.Version
+import de.bixilon.minosoft.protocol.versions.Versions
+import de.bixilon.minosoft.util.DNSUtil
+
+object ConnectCommand : Command {
+ override var node = LiteralNode("connect")
+ .addChild(ArgumentNode("address", StringParser(StringParser.StringModes.QUOTED), onlyDirectExecution = false) { stack ->
+ val address = stack.get("address")!!
+ val version = stack.get("version")?.let { Versions[it] ?: throw CommandException("Unknown version $it") }
+ val account = AccountProfileManager.selected.selected ?: throw CommandException("No account selected!")
+ DefaultThreadPool += add@{
+ if (version == null) {
+ stack.print.print("Pinging server to get version...")
+ val ping = StatusConnection(address)
+ ping::status.observe(this) { connect(stack.print, ping.realAddress!!, ping.serverVersion ?: throw IllegalArgumentException("Could not determinate server's version!"), account) }
+ ping::error.observe(this) { stack.print.print("Could not ping $address: $it") }
+ ping.ping()
+ return@add
+ }
+
+ connect(stack.print, DNSUtil.resolveServerAddress(address).first(), version, account)
+ }
+ }.addChild(ArgumentNode("version", StringParser(StringParser.StringModes.QUOTED), executable = true)))
+
+
+ private fun connect(print: PrintTarget, address: ServerAddress, version: Version, account: Account) {
+ print.print("Connecting to $address")
+
+ val connection = PlayConnection(address, account, version)
+ connection.connect()
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/terminal/commands/PingCommand.kt b/src/main/java/de/bixilon/minosoft/terminal/commands/PingCommand.kt
new file mode 100644
index 000000000..7c40cae4a
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/terminal/commands/PingCommand.kt
@@ -0,0 +1,32 @@
+/*
+ * Minosoft
+ * 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.
+ *
+ * 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.terminal.commands
+
+import de.bixilon.kutil.observer.DataObserver.Companion.observe
+import de.bixilon.minosoft.commands.nodes.ArgumentNode
+import de.bixilon.minosoft.commands.nodes.LiteralNode
+import de.bixilon.minosoft.commands.parser.brigadier.string.StringParser
+import de.bixilon.minosoft.protocol.network.connection.status.StatusConnection
+import de.bixilon.minosoft.protocol.versions.Versions
+
+object PingCommand : Command {
+ override var node = LiteralNode("ping")
+ .addChild(ArgumentNode("address", StringParser(StringParser.StringModes.QUOTED), onlyDirectExecution = false) { stack ->
+ val address = stack.get("address")!!
+ val version = stack.get("version")?.let { Versions[it] ?: throw IllegalArgumentException("Unknown version $it") }
+ val connection = StatusConnection(address, version)
+ connection::status.observe(PingCommand) { if (it == null) return@observe; stack.print.print("Received status of §e$address§r: online=§c${it.usedSlots}§r/§a${it.slots}:\n ${it.motd}") }
+ connection.ping()
+ }.addChild(ArgumentNode("version", StringParser(StringParser.StringModes.QUOTED), executable = true)))
+}