Implement param converter and add tests

This commit is contained in:
Norbi Peti 2023-07-24 17:16:08 +02:00
parent 0e39cd38e3
commit cfa9f14b52
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
3 changed files with 41 additions and 15 deletions

View file

@ -5,10 +5,10 @@ import buttondevteam.lib.ChromaUtils
import buttondevteam.lib.chat.commands.* import buttondevteam.lib.chat.commands.*
import buttondevteam.lib.chat.commands.CommandUtils.coreCommand import buttondevteam.lib.chat.commands.CommandUtils.coreCommand
import buttondevteam.lib.chat.commands.CommandUtils.coreExecutable import buttondevteam.lib.chat.commands.CommandUtils.coreExecutable
import buttondevteam.lib.chat.commands.CommandUtils.getDefaultForEasilyRepresentable
import buttondevteam.lib.chat.commands.CommandUtils.isEasilyRepresentable
import buttondevteam.lib.chat.commands.CommandUtils.subcommandData import buttondevteam.lib.chat.commands.CommandUtils.subcommandData
import buttondevteam.lib.chat.commands.CommandUtils.subcommandDataNoOp import buttondevteam.lib.chat.commands.CommandUtils.subcommandDataNoOp
import com.google.common.base.Defaults
import com.google.common.primitives.Primitives
import com.mojang.brigadier.CommandDispatcher import com.mojang.brigadier.CommandDispatcher
import com.mojang.brigadier.arguments.* import com.mojang.brigadier.arguments.*
import com.mojang.brigadier.builder.ArgumentBuilder import com.mojang.brigadier.builder.ArgumentBuilder
@ -197,7 +197,6 @@ abstract class Command2<TC : ICommand2<TP>, TP : Command2Sender>(
).executes(this::executeHelpText) ).executes(this::executeHelpText)
fun getArgNodes(parent: ArgumentBuilder<TP, *>, params: MutableList<CommandArgument>): Boolean { fun getArgNodes(parent: ArgumentBuilder<TP, *>, params: MutableList<CommandArgument>): Boolean {
// TODO: Implement optional arguments here by making the last non-optional parameter also executable
val param = params.removeFirst() val param = params.removeFirst()
val argType = getArgumentType(param) val argType = getArgumentType(param)
val arg = CoreArgumentBuilder.argument<TP, _>(param.name, argType, param.optional) val arg = CoreArgumentBuilder.argument<TP, _>(param.name, argType, param.optional)
@ -350,7 +349,6 @@ abstract class Command2<TC : ICommand2<TP>, TP : Command2Sender>(
val params = executeGetArguments(sd, context) ?: return executeHelpText(context) val params = executeGetArguments(sd, context) ?: return executeHelpText(context)
// TODO: Invoke using custom method
// TODO: Varargs support? (colors?) // TODO: Varargs support? (colors?)
// TODO: Character handling (strlen) // TODO: Character handling (strlen)
// TODO: Param converter // TODO: Param converter
@ -363,18 +361,18 @@ abstract class Command2<TC : ICommand2<TP>, TP : Command2Sender>(
val params = mutableListOf<Any?>() val params = mutableListOf<Any?>()
for (argument in sd.argumentsInOrder) { for (argument in sd.argumentsInOrder) {
try { try {
val userArgument = context.getArgument(argument.name, argument.type) if (argument.type.isEasilyRepresentable()) {
params.add(userArgument) val userArgument = context.getArgument(argument.name, argument.type)
params.add(userArgument)
} else {
val userArgument = context.getArgument(argument.name, String::class.java)
val converter = paramConverters[argument.type]?.converter
?: throw IllegalStateException("No suitable converter found for ${argument.type} ${argument.name}")
params.add(converter.apply(userArgument))
}
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
// TODO: This probably only works with primitive types (argument.type)
if (argument.optional) { if (argument.optional) {
if (argument.type.isPrimitive) { params.add(argument.type.getDefaultForEasilyRepresentable())
params.add(Defaults.defaultValue(argument.type))
} else if (Number::class.java.isAssignableFrom(argument.type)) {
params.add(Defaults.defaultValue(Primitives.unwrap(argument.type)))
} else {
params.add(null)
}
} else { } else {
return null return null
} }

View file

@ -1,6 +1,8 @@
package buttondevteam.lib.chat.commands package buttondevteam.lib.chat.commands
import buttondevteam.lib.chat.* import buttondevteam.lib.chat.*
import com.google.common.base.Defaults
import com.google.common.primitives.Primitives
import com.mojang.brigadier.builder.ArgumentBuilder import com.mojang.brigadier.builder.ArgumentBuilder
import com.mojang.brigadier.tree.CommandNode import com.mojang.brigadier.tree.CommandNode
import java.util.* import java.util.*
@ -80,4 +82,17 @@ object CommandUtils {
fun <TP : Command2Sender> CommandNode<TP>.subcommandDataNoOp(): NoOpSubcommandData? { fun <TP : Command2Sender> CommandNode<TP>.subcommandDataNoOp(): NoOpSubcommandData? {
return subcommandData() ?: coreCommand<_, NoOpSubcommandData>()?.data return subcommandData() ?: coreCommand<_, NoOpSubcommandData>()?.data
} }
fun Class<*>.isEasilyRepresentable(): Boolean {
return isPrimitive || Number::class.java.isAssignableFrom(this)
|| String::class.java.isAssignableFrom(this)
}
fun Class<*>.getDefaultForEasilyRepresentable(): Any? {
return if (isPrimitive) {
Defaults.defaultValue(this)
} else if (Number::class.java.isAssignableFrom(this)) {
Defaults.defaultValue(Primitives.unwrap(this))
} else null
}
} }

View file

@ -86,12 +86,16 @@ class Command2MCTest {
runFailingCommand(sender, "/erroringtest") runFailingCommand(sender, "/erroringtest")
runCommand(sender, "/multiargtest hmm mhm", MultiArgTestCommand, "hmmmhm") runCommand(sender, "/multiargtest hmm mhm", MultiArgTestCommand, "hmmmhm")
runCommand(sender, "/multiargtest test2 true 19", MultiArgTestCommand, "true 19") runCommand(sender, "/multiargtest test2 true 19", MultiArgTestCommand, "true 19")
runCommand(sender, "/multiargtest testoptional", MultiArgTestCommand, "false") runCommand(sender, "/multiargtest testoptional", MultiArgTestCommand, "false")
runCommand(sender, "/multiargtest testoptional true", MultiArgTestCommand, "true") runCommand(sender, "/multiargtest testoptional true", MultiArgTestCommand, "true")
runCommand(sender, "/multiargtest testoptionalmulti true teszt", MultiArgTestCommand, "true teszt") runCommand(sender, "/multiargtest testoptionalmulti true teszt", MultiArgTestCommand, "true teszt")
runCommand(sender, "/multiargtest testoptionalmulti true", MultiArgTestCommand, "true null") runCommand(sender, "/multiargtest testoptionalmulti true", MultiArgTestCommand, "true null")
runCommand(sender, "/multiargtest testoptionalmulti", MultiArgTestCommand, "false null") runCommand(sender, "/multiargtest testoptionalmulti", MultiArgTestCommand, "false null")
// TODO: Add expected failed param conversions and missing params
runCommand(sender, "/test plugin Chroma-Core", TestCommand, "Chroma-Core")
assertFails { ButtonPlugin.command2MC.handleCommand(sender, "/test playerfail TestPlayer") }
// TODO: Add expected missing params
} }
private fun runCommand(sender: Command2MCSender, command: String, obj: ITestCommand2MC, expected: String) { private fun runCommand(sender: Command2MCSender, command: String, obj: ITestCommand2MC, expected: String) {
@ -111,6 +115,15 @@ class Command2MCTest {
fun def(sender: Command2MCSender, test: String) { fun def(sender: Command2MCSender, test: String) {
testCommandReceived = test testCommandReceived = test
} }
@Command2.Subcommand
fun plugin(sender: Command2MCSender, plugin: ButtonPlugin) {
testCommandReceived = plugin.name
}
@Command2.Subcommand
fun playerFail(sender: Command2MCSender, player: TBMCPlayer) {
}
} }
@CommandClass @CommandClass