From cfa9f14b528b2cbcdd589b9aeb0a2bf9ce36bd19 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 24 Jul 2023 17:16:08 +0200 Subject: [PATCH] Implement param converter and add tests --- .../java/buttondevteam/lib/chat/Command2.kt | 26 +++++++++---------- .../lib/chat/commands/CommandUtils.kt | 15 +++++++++++ .../lib/chat/test/Command2MCTest.kt | 15 ++++++++++- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.kt b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.kt index fc7bc30..3ad74fe 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.kt +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/Command2.kt @@ -5,10 +5,10 @@ import buttondevteam.lib.ChromaUtils import buttondevteam.lib.chat.commands.* import buttondevteam.lib.chat.commands.CommandUtils.coreCommand 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.subcommandDataNoOp -import com.google.common.base.Defaults -import com.google.common.primitives.Primitives import com.mojang.brigadier.CommandDispatcher import com.mojang.brigadier.arguments.* import com.mojang.brigadier.builder.ArgumentBuilder @@ -197,7 +197,6 @@ abstract class Command2, TP : Command2Sender>( ).executes(this::executeHelpText) fun getArgNodes(parent: ArgumentBuilder, params: MutableList): Boolean { - // TODO: Implement optional arguments here by making the last non-optional parameter also executable val param = params.removeFirst() val argType = getArgumentType(param) val arg = CoreArgumentBuilder.argument(param.name, argType, param.optional) @@ -350,7 +349,6 @@ abstract class Command2, TP : Command2Sender>( val params = executeGetArguments(sd, context) ?: return executeHelpText(context) - // TODO: Invoke using custom method // TODO: Varargs support? (colors?) // TODO: Character handling (strlen) // TODO: Param converter @@ -363,18 +361,18 @@ abstract class Command2, TP : Command2Sender>( val params = mutableListOf() for (argument in sd.argumentsInOrder) { try { - val userArgument = context.getArgument(argument.name, argument.type) - params.add(userArgument) + if (argument.type.isEasilyRepresentable()) { + 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) { - // TODO: This probably only works with primitive types (argument.type) if (argument.optional) { - if (argument.type.isPrimitive) { - 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) - } + params.add(argument.type.getDefaultForEasilyRepresentable()) } else { return null } diff --git a/Chroma-Core/src/main/java/buttondevteam/lib/chat/commands/CommandUtils.kt b/Chroma-Core/src/main/java/buttondevteam/lib/chat/commands/CommandUtils.kt index adda0e6..d191309 100644 --- a/Chroma-Core/src/main/java/buttondevteam/lib/chat/commands/CommandUtils.kt +++ b/Chroma-Core/src/main/java/buttondevteam/lib/chat/commands/CommandUtils.kt @@ -1,6 +1,8 @@ package buttondevteam.lib.chat.commands 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.tree.CommandNode import java.util.* @@ -80,4 +82,17 @@ object CommandUtils { fun CommandNode.subcommandDataNoOp(): NoOpSubcommandData? { 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 + } } \ No newline at end of file diff --git a/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCTest.kt b/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCTest.kt index aa0e012..8ca31e8 100644 --- a/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCTest.kt +++ b/Chroma-Core/src/test/kotlin/buttondevteam/lib/chat/test/Command2MCTest.kt @@ -86,12 +86,16 @@ class Command2MCTest { runFailingCommand(sender, "/erroringtest") runCommand(sender, "/multiargtest hmm mhm", MultiArgTestCommand, "hmmmhm") runCommand(sender, "/multiargtest test2 true 19", MultiArgTestCommand, "true 19") + runCommand(sender, "/multiargtest testoptional", MultiArgTestCommand, "false") runCommand(sender, "/multiargtest testoptional true", MultiArgTestCommand, "true") runCommand(sender, "/multiargtest testoptionalmulti true teszt", MultiArgTestCommand, "true teszt") runCommand(sender, "/multiargtest testoptionalmulti true", MultiArgTestCommand, "true 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) { @@ -111,6 +115,15 @@ class Command2MCTest { fun def(sender: Command2MCSender, test: String) { testCommandReceived = test } + + @Command2.Subcommand + fun plugin(sender: Command2MCSender, plugin: ButtonPlugin) { + testCommandReceived = plugin.name + } + + @Command2.Subcommand + fun playerFail(sender: Command2MCSender, player: TBMCPlayer) { + } } @CommandClass