[feature] Baritone AutoComplete

Signed-off-by: Dominika <sokolov.dominika@gmail.com>
This commit is contained in:
Dominika 2021-01-04 23:28:17 -05:00 committed by liv
parent c1dbe4b84f
commit 1bfe13f605
4 changed files with 233 additions and 5 deletions

View File

@ -1,9 +1,15 @@
package me.zeroeightsix.kami.command
import baritone.cache.CachedChunk
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import me.zeroeightsix.kami.manager.managers.UUIDManager
import me.zeroeightsix.kami.module.Module
import me.zeroeightsix.kami.module.ModuleManager
import me.zeroeightsix.kami.util.TickTimer
import me.zeroeightsix.kami.util.TimeUnit
import me.zeroeightsix.kami.util.Wrapper
import me.zeroeightsix.kami.util.threads.defaultScope
import net.minecraft.block.Block
import net.minecraft.item.Item
import net.minecraft.util.math.BlockPos
@ -12,6 +18,7 @@ import org.kamiblue.command.AbstractArg
import org.kamiblue.command.AutoComplete
import org.kamiblue.command.DynamicPrefixMatch
import org.kamiblue.command.StaticPrefixMatch
import java.io.File
import java.util.*
import kotlin.streams.toList
@ -62,16 +69,73 @@ class BlockArg(
}
private companion object {
val allBlockNames = ArrayList<String>().run {
val allBlockNames = ArrayList<String>().apply {
Block.REGISTRY.keys.forEach {
add(it.toString())
add(it.path)
}
sorted()
sort()
}
}
}
class BaritoneBlockArg(
override val name: String
) : AbstractArg<Block>(), AutoComplete by StaticPrefixMatch(baritoneBlockNames) {
override suspend fun convertToType(string: String?): Block? {
if (string == null) return null
return Block.getBlockFromName(string)
}
private companion object {
val baritoneBlockNames = ArrayList<String>().apply {
CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.forEach { block ->
block.registryName?.let {
add(it.toString())
add(it.path)
}
}
sort()
}
}
}
class SchematicArg(
override val name: String
) : AbstractArg<File>(), AutoComplete by DynamicPrefixMatch(::schematicFiles) {
override suspend fun convertToType(string: String?): File? {
if (string == null) return null
val nameWithoutExt = string.removeSuffix(".schematic")
val file = File("schematics").listFiles()?.filter {
it.exists() && it.isFile && it.name.equals("$nameWithoutExt.schematic", true)
} // this stupid find and search is required because ext4 is case sensitive (Linux)
return file?.firstOrNull()
}
private companion object {
val timer = TickTimer(TimeUnit.SECONDS)
val schematicFolder = File("schematics")
var cachedFiles = emptyList<String>()
val schematicFiles: Collection<String>
get() {
if (timer.tick(2L) && schematicFolder.isDirectory) {
defaultScope.launch(Dispatchers.IO) {
schematicFolder.listFiles()?.map { it.name }?.let {
cachedFiles = it
}
}
}
return cachedFiles
}
}
}
class ItemArg(
override val name: String
) : AbstractArg<Item>(), AutoComplete by StaticPrefixMatch(allItemNames) {

View File

@ -16,6 +16,7 @@ import org.kamiblue.command.AbstractArg
import org.kamiblue.command.CommandBuilder
import org.kamiblue.command.utils.BuilderBlock
import org.kamiblue.command.utils.ExecuteBlock
import java.io.File
abstract class ClientCommand(
name: String,
@ -65,6 +66,22 @@ abstract class ClientCommand(
arg(BlockPosArg(name), block)
}
@CommandBuilder
protected fun AbstractArg<*>.baritoneBlock(
name: String,
block: BuilderBlock<Block>
) {
arg(BaritoneBlockArg(name), block)
}
@CommandBuilder
protected fun AbstractArg<*>.schematic(
name: String,
file: BuilderBlock<File>
) {
arg(SchematicArg(name), file)
}
@CommandBuilder
protected fun AbstractArg<*>.executeAsync(
description: String = "No description",

View File

@ -1,20 +1,167 @@
package me.zeroeightsix.kami.command.commands
import me.zeroeightsix.kami.KamiMod
import me.zeroeightsix.kami.command.ClientCommand
import me.zeroeightsix.kami.command.CommandManager
import me.zeroeightsix.kami.util.text.MessageSendHelper
// TODO: Add the follow argument when Baritone 1.2.15 is released.
// Currently follow is broken on Forge 1.12.2 in 1.2.14, it is fixed in master branch.
object BaritoneCommand : ClientCommand(
name = "baritone",
alias = arrayOf("b")
) {
init {
literal("thisway") {
int("blocks") { blocksArg ->
executeSafe("Walk in the current direction for X blocks.") {
exec("thisway", blocksArg.value.toString())
exec("path")
}
}
}
literal("goal") {
literal("clear") {
executeSafe("Clear the current goal.") {
exec("goal", "clear")
}
}
int("x/y") { xArg ->
executeSafe("Set goal to a Y level.") {
exec("goal", xArg.value.toString())
}
int("y/z") { yArg ->
executeSafe("Set goal to X Z.") {
exec("goal", xArg.value.toString(), yArg.value.toString())
}
int("z") { zArg ->
executeSafe("Set goal to X Y Z.") {
exec("goal", xArg.value.toString(), yArg.value.toString(), zArg.value.toString())
}
}
}
}
}
literal("path") {
executeSafe("Start pathing towards your set goal.") {
exec("path")
}
}
literal("stop", "cancel") {
executeSafe("Stop the current Baritone process.") {
exec("stop")
}
}
literal("mine") {
block("block") { blockArg ->
executeSafe("Mine a block.") {
exec("mine", blockArg.value.registryName!!.path)
}
}
greedy("blocks") { blocksArg -> // TODO: When array arguments are added switch this over
executeSafe("Mine any amount of blocks.") {
exec("mine", blocksArg.value)
}
}
}
literal("goto") {
blockPos("coordinates") { coordinatesArg ->
executeSafe("Go to a set of coordinates.") {
val coord = coordinatesArg.value
exec("goto", coord.x.toString(), coord.y.toString(), coord.z.toString())
}
}
baritoneBlock("cached block") { blockArg ->
executeSafe("Go to a Baritone cached block.") {
exec("goto", blockArg.value.registryName!!.path)
}
}
greedy("x y z") { coordinatesArg ->
executeSafe("Go to a set of coords. Y and Z optional.") {
exec("goto", coordinatesArg.value)
}
}
}
literal("click") {
executeSafe("Open the click and drag menu.") {
exec("click")
}
}
literal("build") {
schematic("schematic") { schematicArg ->
executeSafe("Build something from inside the schematics folder.") {
exec("build", schematicArg.value.name)
}
}
}
literal("schematica") {
executeSafe("Build the currently opened schematic in Schematica.") {
exec("schematica")
}
greedy("args") { greedyArg ->
executeSafe("Build the currently opened schematic in Schematica.") {
exec("schematica", greedyArg.value)
}
}
}
literal("farm") {
executeSafe("Automatically farm any found crops.") {
exec("farm")
}
}
literal("explore") {
executeSafe("Explore away from you.") {
exec("explore")
}
int("x") { xArg ->
int("z") { zArg ->
executeSafe("Explore away from X Z.") {
exec("explore", xArg.value.toString(), zArg.value.toString())
}
}
}
}
literal("invert") {
executeSafe("Go in the opposite direction of your goal.") {
exec("invert")
}
}
literal("version") {
executeSafe {
exec("version")
MessageSendHelper.sendBaritoneMessage("Running on KAMI Blue ${KamiMod.VERSION}")
}
}
greedy("arguments") { args ->
executeSafe {
val newArgs = CommandManager.tryParseArgument(args.value) ?: return@executeSafe
MessageSendHelper.sendBaritoneCommand(*newArgs)
exec(args.value)
}
}
}
private fun exec(vararg args: String) {
val safeArgs = CommandManager.tryParseArgument(args.joinToString(" ")) ?: return
MessageSendHelper.sendBaritoneCommand(*safeArgs)
}
}

View File

@ -44,7 +44,7 @@ object MessageSendHelper {
val prevValue = chatControl?.value
chatControl?.value = true
val event = ChatEvent(args.joinToString(separator = " "))
val event = ChatEvent(args.joinToString(" "))
BaritoneUtils.primary?.gameEventHandler?.onSendChatMessage(event)
if (!event.isCancelled && args[0] != "damn") { // don't remove the 'damn', it's critical code that will break everything if you remove it
sendBaritoneMessage("Invalid Command! Please view possible commands at https://github.com/cabaletta/baritone/blob/master/USAGE.md")