Skip to content

Commit

Permalink
Command: Fix a few bugs
Browse files Browse the repository at this point in the history
- Commands did not reregister when rejoining a world, as the dispatcher
  was recreated
- .redirect() only redirects on the thing its applied to, so it doesn't
  work if there are multiple cases (via .then())
  • Loading branch information
mattco98 committed Jul 8, 2023
1 parent 3cd3c4e commit 2de212d
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 38 deletions.
12 changes: 0 additions & 12 deletions src/main/kotlin/com/chattriggers/ctjs/CTJS.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.chattriggers.ctjs

import com.chattriggers.ctjs.commands.CTCommand
import com.chattriggers.ctjs.commands.Command
import com.chattriggers.ctjs.console.*
import com.chattriggers.ctjs.engine.module.ModuleManager
import com.chattriggers.ctjs.minecraft.libs.renderer.Image
Expand All @@ -14,7 +12,6 @@ import com.chattriggers.ctjs.utils.Initializer
import com.google.gson.Gson
import com.mojang.brigadier.CommandDispatcher
import net.fabricmc.api.ClientModInitializer
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
import net.fabricmc.loader.api.FabricLoader
import java.io.File
Expand All @@ -30,14 +27,6 @@ internal class CTJS : ClientModInitializer {

Initializer.initializers.forEach(Initializer::init)

ClientCommandRegistrationCallback.EVENT.register { dispatcher, _ ->
CTCommand.register(dispatcher)
commandDispatcher = dispatcher

Command.pendingCommands.forEach(Command::register)
Command.pendingCommands.clear()
}

thread {
ModuleManager.entryPass()
reportHashedUUID()
Expand Down Expand Up @@ -69,7 +58,6 @@ internal class CTJS : ClientModInitializer {
const val WEBSITE_ROOT = "https://www.chattriggers.com"
internal val images = mutableListOf<Image>()
internal val sounds = mutableListOf<Sound>()
internal var commandDispatcher: CommandDispatcher<FabricClientCommandSource>? = null
internal val isDevelopment = FabricLoader.getInstance().isDevelopmentEnvironment

val configLocation = File("./config")
Expand Down
71 changes: 45 additions & 26 deletions src/main/kotlin/com/chattriggers/ctjs/commands/Command.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ import com.chattriggers.ctjs.triggers.CommandTrigger
import com.chattriggers.ctjs.console.LogType
import com.chattriggers.ctjs.console.printToConsole
import com.chattriggers.ctjs.engine.js.JSLoader
import com.chattriggers.ctjs.utils.Initializer
import com.mojang.brigadier.CommandDispatcher
import com.mojang.brigadier.arguments.StringArgumentType
import com.mojang.brigadier.builder.ArgumentBuilder
import com.mojang.brigadier.builder.LiteralArgumentBuilder
import com.mojang.brigadier.context.CommandContext
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
import net.minecraft.command.CommandSource

internal class Command(
val trigger: CommandTrigger,
Expand All @@ -22,13 +28,31 @@ internal class Command(
private val registeredAliases = mutableSetOf<String>()

fun register() {
val dispatcher = CTJS.commandDispatcher
if (dispatcher == null) {
pendingCommands.add(this)
return
}

val command = literal(name)
if (hasConflict(name)) {
existingCommandWarning(name).printToConsole(JSLoader.console, LogType.WARN)
return
}

dispatcher!!.register(makeCommand(name))
activeCommands.add(this)

for (alias in aliases) {
if (hasConflict(alias)) {
existingCommandWarning(alias).printToConsole(JSLoader.console, LogType.WARN)
} else {
dispatcher!!.register(makeCommand(alias))
registeredAliases.add(alias)
}
}
}

private fun makeCommand(name: String): LiteralArgumentBuilder<FabricClientCommandSource> {
return literal(name)
.then(argument("args", StringArgumentType.greedyString())
.suggests { ctx, builder ->
val suggestions = if (dynamicSuggestions != null) {
Expand All @@ -53,23 +77,6 @@ internal class Command(
trigger.trigger(StringArgumentType.getString(it, "args").split(" ").toTypedArray())
})
.onExecute { trigger.trigger(emptyArray()) }

if (hasConflict(name)) {
existingCommandWarning(name).printToConsole(JSLoader.console, LogType.WARN)
return
}

val registeredCommand = dispatcher.register(command)
activeCommands.add(this)

for (name in aliases) {
if (hasConflict(name)) {
existingCommandWarning(name).printToConsole(JSLoader.console, LogType.WARN)
} else {
dispatcher.register(literal(name).redirect(registeredCommand))
registeredAliases.add(name)
}
}
}

fun unregister() {
Expand All @@ -78,30 +85,42 @@ internal class Command(
return
}

CTJS.commandDispatcher!!.root.children.removeIf {
dispatcher!!.root.children.removeIf {
it.name == name || it.name in registeredAliases
}

activeCommands.remove(this)
registeredAliases.clear()
}

private fun hasConflict(name: String) = !overrideExisting && CTJS.commandDispatcher!!.root.getChild(name) != null
private fun hasConflict(name: String) = !overrideExisting && dispatcher!!.root.getChild(name) != null

companion object {
companion object : Initializer {
private var dispatcher: CommandDispatcher<FabricClientCommandSource>? = null
internal val activeCommands = mutableSetOf<Command>()
internal val pendingCommands = mutableSetOf<Command>()

override fun init() {
ClientCommandRegistrationCallback.EVENT.register { dispatcher, _ ->
CTCommand.register(dispatcher)
this.dispatcher = dispatcher

activeCommands.forEach(Command::register)
pendingCommands.forEach(Command::register)
pendingCommands.clear()
}
}

private fun existingCommandWarning(name: String) =
"""
Command with name $name already exists! This will not override the
other command with the same name. To override the other command, set the
overrideExisting flag in setName() (the second argument) to true.
""".trimIndent().replace("\n", "")

fun <S, T : ArgumentBuilder<S, T>> ArgumentBuilder<S, T>.onExecute(block: (CommandContext<S>) -> Unit) = this.executes {
block(it)
1
}
fun <S, T : ArgumentBuilder<S, T>> ArgumentBuilder<S, T>.onExecute(block: (CommandContext<S>) -> Unit): T = this.executes {
block(it)
1
}
}
}
2 changes: 2 additions & 0 deletions src/main/kotlin/com/chattriggers/ctjs/utils/Initializer.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.chattriggers.ctjs.utils

import com.chattriggers.ctjs.commands.Command
import com.chattriggers.ctjs.engine.module.ModuleUpdater
import com.chattriggers.ctjs.minecraft.listeners.ClientListener
import com.chattriggers.ctjs.minecraft.listeners.MouseListener
Expand All @@ -15,6 +16,7 @@ internal interface Initializer {
companion object {
internal val initializers = listOf(
ClientListener,
Command,
ConsoleManager,
CPS,
Image.Companion,
Expand Down

0 comments on commit 2de212d

Please sign in to comment.