From 74ed68dcfcfa4487af02d9d4bbd808b88acabc04 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 17:39:24 +0100 Subject: [PATCH 01/25] added test --- .../github/spigotbasics/common/DictionaryTest.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/common/src/test/kotlin/com/github/spigotbasics/common/DictionaryTest.kt b/common/src/test/kotlin/com/github/spigotbasics/common/DictionaryTest.kt index eed87b00..8d2c6d5b 100644 --- a/common/src/test/kotlin/com/github/spigotbasics/common/DictionaryTest.kt +++ b/common/src/test/kotlin/com/github/spigotbasics/common/DictionaryTest.kt @@ -25,4 +25,18 @@ class DictionaryTest { assertNull(map["test2"]) assertNull(map["TEST2"]) } + + @Test + fun replacesProperly() { + val map = Dictionary() + map["aaa"] = object { } + map["AAA"] = object { } + map["aAa"] = object { } + assertEquals(1, map.size) + + map["aab"] = object { } + map["AAB"] = object { } + map["aAb"] = object { } + assertEquals(2, map.size) + } } From 978c8d2780bdf08df556de3ca7cb49b54dc67879 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 17:39:46 +0100 Subject: [PATCH 02/25] began new argument parsing system --- .github/workflows/build.yml | 2 +- .github/workflows/dependency-graph.yml | 2 +- .../command/arguments/ArgumentSignature.kt | 3 +++ .../core/command/arguments/ArgumentType.kt | 5 +++++ .../core/command/arguments/EnumArgument.kt | 18 ++++++++++++++++++ .../arguments/EnumValueNotFoundException.kt | 5 +++++ .../core/command/arguments/PlayerArgument.kt | 14 ++++++++++++++ .../arguments/PlayerNotFoundException.kt | 3 +++ 8 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerArgument.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerNotFoundException.kt diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4ab32967..706aae1c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: with: java-version: '17' distribution: 'temurin' - cache: "gradle" +# cache: "gradle" - name: Setup Gradle uses: gradle/actions/setup-gradle@ec92e829475ac0c2315ea8f9eced72db85bb337a # v3.0.0 diff --git a/.github/workflows/dependency-graph.yml b/.github/workflows/dependency-graph.yml index 01252eb3..e0496b95 100644 --- a/.github/workflows/dependency-graph.yml +++ b/.github/workflows/dependency-graph.yml @@ -20,7 +20,7 @@ jobs: with: java-version: '17' distribution: 'temurin' - cache: "gradle" +# cache: "gradle" - name: Generate and submit dependency graph uses: gradle/actions/dependency-submission@ec92e829475ac0c2315ea8f9eced72db85bb337a # v3.0.0 diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt new file mode 100644 index 00000000..9bca85ad --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt @@ -0,0 +1,3 @@ +package com.github.spigotbasics.core.command.arguments + +data class ArgumentSignature(val arguments: List>) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt new file mode 100644 index 00000000..00c22ab4 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt @@ -0,0 +1,5 @@ +package com.github.spigotbasics.core.command.arguments + +interface ArgumentType { + fun parse(value: String): T +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt new file mode 100644 index 00000000..39ce1a58 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt @@ -0,0 +1,18 @@ +package com.github.spigotbasics.core.command.arguments + +import com.github.spigotbasics.common.Dictionary + +class EnumArgument>(val enumClass: Class) : ArgumentType { + + private val enumConstants: Dictionary + + init { + enumConstants = Dictionary() + for (constant in enumClass.enumConstants) { + enumConstants[constant.name] = constant + } + } + override fun parse(value: String): T { + return enumConstants[value] ?: throw EnumValueNotFoundException(value, enumClass) + } +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt new file mode 100644 index 00000000..9bed965b --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt @@ -0,0 +1,5 @@ +package com.github.spigotbasics.core.command.arguments + +class EnumValueNotFoundException(value: String, enumClass: Class) : Throwable() { + +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerArgument.kt new file mode 100644 index 00000000..00e21ff4 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerArgument.kt @@ -0,0 +1,14 @@ +package com.github.spigotbasics.core.command.arguments + +import org.bukkit.Bukkit +import org.bukkit.entity.Player + +object PlayerArgument : ArgumentType { + override fun parse(value: String): Player { + val player = Bukkit.getPlayer(value) + if (player == null) { + throw PlayerNotFoundException(value) + } + return player + } +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerNotFoundException.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerNotFoundException.kt new file mode 100644 index 00000000..2d6e8664 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerNotFoundException.kt @@ -0,0 +1,3 @@ +package com.github.spigotbasics.core.command.arguments + +class PlayerNotFoundException(value: String) : IllegalArgumentException("Player not found: $value") From f5570d0c4c898685e7fb8daceb1d91b2ccdaa62d Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 17:44:21 +0100 Subject: [PATCH 03/25] fixed signature --- .../core/command/arguments/EnumValueNotFoundException.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt index 9bed965b..b0b656f9 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt @@ -1,5 +1,5 @@ package com.github.spigotbasics.core.command.arguments -class EnumValueNotFoundException(value: String, enumClass: Class) : Throwable() { +class EnumValueNotFoundException(value: String, enumClass: Class<*>) : NoSuchElementException("Enum value not found: $value in enum class: $enumClass") { } From 48e596508d9e4f6bd33ceca4a5b89d91f163633a Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 19:13:44 +0100 Subject: [PATCH 04/25] how? --- .../core/command/ParsedCommand.kt | 19 +++++++++++++++ .../command/arguments/ArgumentSignature.kt | 4 +++- .../core/command/arguments/ArgumentType.kt | 2 ++ .../core/command/parsed/Argument.kt | 5 ++++ .../core/command/parsed/ArgumentMaterial.kt | 9 ++++++++ .../core/command/parsed/ArgumentPlayer.kt | 10 ++++++++ .../core/command/parsed/GiveCommand.kt | 11 +++++++++ .../core/command/parsed/GiveCommandContext.kt | 14 +++++++++++ .../core/command/parsed/ParsedCommand.kt | 23 +++++++++++++++++++ .../command/parsed/ParsedCommandContext.kt | 9 ++++++++ .../command/parsed/ParsedCommandExecutor.kt | 6 +++++ 11 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt new file mode 100644 index 00000000..0815d94a --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt @@ -0,0 +1,19 @@ +package com.github.spigotbasics.core.command + +import com.github.spigotbasics.core.command.arguments.ArgumentSignature +import org.bukkit.Bukkit +import org.bukkit.Material +import org.bukkit.Statistic +import org.bukkit.command.Command +import org.bukkit.command.CommandSender + +class ParsedCommand( + val info: CommandInfo, + val signatures: List>, +) : Command(info.name) { + override fun execute(sender: CommandSender, commandLabel: String, args: Array): Boolean { + + + return false + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt index 9bca85ad..f5116510 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt @@ -1,3 +1,5 @@ package com.github.spigotbasics.core.command.arguments -data class ArgumentSignature(val arguments: List>) +import org.bukkit.command.CommandSender + +class ArgumentSignature(val requiredSender: Class, val arguments: List>) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt index 00c22ab4..98223370 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt @@ -2,4 +2,6 @@ package com.github.spigotbasics.core.command.arguments interface ArgumentType { fun parse(value: String): T + + fun tabComplete(value: String): MutableList? = null } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt new file mode 100644 index 00000000..cf2688e5 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt @@ -0,0 +1,5 @@ +package com.github.spigotbasics.core.command.parsed + +interface Argument { + fun parse(value: String): T? +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt new file mode 100644 index 00000000..988aaf43 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt @@ -0,0 +1,9 @@ +package com.github.spigotbasics.core.command.parsed + +import org.bukkit.Material + +object ArgumentMaterial : Argument { + override fun parse(value: String): Material? { + return Material.getMaterial(value) + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt new file mode 100644 index 00000000..dcc9d52a --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt @@ -0,0 +1,10 @@ +package com.github.spigotbasics.core.command.parsed + +import org.bukkit.Bukkit +import org.bukkit.entity.Player + +object ArgumentPlayer : Argument { + override fun parse(value: String): Player? { + return Bukkit.getPlayer(value) + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt new file mode 100644 index 00000000..93508fd2 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt @@ -0,0 +1,11 @@ +package com.github.spigotbasics.core.command.parsed + +import org.bukkit.inventory.ItemStack + +class GiveCommand : ParsedCommandExecutor() { + override fun execute(context: GiveCommandContext) { + val itemStack = ItemStack(context.item) + context.receiver.inventory.addItem(itemStack) + context.sender.sendMessage("Gave ${context.receiver.name} ${itemStack.type}!") + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt new file mode 100644 index 00000000..67e53776 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt @@ -0,0 +1,14 @@ +package com.github.spigotbasics.core.command.parsed + +import org.bukkit.Material +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player + +class GiveCommandContext( + sender: CommandSender, + val receiver: Player, + val item: Material, +) : ParsedCommandContext(sender) { + + +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt new file mode 100644 index 00000000..3f4569d6 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt @@ -0,0 +1,23 @@ +package com.github.spigotbasics.core.command.parsed + +import org.bukkit.command.Command +import org.bukkit.command.CommandSender + +class ParsedCommand : Command("give") { + + val argumentList: List>> = listOf( + "receiver" to ArgumentPlayer, + "material" to ArgumentMaterial, + ) + + + override fun execute(sender: CommandSender, commandLabel: String, args: Array): Boolean { + val argsList = args.toList() + argsList.forEachIndexed() { index, arg -> + val argument = argumentList[index] + val valueName = argument.first + val value = argument.second.parse(arg) + } + // But how do I turn this into a GiveCommandContext now?? + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt new file mode 100644 index 00000000..f4cd2870 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt @@ -0,0 +1,9 @@ +package com.github.spigotbasics.core.command.parsed + +import org.bukkit.command.CommandSender + +open class ParsedCommandContext(val sender: CommandSender) { + + + +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt new file mode 100644 index 00000000..877bafc5 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt @@ -0,0 +1,6 @@ +package com.github.spigotbasics.core.command.parsed + +abstract class ParsedCommandExecutor { + + abstract fun execute(context: T) +} From 21c2a5045e2033f6d4cb8dc9e81078041bc0c3e7 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 19:34:40 +0100 Subject: [PATCH 05/25] another attempt --- .../core/command/parsed/ParsedCommand.kt | 1 + .../core/command/parsed2/ArgumentPath.kt | 25 ++++++++++++++++ .../core/command/parsed2/Command.kt | 12 ++++++++ .../core/command/parsed2/CommandArgument.kt | 5 ++++ .../core/command/parsed2/CommandContext.kt | 3 ++ .../core/command/parsed2/GiveCommand.kt | 29 +++++++++++++++++++ .../command/parsed2/GiveCommandContext.kt | 6 ++++ .../core/command/parsed2/IntArgument.kt | 5 ++++ .../core/command/parsed2/MaterialArgument.kt | 9 ++++++ .../core/command/parsed2/PlayerArgument.kt | 10 +++++++ 10 files changed, 105 insertions(+) create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/IntArgument.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt index 3f4569d6..1e565fae 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt @@ -19,5 +19,6 @@ class ParsedCommand : Command("give") { val value = argument.second.parse(arg) } // But how do I turn this into a GiveCommandContext now?? + return true } } \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt new file mode 100644 index 00000000..213b16d8 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt @@ -0,0 +1,25 @@ +package com.github.spigotbasics.core.command.parsed2 + +class ArgumentPath( + private val arguments: List>, + private val contextBuilder: (List) -> T +) { + fun matches(args: List): Boolean { + if (args.size != arguments.size) return false + return arguments.zip(args).all { (arg, value) -> + try { + arg.parse(value) != null + } catch (e: Exception) { + false + } + } + } + + fun parse(args: List): T? { + if (!matches(args)) return null + val parsedArgs = arguments.zip(args).mapNotNull { (arg, value) -> + arg.parse(value) + } + return contextBuilder(parsedArgs) + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt new file mode 100644 index 00000000..d532038e --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt @@ -0,0 +1,12 @@ +package com.github.spigotbasics.core.command.parsed2 + +class Command(val paths: List) { + fun execute(input: String): CommandContext<*>? { + val args = input.split(" ") + for (path in paths) { + val context = path.parse(args) + if (context != null) return context + } + return null // No matching path found + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt new file mode 100644 index 00000000..75dcd4e6 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt @@ -0,0 +1,5 @@ +package com.github.spigotbasics.core.command.parsed2 + +abstract class CommandArgument { + abstract fun parse(value: String): T? +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt new file mode 100644 index 00000000..9780b603 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt @@ -0,0 +1,3 @@ +package com.github.spigotbasics.core.command.parsed2 + +interface CommandContext \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt new file mode 100644 index 00000000..f8448543 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt @@ -0,0 +1,29 @@ +package com.github.spigotbasics.core.command.parsed2 + +import org.bukkit.Material +import org.bukkit.entity.Player + + +val giveCommandPathBasic = ArgumentPath( + listOf(PlayerArgument(), MaterialArgument()) +) { parsedArgs -> + GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material) +} + +// Path for player, material, and amount +val giveCommandPathWithAmount = ArgumentPath( + listOf(PlayerArgument(), MaterialArgument(), IntArgument()) +) { parsedArgs -> + GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material, parsedArgs[2] as Int) +} + +class GiveCommand(private val paths: List>) { + fun execute(input: List): GiveCommandContext? { + for (path in paths) { + path.parse(input)?.let { return it } + } + return null // No matching path found + } +} + +val giveCommand = GiveCommand(listOf(giveCommandPathWithAmount, giveCommandPathBasic)) \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt new file mode 100644 index 00000000..9bcf8553 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt @@ -0,0 +1,6 @@ +package com.github.spigotbasics.core.command.parsed2 + +import org.bukkit.Material +import org.bukkit.entity.Player + +class GiveCommandContext(val receiver: Player, val material: Material, val amount: Int = 1) : CommandContext \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/IntArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/IntArgument.kt new file mode 100644 index 00000000..9ba77f84 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/IntArgument.kt @@ -0,0 +1,5 @@ +package com.github.spigotbasics.core.command.parsed2 + +class IntArgument : CommandArgument() { + override fun parse(value: String): Int? = value.toIntOrNull() +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt new file mode 100644 index 00000000..262071db --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt @@ -0,0 +1,9 @@ +package com.github.spigotbasics.core.command.parsed2 + +import org.bukkit.Material + +class MaterialArgument : CommandArgument() { + override fun parse(value: String): Material? { + return Material.valueOf(value.uppercase()) + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt new file mode 100644 index 00000000..17d6d11e --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt @@ -0,0 +1,10 @@ +package com.github.spigotbasics.core.command.parsed2 + +import org.bukkit.Bukkit +import org.bukkit.entity.Player + +class PlayerArgument : CommandArgument() { + override fun parse(value: String): Player? { + return Bukkit.getPlayer(value) + } +} \ No newline at end of file From ab99a324feba1cad0865cf1d35b6acd81cc92527 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 20:09:59 +0100 Subject: [PATCH 06/25] getting _somewhere_ --- .../core/command/ParsedCommand.kt | 13 ++-- .../command/arguments/ArgumentSignature.kt | 2 +- .../core/command/arguments/EnumArgument.kt | 2 +- .../arguments/EnumValueNotFoundException.kt | 6 +- .../core/command/parsed/Argument.kt | 2 +- .../core/command/parsed/ArgumentMaterial.kt | 2 +- .../core/command/parsed/ArgumentPlayer.kt | 2 +- .../core/command/parsed/GiveCommand.kt | 2 +- .../core/command/parsed/GiveCommandContext.kt | 5 +- .../core/command/parsed/ParsedCommand.kt | 21 ++--- .../command/parsed/ParsedCommandContext.kt | 6 +- .../command/parsed/ParsedCommandExecutor.kt | 3 +- .../core/command/parsed2/ArgumentPath.kt | 11 +-- .../core/command/parsed2/Command.kt | 19 +++-- .../core/command/parsed2/CommandArgument.kt | 2 +- .../core/command/parsed2/CommandContext.kt | 2 +- .../core/command/parsed2/CommandExecutor.kt | 5 ++ .../core/command/parsed2/GiveCommand.kt | 25 +++--- .../command/parsed2/GiveCommandContext.kt | 2 +- .../command/parsed2/GiveCommandExecutor.kt | 10 +++ .../core/command/parsed2/IntArgument.kt | 2 +- .../core/command/parsed2/MaterialArgument.kt | 2 +- .../command/parsed2/ParsedCommandBuilder.kt | 76 +++++++++++++++++++ .../core/command/parsed2/PlayerArgument.kt | 2 +- .../core/module/AbstractBasicsModule.kt | 9 +++ .../spigotbasics/core/module/BasicsModule.kt | 7 ++ modules/basics-give/build.gradle.kts | 3 + .../modules/basicsgive/BasicsGiveModule.kt | 39 ++++++++++ .../modules/basicsgive/GiveContext.kt | 9 +++ .../modules/basicsgive/GiveExecutor.kt | 12 +++ .../src/main/resources/basics-module.yml | 3 + 31 files changed, 240 insertions(+), 66 deletions(-) create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandExecutor.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandExecutor.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ParsedCommandBuilder.kt create mode 100644 modules/basics-give/build.gradle.kts create mode 100644 modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt create mode 100644 modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt create mode 100644 modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt create mode 100644 modules/basics-give/src/main/resources/basics-module.yml diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt index 0815d94a..0b5fa209 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt @@ -1,9 +1,6 @@ package com.github.spigotbasics.core.command import com.github.spigotbasics.core.command.arguments.ArgumentSignature -import org.bukkit.Bukkit -import org.bukkit.Material -import org.bukkit.Statistic import org.bukkit.command.Command import org.bukkit.command.CommandSender @@ -11,9 +8,11 @@ class ParsedCommand( val info: CommandInfo, val signatures: List>, ) : Command(info.name) { - override fun execute(sender: CommandSender, commandLabel: String, args: Array): Boolean { - - + override fun execute( + sender: CommandSender, + commandLabel: String, + args: Array, + ): Boolean { return false } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt index f5116510..3107d618 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt @@ -2,4 +2,4 @@ package com.github.spigotbasics.core.command.arguments import org.bukkit.command.CommandSender -class ArgumentSignature(val requiredSender: Class, val arguments: List>) +class ArgumentSignature(val requiredSender: Class, val arguments: List>) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt index 39ce1a58..d3f6cafc 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt @@ -3,7 +3,6 @@ package com.github.spigotbasics.core.command.arguments import com.github.spigotbasics.common.Dictionary class EnumArgument>(val enumClass: Class) : ArgumentType { - private val enumConstants: Dictionary init { @@ -12,6 +11,7 @@ class EnumArgument>(val enumClass: Class) : ArgumentType { enumConstants[constant.name] = constant } } + override fun parse(value: String): T { return enumConstants[value] ?: throw EnumValueNotFoundException(value, enumClass) } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt index b0b656f9..da93393a 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt @@ -1,5 +1,5 @@ package com.github.spigotbasics.core.command.arguments -class EnumValueNotFoundException(value: String, enumClass: Class<*>) : NoSuchElementException("Enum value not found: $value in enum class: $enumClass") { - -} +class EnumValueNotFoundException(value: String, enumClass: Class<*>) : NoSuchElementException( + "Enum value not found: $value in enum class: $enumClass", +) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt index cf2688e5..09c69d9b 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt @@ -2,4 +2,4 @@ package com.github.spigotbasics.core.command.parsed interface Argument { fun parse(value: String): T? -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt index 988aaf43..c9278936 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt @@ -6,4 +6,4 @@ object ArgumentMaterial : Argument { override fun parse(value: String): Material? { return Material.getMaterial(value) } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt index dcc9d52a..9e0da2e9 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt @@ -7,4 +7,4 @@ object ArgumentPlayer : Argument { override fun parse(value: String): Player? { return Bukkit.getPlayer(value) } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt index 93508fd2..b6b29a3c 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt @@ -8,4 +8,4 @@ class GiveCommand : ParsedCommandExecutor() { context.receiver.inventory.addItem(itemStack) context.sender.sendMessage("Gave ${context.receiver.name} ${itemStack.type}!") } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt index 67e53776..2799a371 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt @@ -8,7 +8,4 @@ class GiveCommandContext( sender: CommandSender, val receiver: Player, val item: Material, -) : ParsedCommandContext(sender) { - - -} +) : ParsedCommandContext(sender) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt index 1e565fae..f5a3907e 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt @@ -4,16 +4,19 @@ import org.bukkit.command.Command import org.bukkit.command.CommandSender class ParsedCommand : Command("give") { + val argumentList: List>> = + listOf( + "receiver" to ArgumentPlayer, + "material" to ArgumentMaterial, + ) - val argumentList: List>> = listOf( - "receiver" to ArgumentPlayer, - "material" to ArgumentMaterial, - ) - - - override fun execute(sender: CommandSender, commandLabel: String, args: Array): Boolean { + override fun execute( + sender: CommandSender, + commandLabel: String, + args: Array, + ): Boolean { val argsList = args.toList() - argsList.forEachIndexed() { index, arg -> + argsList.forEachIndexed { index, arg -> val argument = argumentList[index] val valueName = argument.first val value = argument.second.parse(arg) @@ -21,4 +24,4 @@ class ParsedCommand : Command("give") { // But how do I turn this into a GiveCommandContext now?? return true } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt index f4cd2870..8e7bdffc 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt @@ -2,8 +2,4 @@ package com.github.spigotbasics.core.command.parsed import org.bukkit.command.CommandSender -open class ParsedCommandContext(val sender: CommandSender) { - - - -} +open class ParsedCommandContext(val sender: CommandSender) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt index 877bafc5..25a2837c 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt @@ -1,6 +1,5 @@ package com.github.spigotbasics.core.command.parsed -abstract class ParsedCommandExecutor { - +abstract class ParsedCommandExecutor { abstract fun execute(context: T) } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt index 213b16d8..eb61e60c 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt @@ -2,7 +2,7 @@ package com.github.spigotbasics.core.command.parsed2 class ArgumentPath( private val arguments: List>, - private val contextBuilder: (List) -> T + private val contextBuilder: (List) -> T, ) { fun matches(args: List): Boolean { if (args.size != arguments.size) return false @@ -17,9 +17,10 @@ class ArgumentPath( fun parse(args: List): T? { if (!matches(args)) return null - val parsedArgs = arguments.zip(args).mapNotNull { (arg, value) -> - arg.parse(value) - } + val parsedArgs = + arguments.zip(args).mapNotNull { (arg, value) -> + arg.parse(value) + } return contextBuilder(parsedArgs) } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt index d532038e..c722160b 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt @@ -1,12 +1,17 @@ package com.github.spigotbasics.core.command.parsed2 -class Command(val paths: List) { - fun execute(input: String): CommandContext<*>? { - val args = input.split(" ") +class Command( + private val executor: CommandExecutor, + private val paths: List>, +) { + fun execute(input: List) { for (path in paths) { - val context = path.parse(args) - if (context != null) return context + val context = path.parse(input) + if (context != null) { + executor.execute(context) + return + } } - return null // No matching path found + // Handle no matching path found, e.g., show usage or error message } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt index 75dcd4e6..e1916aa3 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt @@ -2,4 +2,4 @@ package com.github.spigotbasics.core.command.parsed2 abstract class CommandArgument { abstract fun parse(value: String): T? -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt index 9780b603..84a1db25 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt @@ -1,3 +1,3 @@ package com.github.spigotbasics.core.command.parsed2 -interface CommandContext \ No newline at end of file +interface CommandContext diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandExecutor.kt new file mode 100644 index 00000000..84acee19 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandExecutor.kt @@ -0,0 +1,5 @@ +package com.github.spigotbasics.core.command.parsed2 + +interface CommandExecutor { + fun execute(context: T) +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt index f8448543..ef4dc6c5 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt @@ -3,19 +3,20 @@ package com.github.spigotbasics.core.command.parsed2 import org.bukkit.Material import org.bukkit.entity.Player - -val giveCommandPathBasic = ArgumentPath( - listOf(PlayerArgument(), MaterialArgument()) -) { parsedArgs -> - GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material) -} +val giveCommandPathBasic = + ArgumentPath( + listOf(PlayerArgument(), MaterialArgument()), + ) { parsedArgs -> + GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material) + } // Path for player, material, and amount -val giveCommandPathWithAmount = ArgumentPath( - listOf(PlayerArgument(), MaterialArgument(), IntArgument()) -) { parsedArgs -> - GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material, parsedArgs[2] as Int) -} +val giveCommandPathWithAmount = + ArgumentPath( + listOf(PlayerArgument(), MaterialArgument(), IntArgument()), + ) { parsedArgs -> + GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material, parsedArgs[2] as Int) + } class GiveCommand(private val paths: List>) { fun execute(input: List): GiveCommandContext? { @@ -26,4 +27,4 @@ class GiveCommand(private val paths: List>) { } } -val giveCommand = GiveCommand(listOf(giveCommandPathWithAmount, giveCommandPathBasic)) \ No newline at end of file +val giveCommand = GiveCommand(listOf(giveCommandPathWithAmount, giveCommandPathBasic)) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt index 9bcf8553..436a6248 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt @@ -3,4 +3,4 @@ package com.github.spigotbasics.core.command.parsed2 import org.bukkit.Material import org.bukkit.entity.Player -class GiveCommandContext(val receiver: Player, val material: Material, val amount: Int = 1) : CommandContext \ No newline at end of file +class GiveCommandContext(val receiver: Player, val material: Material, val amount: Int = 1) : CommandContext diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandExecutor.kt new file mode 100644 index 00000000..0ea128df --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandExecutor.kt @@ -0,0 +1,10 @@ +package com.github.spigotbasics.core.command.parsed2 + +import org.bukkit.inventory.ItemStack + +class GiveCommandExecutor : CommandExecutor { + override fun execute(context: GiveCommandContext) { + context.receiver.inventory.addItem(ItemStack(context.material, context.amount)) + println("Giving ${context.amount} of ${context.material} to ${context.receiver}") + } +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/IntArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/IntArgument.kt index 9ba77f84..ec0532a7 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/IntArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/IntArgument.kt @@ -2,4 +2,4 @@ package com.github.spigotbasics.core.command.parsed2 class IntArgument : CommandArgument() { override fun parse(value: String): Int? = value.toIntOrNull() -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt index 262071db..06c0bfa9 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt @@ -6,4 +6,4 @@ class MaterialArgument : CommandArgument() { override fun parse(value: String): Material? { return Material.valueOf(value.uppercase()) } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ParsedCommandBuilder.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ParsedCommandBuilder.kt new file mode 100644 index 00000000..0f4fb250 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ParsedCommandBuilder.kt @@ -0,0 +1,76 @@ +package com.github.spigotbasics.core.command + +import com.github.spigotbasics.core.command.parsed2.ArgumentPath +import com.github.spigotbasics.core.command.parsed2.Command +import com.github.spigotbasics.core.command.parsed2.CommandContext +import com.github.spigotbasics.core.command.parsed2.CommandExecutor +import com.github.spigotbasics.core.messages.Message +import com.github.spigotbasics.core.module.BasicsModule +import org.bukkit.permissions.Permission + +class ParsedCommandBuilder( + private val module: BasicsModule, + private val name: String, + private val permission: Permission, +) { + private var permissionMessage: Message = module.plugin.messages.noPermission + private var description: String? = null + private var usage: String = "" + private var aliases: List = emptyList() + private var executor: BasicsCommandExecutor? = null + private var tabCompleter: BasicsTabCompleter? = null + private var parsedExecutor: CommandExecutor? = null + private var argumentPaths: List>? = null + + fun description(description: String) = apply { this.description = description } + + fun usage(usage: String) = + apply { + if (usage.startsWith("/")) error("Usage should not start with / - only pass the arguments.") + this.usage = usage + } + + fun paths(argumentPaths: List>) = apply { this.argumentPaths = argumentPaths } + + fun executor(executor: CommandExecutor) = apply { this.parsedExecutor = executor } + + private fun executor(executor: BasicsCommandExecutor) = apply { this.executor = executor } + + private fun executor(command: Command) = + apply { + this.executor = + object : BasicsCommandExecutor(module) { + override fun execute(context: BasicsCommandContext): CommandResult? { + command.execute(context.args) + return CommandResult.SUCCESS + } + } + } + + fun register(): BasicsCommand { + val command = build() + module.commandManager.registerCommand(command) + return command + } + + private fun build(): BasicsCommand { + val command = Command(parsedExecutor ?: error("parsedExecutor must be set"), argumentPaths ?: error("Argument paths must be set")) + executor(command) + val info = + CommandInfo( + name = name, + permission = permission, + permissionMessage = permissionMessage, + description = description, + usage = usage, + aliases = aliases, + ) + return BasicsCommand( + info = info, + executor = executor ?: error("Executor must be set"), + tabCompleter = tabCompleter ?: executor, + coreMessages = module.plugin.messages, + messageFactory = module.plugin.messageFactory, + ) + } +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt index 17d6d11e..df5d429a 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt @@ -7,4 +7,4 @@ class PlayerArgument : CommandArgument() { override fun parse(value: String): Player? { return Bukkit.getPlayer(value) } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/module/AbstractBasicsModule.kt b/core/src/main/kotlin/com/github/spigotbasics/core/module/AbstractBasicsModule.kt index 24ecafc5..682dc5e8 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/module/AbstractBasicsModule.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/module/AbstractBasicsModule.kt @@ -3,6 +3,8 @@ package com.github.spigotbasics.core.module import com.github.spigotbasics.core.NamespacedNamespacedKeyFactory import com.github.spigotbasics.core.command.BasicsCommandBuilder import com.github.spigotbasics.core.command.BasicsCommandManager +import com.github.spigotbasics.core.command.ParsedCommandBuilder +import com.github.spigotbasics.core.command.parsed2.CommandContext import com.github.spigotbasics.core.config.ConfigName import com.github.spigotbasics.core.config.SavedConfig import com.github.spigotbasics.core.event.BasicsEventBus @@ -150,4 +152,11 @@ abstract class AbstractBasicsModule(context: ModuleInstantiationContext) : Basic ): BasicsCommandBuilder { return BasicsCommandBuilder(this, name, permission) } + + final override fun createParsedCommand( + name: String, + permission: Permission, + ): ParsedCommandBuilder { + return ParsedCommandBuilder(this, name, permission) + } } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/module/BasicsModule.kt b/core/src/main/kotlin/com/github/spigotbasics/core/module/BasicsModule.kt index e9e4756f..ca3c9080 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/module/BasicsModule.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/module/BasicsModule.kt @@ -4,6 +4,8 @@ import com.github.spigotbasics.core.BasicsPlugin import com.github.spigotbasics.core.NamespacedNamespacedKeyFactory import com.github.spigotbasics.core.command.BasicsCommandBuilder import com.github.spigotbasics.core.command.BasicsCommandManager +import com.github.spigotbasics.core.command.ParsedCommandBuilder +import com.github.spigotbasics.core.command.parsed2.CommandContext import com.github.spigotbasics.core.config.ConfigName import com.github.spigotbasics.core.config.SavedConfig import com.github.spigotbasics.core.event.BasicsEventBus @@ -153,6 +155,11 @@ interface BasicsModule { permission: Permission, ): BasicsCommandBuilder + fun createParsedCommand( + name: String, + permission: Permission, + ): ParsedCommandBuilder + fun createStorage(name: String? = null): NamespacedStorage fun getConfig(configName: ConfigName): SavedConfig diff --git a/modules/basics-give/build.gradle.kts b/modules/basics-give/build.gradle.kts new file mode 100644 index 00000000..c1fb740e --- /dev/null +++ b/modules/basics-give/build.gradle.kts @@ -0,0 +1,3 @@ +plugins { + id("basics.module") +} diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt new file mode 100644 index 00000000..873a0c99 --- /dev/null +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt @@ -0,0 +1,39 @@ +package com.github.spigotbasics.modules.basicsgive + +import com.github.spigotbasics.core.command.parsed2.ArgumentPath +import com.github.spigotbasics.core.command.parsed2.GiveCommandContext +import com.github.spigotbasics.core.command.parsed2.IntArgument +import com.github.spigotbasics.core.command.parsed2.MaterialArgument +import com.github.spigotbasics.core.command.parsed2.PlayerArgument +import com.github.spigotbasics.core.module.AbstractBasicsModule +import com.github.spigotbasics.core.module.loader.ModuleInstantiationContext +import org.bukkit.Material +import org.bukkit.entity.Player + +class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModule(context) { + val permission = + permissionManager.createSimplePermission("basics.give", "Allows the player to use the /give command") + + + val giveCommandPathBasic = + ArgumentPath( + listOf(PlayerArgument(), MaterialArgument()), + ) { parsedArgs -> + GiveContext(parsedArgs[0] as Player, parsedArgs[1] as Material) + } + + val giveCommandPathWithAmount = + ArgumentPath( + listOf(PlayerArgument(), MaterialArgument(), IntArgument()), + ) { parsedArgs -> + GiveContext(parsedArgs[0] as Player, parsedArgs[1] as Material, parsedArgs[2] as Int) + } + + + override fun onEnable() { + createParsedCommand("give", permission) + .paths(listOf(giveCommandPathWithAmount, giveCommandPathBasic)) + .executor(GiveExecutor()) + .register() + } +} diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt new file mode 100644 index 00000000..9c56ca90 --- /dev/null +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt @@ -0,0 +1,9 @@ +package com.github.spigotbasics.modules.basicsgive + +import com.github.spigotbasics.core.command.parsed2.CommandContext +import org.bukkit.Material +import org.bukkit.entity.Player + +class GiveContext(val receiver: Player, val material: Material, val amount: Int = 1) : CommandContext { + +} diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt new file mode 100644 index 00000000..7192e662 --- /dev/null +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt @@ -0,0 +1,12 @@ +package com.github.spigotbasics.modules.basicsgive + +import com.github.spigotbasics.core.command.parsed2.CommandExecutor +import com.github.spigotbasics.core.command.parsed2.GiveCommandContext +import org.bukkit.inventory.ItemStack + +class GiveExecutor : CommandExecutor { + override fun execute(context: GiveContext) { + context.receiver.inventory.addItem(ItemStack(context.material, context.amount)) + println("Giving ${context.amount} of ${context.material} to ${context.receiver}") + } +} \ No newline at end of file diff --git a/modules/basics-give/src/main/resources/basics-module.yml b/modules/basics-give/src/main/resources/basics-module.yml new file mode 100644 index 00000000..038f9d0a --- /dev/null +++ b/modules/basics-give/src/main/resources/basics-module.yml @@ -0,0 +1,3 @@ +main-class: com.github.spigotbasics.modules.basicsgive.BasicsGiveModule +name: basics-give +version: ${moduleVersion} \ No newline at end of file From a8016844db0dd42061d5510f7aab0deaf48e761b Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 20:39:24 +0100 Subject: [PATCH 07/25] This is actually looking good now! --- .../github/spigotbasics/common/Dictionary.kt | 23 +++++- .../core/command/parsed/Argument.kt | 5 -- .../core/command/parsed/ArgumentMaterial.kt | 9 --- .../core/command/parsed/ArgumentPath.kt | 70 +++++++++++++++++++ .../core/command/parsed/ArgumentPlayer.kt | 10 --- .../core/command/parsed/Command.kt | 50 +++++++++++++ .../core/command/parsed/CommandArgument.kt | 7 ++ .../core/command/parsed/CommandContext.kt | 3 + .../{parsed2 => parsed}/CommandExecutor.kt | 2 +- .../core/command/parsed/GiveCommand.kt | 41 ++++++++--- .../core/command/parsed/GiveCommandContext.kt | 7 +- .../GiveCommandExecutor.kt | 2 +- .../{parsed2 => parsed}/IntArgument.kt | 2 +- .../core/command/parsed/MaterialArgument.kt | 18 +++++ .../core/command/parsed/ParseResult.kt | 6 ++ .../core/command/parsed/ParsedCommand.kt | 27 ------- .../ParsedCommandBuilder.kt | 33 +++++++-- .../command/parsed/ParsedCommandContext.kt | 5 -- .../command/parsed/ParsedCommandExecutor.kt | 5 -- .../core/command/parsed/PlayerArgument.kt | 18 +++++ .../core/command/parsed2/ArgumentPath.kt | 26 ------- .../core/command/parsed2/Command.kt | 17 ----- .../core/command/parsed2/CommandArgument.kt | 5 -- .../core/command/parsed2/CommandContext.kt | 3 - .../core/command/parsed2/GiveCommand.kt | 30 -------- .../command/parsed2/GiveCommandContext.kt | 6 -- .../core/command/parsed2/MaterialArgument.kt | 9 --- .../core/command/parsed2/PlayerArgument.kt | 10 --- .../core/module/AbstractBasicsModule.kt | 2 +- .../spigotbasics/core/module/BasicsModule.kt | 2 +- .../modules/basicsgive/BasicsGiveModule.kt | 10 +-- .../modules/basicsgive/GiveContext.kt | 2 +- .../modules/basicsgive/GiveExecutor.kt | 4 +- 33 files changed, 264 insertions(+), 205 deletions(-) delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandContext.kt rename core/src/main/kotlin/com/github/spigotbasics/core/command/{parsed2 => parsed}/CommandExecutor.kt (59%) rename core/src/main/kotlin/com/github/spigotbasics/core/command/{parsed2 => parsed}/GiveCommandExecutor.kt (86%) rename core/src/main/kotlin/com/github/spigotbasics/core/command/{parsed2 => parsed}/IntArgument.kt (68%) create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/MaterialArgument.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt rename core/src/main/kotlin/com/github/spigotbasics/core/command/{parsed2 => parsed}/ParsedCommandBuilder.kt (67%) delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PlayerArgument.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt diff --git a/common/src/main/kotlin/com/github/spigotbasics/common/Dictionary.kt b/common/src/main/kotlin/com/github/spigotbasics/common/Dictionary.kt index 246fb742..66bd74d0 100644 --- a/common/src/main/kotlin/com/github/spigotbasics/common/Dictionary.kt +++ b/common/src/main/kotlin/com/github/spigotbasics/common/Dictionary.kt @@ -8,4 +8,25 @@ import java.util.TreeMap * @param T The type of the values in the map. * @constructor Create empty Dictionary */ -class Dictionary : MutableMap, TreeMap(String.CASE_INSENSITIVE_ORDER) +class Dictionary : MutableMap, TreeMap(String.CASE_INSENSITIVE_ORDER) { + + companion object { + fun fromEnum(enumClass: Class>, lowercase: Boolean = false): Dictionary> { + val dictionary = Dictionary>() + for (enumConstant in enumClass.enumConstants) { + val name = if (lowercase) enumConstant.name.lowercase() else enumConstant.name + dictionary[name] = enumConstant + } + return dictionary + } + + fun from(entries: List>): Dictionary { + val dictionary = Dictionary() + for ((key, value) in entries) { + dictionary[key] = value + } + return dictionary + } + } + +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt deleted file mode 100644 index 09c69d9b..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Argument.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.spigotbasics.core.command.parsed - -interface Argument { - fun parse(value: String): T? -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt deleted file mode 100644 index c9278936..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentMaterial.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.github.spigotbasics.core.command.parsed - -import org.bukkit.Material - -object ArgumentMaterial : Argument { - override fun parse(value: String): Material? { - return Material.getMaterial(value) - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt new file mode 100644 index 00000000..ef4da5ca --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt @@ -0,0 +1,70 @@ +package com.github.spigotbasics.core.command.parsed + +class ArgumentPath( + private val arguments: List>, + private val contextBuilder: (List) -> T, +) { + fun matches(args: List): Boolean { + if (args.size != arguments.size) return false + return arguments.zip(args).all { (arg, value) -> + try { + arg.parse(value) != null + } catch (e: Exception) { + false + } + } + } + +// fun parse(args: List): T? { +// if (!matches(args)) return null +// val parsedArgs = +// arguments.zip(args).mapNotNull { (arg, value) -> +// arg.parse(value) +// } +// return contextBuilder(parsedArgs) +// } + + fun parse(args: List): ParseResult { + val parsedArgs = mutableListOf() + val errors = mutableListOf() + + for ((index, arg) in arguments.withIndex()) { + if (index >= args.size) { + errors.add("Missing argument for ${arg::class.simpleName}") + break + } + + val parsed = arg.parse(args[index]) + if (parsed == null) { + errors.add(arg.errorMessage(args[index])) + break + } else { + parsedArgs.add(parsed) + } + } + + if (errors.isEmpty() && parsedArgs.size == arguments.size) { + return ParseResult.Success(contextBuilder(parsedArgs)) + } else { + return ParseResult.Failure(errors) + } + } + + fun tabComplete(args: List): List { + // If the current args size is less than or equal to the arguments size, + // suggest completions for the current argument. + if (args.size <= arguments.size) { + val currentArgIndex = args.size - 1 + // If exactly equal, user is typing the next argument (or just started typing the first one) + return if (args.size == arguments.size) { + arguments.getOrNull(currentArgIndex)?.tabComplete() ?: emptyList() + } else { + // User is in the middle of typing an argument; suggest completions for this arg + arguments.getOrNull(currentArgIndex)?.tabComplete()?.filter { + it.startsWith(args.last(), ignoreCase = true) + } ?: emptyList() + } + } + return emptyList() + } +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt deleted file mode 100644 index 9e0da2e9..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPlayer.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.spigotbasics.core.command.parsed - -import org.bukkit.Bukkit -import org.bukkit.entity.Player - -object ArgumentPlayer : Argument { - override fun parse(value: String): Player? { - return Bukkit.getPlayer(value) - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt new file mode 100644 index 00000000..28538efc --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt @@ -0,0 +1,50 @@ +package com.github.spigotbasics.core.command.parsed + +import com.github.spigotbasics.common.Either +import com.github.spigotbasics.core.command.CommandResult + +class Command( + private val executor: CommandExecutor, + private val paths: List>, +) { +// fun execute(input: List) { +// for (path in paths) { +// val context = path.parse(input) +// if (context != null) { +// executor.execute(context) +// return +// } +// } +// // Handle no matching path found, e.g., show usage or error message +// } + + fun execute(input: List): Either { + for (path in paths) { + when (val result = path.parse(input)) { + is ParseResult.Success -> { + executor.execute(result.context) + return Either.Left(CommandResult.SUCCESS) + } + is ParseResult.Failure -> { + // Handle or display errors + result.errors.forEach { println(it) } + return Either.Right(result) + } + } + } + // If no paths matched, optionally print a generic error or usage message + println("Invalid command syntax.") + return Either.Left(CommandResult.USAGE) + } + + fun tabComplete(input: List): List { + // Attempt to find the best matching ArgumentPath for the current input + // and return its tab completions. + val completions = mutableListOf() + for (path in paths) { + completions.addAll(path.tabComplete(input)) + } + // Remove duplicates and return + return completions.distinct() + } +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt new file mode 100644 index 00000000..d1343482 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt @@ -0,0 +1,7 @@ +package com.github.spigotbasics.core.command.parsed + +abstract class CommandArgument { + abstract fun parse(value: String): T? + open fun tabComplete(): List = emptyList() + open fun errorMessage(value: String? = null): String = "Invalid value $value for argument ${this::class.simpleName}" +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandContext.kt new file mode 100644 index 00000000..8b0646df --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandContext.kt @@ -0,0 +1,3 @@ +package com.github.spigotbasics.core.command.parsed + +interface CommandContext diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandExecutor.kt similarity index 59% rename from core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandExecutor.kt rename to core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandExecutor.kt index 84acee19..668bee3c 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandExecutor.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandExecutor.kt @@ -1,4 +1,4 @@ -package com.github.spigotbasics.core.command.parsed2 +package com.github.spigotbasics.core.command.parsed interface CommandExecutor { fun execute(context: T) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt index b6b29a3c..90c4c13f 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt @@ -1,11 +1,30 @@ -package com.github.spigotbasics.core.command.parsed - -import org.bukkit.inventory.ItemStack - -class GiveCommand : ParsedCommandExecutor() { - override fun execute(context: GiveCommandContext) { - val itemStack = ItemStack(context.item) - context.receiver.inventory.addItem(itemStack) - context.sender.sendMessage("Gave ${context.receiver.name} ${itemStack.type}!") - } -} +//package com.github.spigotbasics.core.command.parsed +// +//import org.bukkit.Material +//import org.bukkit.entity.Player +// +//val giveCommandPathBasic = +// ArgumentPath( +// listOf(PlayerArgument(), MaterialArgument()), +// ) { parsedArgs -> +// GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material) +// } +// +//// Path for player, material, and amount +//val giveCommandPathWithAmount = +// ArgumentPath( +// listOf(PlayerArgument(), MaterialArgument(), IntArgument()), +// ) { parsedArgs -> +// GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material, parsedArgs[2] as Int) +// } +// +//class GiveCommand(private val paths: List>) { +// fun execute(input: List): GiveCommandContext? { +// for (path in paths) { +// path.parse(input)?.let { return it } +// } +// return null // No matching path found +// } +//} +// +//val giveCommand = GiveCommand(listOf(giveCommandPathWithAmount, giveCommandPathBasic)) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt index 2799a371..739b0004 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt @@ -1,11 +1,6 @@ package com.github.spigotbasics.core.command.parsed import org.bukkit.Material -import org.bukkit.command.CommandSender import org.bukkit.entity.Player -class GiveCommandContext( - sender: CommandSender, - val receiver: Player, - val item: Material, -) : ParsedCommandContext(sender) +class GiveCommandContext(val receiver: Player, val material: Material, val amount: Int = 1) : CommandContext diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandExecutor.kt similarity index 86% rename from core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandExecutor.kt rename to core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandExecutor.kt index 0ea128df..79a489db 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandExecutor.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandExecutor.kt @@ -1,4 +1,4 @@ -package com.github.spigotbasics.core.command.parsed2 +package com.github.spigotbasics.core.command.parsed import org.bukkit.inventory.ItemStack diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/IntArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/IntArgument.kt similarity index 68% rename from core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/IntArgument.kt rename to core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/IntArgument.kt index ec0532a7..974b0172 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/IntArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/IntArgument.kt @@ -1,4 +1,4 @@ -package com.github.spigotbasics.core.command.parsed2 +package com.github.spigotbasics.core.command.parsed class IntArgument : CommandArgument() { override fun parse(value: String): Int? = value.toIntOrNull() diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/MaterialArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/MaterialArgument.kt new file mode 100644 index 00000000..a83eed2d --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/MaterialArgument.kt @@ -0,0 +1,18 @@ +package com.github.spigotbasics.core.command.parsed + +import com.github.spigotbasics.common.Dictionary +import org.bukkit.Material + +class MaterialArgument : CommandArgument() { + + private val materials = Dictionary.from(Material.entries.filter { it.isItem }.map { it.name to it }) + private val materialNames = materials.keys.toList().sorted() + + override fun parse(value: String): Material? { + return materials[value] + } + + override fun tabComplete(): List { + return materialNames + } +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt new file mode 100644 index 00000000..0f6e22ff --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt @@ -0,0 +1,6 @@ +package com.github.spigotbasics.core.command.parsed + +sealed class ParseResult { + data class Success(val context: T) : ParseResult() + data class Failure(val errors: List) : ParseResult() +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt deleted file mode 100644 index f5a3907e..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommand.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.spigotbasics.core.command.parsed - -import org.bukkit.command.Command -import org.bukkit.command.CommandSender - -class ParsedCommand : Command("give") { - val argumentList: List>> = - listOf( - "receiver" to ArgumentPlayer, - "material" to ArgumentMaterial, - ) - - override fun execute( - sender: CommandSender, - commandLabel: String, - args: Array, - ): Boolean { - val argsList = args.toList() - argsList.forEachIndexed { index, arg -> - val argument = argumentList[index] - val valueName = argument.first - val value = argument.second.parse(arg) - } - // But how do I turn this into a GiveCommandContext now?? - return true - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ParsedCommandBuilder.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt similarity index 67% rename from core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ParsedCommandBuilder.kt rename to core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt index 0f4fb250..4d2383f9 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ParsedCommandBuilder.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt @@ -1,9 +1,10 @@ package com.github.spigotbasics.core.command -import com.github.spigotbasics.core.command.parsed2.ArgumentPath -import com.github.spigotbasics.core.command.parsed2.Command -import com.github.spigotbasics.core.command.parsed2.CommandContext -import com.github.spigotbasics.core.command.parsed2.CommandExecutor +import com.github.spigotbasics.common.Either +import com.github.spigotbasics.core.command.parsed.ArgumentPath +import com.github.spigotbasics.core.command.parsed.Command +import com.github.spigotbasics.core.command.parsed.CommandContext +import com.github.spigotbasics.core.command.parsed.CommandExecutor import com.github.spigotbasics.core.messages.Message import com.github.spigotbasics.core.module.BasicsModule import org.bukkit.permissions.Permission @@ -41,8 +42,23 @@ class ParsedCommandBuilder( this.executor = object : BasicsCommandExecutor(module) { override fun execute(context: BasicsCommandContext): CommandResult? { - command.execute(context.args) - return CommandResult.SUCCESS + val result = command.execute(context.args) + + if (result is Either.Left) { + return result.value + } + + if (result is Either.Right) { + val failure = result.value + // TODO: Proper messages + failure.errors.forEach(context.sender::sendMessage) + } + + return null + } + + override fun tabComplete(context: BasicsCommandContext): MutableList { + return command.tabComplete(context.args).toMutableList() } } } @@ -54,7 +70,10 @@ class ParsedCommandBuilder( } private fun build(): BasicsCommand { - val command = Command(parsedExecutor ?: error("parsedExecutor must be set"), argumentPaths ?: error("Argument paths must be set")) + val command = Command( + parsedExecutor ?: error("parsedExecutor must be set"), + argumentPaths ?: error("Argument paths must be set") + ) executor(command) val info = CommandInfo( diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt deleted file mode 100644 index 8e7bdffc..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandContext.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.spigotbasics.core.command.parsed - -import org.bukkit.command.CommandSender - -open class ParsedCommandContext(val sender: CommandSender) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt deleted file mode 100644 index 25a2837c..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.spigotbasics.core.command.parsed - -abstract class ParsedCommandExecutor { - abstract fun execute(context: T) -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PlayerArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PlayerArgument.kt new file mode 100644 index 00000000..233f64e6 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PlayerArgument.kt @@ -0,0 +1,18 @@ +package com.github.spigotbasics.core.command.parsed + +import org.bukkit.Bukkit +import org.bukkit.entity.Player + +class PlayerArgument : CommandArgument() { + override fun parse(value: String): Player? { + return Bukkit.getPlayer(value) + } + + override fun tabComplete(): MutableList { + return Bukkit.getOnlinePlayers().map { it.name }.toMutableList() + } + + override fun errorMessage(value: String?): String { + return "Player $value not found" + } +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt deleted file mode 100644 index eb61e60c..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/ArgumentPath.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.github.spigotbasics.core.command.parsed2 - -class ArgumentPath( - private val arguments: List>, - private val contextBuilder: (List) -> T, -) { - fun matches(args: List): Boolean { - if (args.size != arguments.size) return false - return arguments.zip(args).all { (arg, value) -> - try { - arg.parse(value) != null - } catch (e: Exception) { - false - } - } - } - - fun parse(args: List): T? { - if (!matches(args)) return null - val parsedArgs = - arguments.zip(args).mapNotNull { (arg, value) -> - arg.parse(value) - } - return contextBuilder(parsedArgs) - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt deleted file mode 100644 index c722160b..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/Command.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.github.spigotbasics.core.command.parsed2 - -class Command( - private val executor: CommandExecutor, - private val paths: List>, -) { - fun execute(input: List) { - for (path in paths) { - val context = path.parse(input) - if (context != null) { - executor.execute(context) - return - } - } - // Handle no matching path found, e.g., show usage or error message - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt deleted file mode 100644 index e1916aa3..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandArgument.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.spigotbasics.core.command.parsed2 - -abstract class CommandArgument { - abstract fun parse(value: String): T? -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt deleted file mode 100644 index 84a1db25..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/CommandContext.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.github.spigotbasics.core.command.parsed2 - -interface CommandContext diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt deleted file mode 100644 index ef4dc6c5..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommand.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.github.spigotbasics.core.command.parsed2 - -import org.bukkit.Material -import org.bukkit.entity.Player - -val giveCommandPathBasic = - ArgumentPath( - listOf(PlayerArgument(), MaterialArgument()), - ) { parsedArgs -> - GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material) - } - -// Path for player, material, and amount -val giveCommandPathWithAmount = - ArgumentPath( - listOf(PlayerArgument(), MaterialArgument(), IntArgument()), - ) { parsedArgs -> - GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material, parsedArgs[2] as Int) - } - -class GiveCommand(private val paths: List>) { - fun execute(input: List): GiveCommandContext? { - for (path in paths) { - path.parse(input)?.let { return it } - } - return null // No matching path found - } -} - -val giveCommand = GiveCommand(listOf(giveCommandPathWithAmount, giveCommandPathBasic)) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt deleted file mode 100644 index 436a6248..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/GiveCommandContext.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.github.spigotbasics.core.command.parsed2 - -import org.bukkit.Material -import org.bukkit.entity.Player - -class GiveCommandContext(val receiver: Player, val material: Material, val amount: Int = 1) : CommandContext diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt deleted file mode 100644 index 06c0bfa9..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/MaterialArgument.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.github.spigotbasics.core.command.parsed2 - -import org.bukkit.Material - -class MaterialArgument : CommandArgument() { - override fun parse(value: String): Material? { - return Material.valueOf(value.uppercase()) - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt deleted file mode 100644 index df5d429a..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed2/PlayerArgument.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.spigotbasics.core.command.parsed2 - -import org.bukkit.Bukkit -import org.bukkit.entity.Player - -class PlayerArgument : CommandArgument() { - override fun parse(value: String): Player? { - return Bukkit.getPlayer(value) - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/module/AbstractBasicsModule.kt b/core/src/main/kotlin/com/github/spigotbasics/core/module/AbstractBasicsModule.kt index 682dc5e8..981ec4ad 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/module/AbstractBasicsModule.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/module/AbstractBasicsModule.kt @@ -4,7 +4,7 @@ import com.github.spigotbasics.core.NamespacedNamespacedKeyFactory import com.github.spigotbasics.core.command.BasicsCommandBuilder import com.github.spigotbasics.core.command.BasicsCommandManager import com.github.spigotbasics.core.command.ParsedCommandBuilder -import com.github.spigotbasics.core.command.parsed2.CommandContext +import com.github.spigotbasics.core.command.parsed.CommandContext import com.github.spigotbasics.core.config.ConfigName import com.github.spigotbasics.core.config.SavedConfig import com.github.spigotbasics.core.event.BasicsEventBus diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/module/BasicsModule.kt b/core/src/main/kotlin/com/github/spigotbasics/core/module/BasicsModule.kt index ca3c9080..4712e160 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/module/BasicsModule.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/module/BasicsModule.kt @@ -5,7 +5,7 @@ import com.github.spigotbasics.core.NamespacedNamespacedKeyFactory import com.github.spigotbasics.core.command.BasicsCommandBuilder import com.github.spigotbasics.core.command.BasicsCommandManager import com.github.spigotbasics.core.command.ParsedCommandBuilder -import com.github.spigotbasics.core.command.parsed2.CommandContext +import com.github.spigotbasics.core.command.parsed.CommandContext import com.github.spigotbasics.core.config.ConfigName import com.github.spigotbasics.core.config.SavedConfig import com.github.spigotbasics.core.event.BasicsEventBus diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt index 873a0c99..ee80e836 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt @@ -1,10 +1,10 @@ package com.github.spigotbasics.modules.basicsgive -import com.github.spigotbasics.core.command.parsed2.ArgumentPath -import com.github.spigotbasics.core.command.parsed2.GiveCommandContext -import com.github.spigotbasics.core.command.parsed2.IntArgument -import com.github.spigotbasics.core.command.parsed2.MaterialArgument -import com.github.spigotbasics.core.command.parsed2.PlayerArgument +import com.github.spigotbasics.core.command.parsed.ArgumentPath +import com.github.spigotbasics.core.command.parsed.GiveCommandContext +import com.github.spigotbasics.core.command.parsed.IntArgument +import com.github.spigotbasics.core.command.parsed.MaterialArgument +import com.github.spigotbasics.core.command.parsed.PlayerArgument import com.github.spigotbasics.core.module.AbstractBasicsModule import com.github.spigotbasics.core.module.loader.ModuleInstantiationContext import org.bukkit.Material diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt index 9c56ca90..3cdffea5 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt @@ -1,6 +1,6 @@ package com.github.spigotbasics.modules.basicsgive -import com.github.spigotbasics.core.command.parsed2.CommandContext +import com.github.spigotbasics.core.command.parsed.CommandContext import org.bukkit.Material import org.bukkit.entity.Player diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt index 7192e662..0f9097fd 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt @@ -1,7 +1,7 @@ package com.github.spigotbasics.modules.basicsgive -import com.github.spigotbasics.core.command.parsed2.CommandExecutor -import com.github.spigotbasics.core.command.parsed2.GiveCommandContext +import com.github.spigotbasics.core.command.parsed.CommandExecutor +import com.github.spigotbasics.core.command.parsed.GiveCommandContext import org.bukkit.inventory.ItemStack class GiveExecutor : CommandExecutor { From 788f75a7df9cd62bd9bb990952973e32d169dd69 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 20:47:57 +0100 Subject: [PATCH 08/25] Working fine - now we only need configurable messages! --- .../command/arguments/ArgumentSignature.kt | 5 ---- .../core/command/arguments/ArgumentType.kt | 7 ----- .../core/command/arguments/EnumArgument.kt | 18 ----------- .../arguments/EnumValueNotFoundException.kt | 5 ---- .../core/command/arguments/PlayerArgument.kt | 14 --------- .../arguments/PlayerNotFoundException.kt | 3 -- .../core/command/parsed/GiveCommand.kt | 30 ------------------- .../core/command/parsed/GiveCommandContext.kt | 6 ---- .../command/parsed/GiveCommandExecutor.kt | 10 ------- .../core/command/parsed/IntArgument.kt | 5 ---- .../command/parsed/arguments/IntArgument.kt | 7 +++++ .../{ => arguments}/MaterialArgument.kt | 3 +- .../parsed/{ => arguments}/PlayerArgument.kt | 3 +- .../modules/basicsgive/BasicsGiveModule.kt | 7 ++--- .../modules/basicsgive/GiveExecutor.kt | 1 - 15 files changed, 14 insertions(+), 110 deletions(-) delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerArgument.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerNotFoundException.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandExecutor.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/IntArgument.kt create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArgument.kt rename core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/{ => arguments}/MaterialArgument.kt (78%) rename core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/{ => arguments}/PlayerArgument.kt (77%) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt deleted file mode 100644 index 3107d618..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentSignature.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.spigotbasics.core.command.arguments - -import org.bukkit.command.CommandSender - -class ArgumentSignature(val requiredSender: Class, val arguments: List>) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt deleted file mode 100644 index 98223370..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/ArgumentType.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.github.spigotbasics.core.command.arguments - -interface ArgumentType { - fun parse(value: String): T - - fun tabComplete(value: String): MutableList? = null -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt deleted file mode 100644 index d3f6cafc..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumArgument.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.github.spigotbasics.core.command.arguments - -import com.github.spigotbasics.common.Dictionary - -class EnumArgument>(val enumClass: Class) : ArgumentType { - private val enumConstants: Dictionary - - init { - enumConstants = Dictionary() - for (constant in enumClass.enumConstants) { - enumConstants[constant.name] = constant - } - } - - override fun parse(value: String): T { - return enumConstants[value] ?: throw EnumValueNotFoundException(value, enumClass) - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt deleted file mode 100644 index da93393a..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/EnumValueNotFoundException.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.spigotbasics.core.command.arguments - -class EnumValueNotFoundException(value: String, enumClass: Class<*>) : NoSuchElementException( - "Enum value not found: $value in enum class: $enumClass", -) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerArgument.kt deleted file mode 100644 index 00e21ff4..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerArgument.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.github.spigotbasics.core.command.arguments - -import org.bukkit.Bukkit -import org.bukkit.entity.Player - -object PlayerArgument : ArgumentType { - override fun parse(value: String): Player { - val player = Bukkit.getPlayer(value) - if (player == null) { - throw PlayerNotFoundException(value) - } - return player - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerNotFoundException.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerNotFoundException.kt deleted file mode 100644 index 2d6e8664..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/arguments/PlayerNotFoundException.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.github.spigotbasics.core.command.arguments - -class PlayerNotFoundException(value: String) : IllegalArgumentException("Player not found: $value") diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt deleted file mode 100644 index 90c4c13f..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommand.kt +++ /dev/null @@ -1,30 +0,0 @@ -//package com.github.spigotbasics.core.command.parsed -// -//import org.bukkit.Material -//import org.bukkit.entity.Player -// -//val giveCommandPathBasic = -// ArgumentPath( -// listOf(PlayerArgument(), MaterialArgument()), -// ) { parsedArgs -> -// GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material) -// } -// -//// Path for player, material, and amount -//val giveCommandPathWithAmount = -// ArgumentPath( -// listOf(PlayerArgument(), MaterialArgument(), IntArgument()), -// ) { parsedArgs -> -// GiveCommandContext(parsedArgs[0] as Player, parsedArgs[1] as Material, parsedArgs[2] as Int) -// } -// -//class GiveCommand(private val paths: List>) { -// fun execute(input: List): GiveCommandContext? { -// for (path in paths) { -// path.parse(input)?.let { return it } -// } -// return null // No matching path found -// } -//} -// -//val giveCommand = GiveCommand(listOf(giveCommandPathWithAmount, giveCommandPathBasic)) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt deleted file mode 100644 index 739b0004..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandContext.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.github.spigotbasics.core.command.parsed - -import org.bukkit.Material -import org.bukkit.entity.Player - -class GiveCommandContext(val receiver: Player, val material: Material, val amount: Int = 1) : CommandContext diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandExecutor.kt deleted file mode 100644 index 79a489db..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/GiveCommandExecutor.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.spigotbasics.core.command.parsed - -import org.bukkit.inventory.ItemStack - -class GiveCommandExecutor : CommandExecutor { - override fun execute(context: GiveCommandContext) { - context.receiver.inventory.addItem(ItemStack(context.material, context.amount)) - println("Giving ${context.amount} of ${context.material} to ${context.receiver}") - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/IntArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/IntArgument.kt deleted file mode 100644 index 974b0172..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/IntArgument.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.spigotbasics.core.command.parsed - -class IntArgument : CommandArgument() { - override fun parse(value: String): Int? = value.toIntOrNull() -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArgument.kt new file mode 100644 index 00000000..28de3cc4 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArgument.kt @@ -0,0 +1,7 @@ +package com.github.spigotbasics.core.command.parsed.arguments + +import com.github.spigotbasics.core.command.parsed.CommandArgument + +class IntArgument : CommandArgument() { + override fun parse(value: String): Int? = value.toIntOrNull() +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/MaterialArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt similarity index 78% rename from core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/MaterialArgument.kt rename to core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt index a83eed2d..17d63a37 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/MaterialArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt @@ -1,6 +1,7 @@ -package com.github.spigotbasics.core.command.parsed +package com.github.spigotbasics.core.command.parsed.arguments import com.github.spigotbasics.common.Dictionary +import com.github.spigotbasics.core.command.parsed.CommandArgument import org.bukkit.Material class MaterialArgument : CommandArgument() { diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PlayerArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArgument.kt similarity index 77% rename from core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PlayerArgument.kt rename to core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArgument.kt index 233f64e6..2a8059e6 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PlayerArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArgument.kt @@ -1,5 +1,6 @@ -package com.github.spigotbasics.core.command.parsed +package com.github.spigotbasics.core.command.parsed.arguments +import com.github.spigotbasics.core.command.parsed.CommandArgument import org.bukkit.Bukkit import org.bukkit.entity.Player diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt index ee80e836..3ec2f02a 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt @@ -1,10 +1,9 @@ package com.github.spigotbasics.modules.basicsgive import com.github.spigotbasics.core.command.parsed.ArgumentPath -import com.github.spigotbasics.core.command.parsed.GiveCommandContext -import com.github.spigotbasics.core.command.parsed.IntArgument -import com.github.spigotbasics.core.command.parsed.MaterialArgument -import com.github.spigotbasics.core.command.parsed.PlayerArgument +import com.github.spigotbasics.core.command.parsed.arguments.IntArgument +import com.github.spigotbasics.core.command.parsed.arguments.MaterialArgument +import com.github.spigotbasics.core.command.parsed.arguments.PlayerArgument import com.github.spigotbasics.core.module.AbstractBasicsModule import com.github.spigotbasics.core.module.loader.ModuleInstantiationContext import org.bukkit.Material diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt index 0f9097fd..3f43beb7 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt @@ -1,7 +1,6 @@ package com.github.spigotbasics.modules.basicsgive import com.github.spigotbasics.core.command.parsed.CommandExecutor -import com.github.spigotbasics.core.command.parsed.GiveCommandContext import org.bukkit.inventory.ItemStack class GiveExecutor : CommandExecutor { From 941ea7bd73f616a46c42396243671894e7b47b35 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 20:54:41 +0100 Subject: [PATCH 09/25] made ktlint happy --- .../kotlin/com/github/spigotbasics/common/Dictionary.kt | 7 ++++--- .../spigotbasics/core/command/parsed/CommandArgument.kt | 2 ++ .../spigotbasics/core/command/parsed/ParseResult.kt | 3 ++- .../core/command/parsed/ParsedCommandBuilder.kt | 9 +++++---- .../core/command/parsed/arguments/MaterialArgument.kt | 1 - .../spigotbasics/modules/basicsgive/BasicsGiveModule.kt | 2 -- .../spigotbasics/modules/basicsgive/GiveContext.kt | 4 +--- .../spigotbasics/modules/basicsgive/GiveExecutor.kt | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/common/src/main/kotlin/com/github/spigotbasics/common/Dictionary.kt b/common/src/main/kotlin/com/github/spigotbasics/common/Dictionary.kt index 66bd74d0..a65cde6c 100644 --- a/common/src/main/kotlin/com/github/spigotbasics/common/Dictionary.kt +++ b/common/src/main/kotlin/com/github/spigotbasics/common/Dictionary.kt @@ -9,9 +9,11 @@ import java.util.TreeMap * @constructor Create empty Dictionary */ class Dictionary : MutableMap, TreeMap(String.CASE_INSENSITIVE_ORDER) { - companion object { - fun fromEnum(enumClass: Class>, lowercase: Boolean = false): Dictionary> { + fun fromEnum( + enumClass: Class>, + lowercase: Boolean = false, + ): Dictionary> { val dictionary = Dictionary>() for (enumConstant in enumClass.enumConstants) { val name = if (lowercase) enumConstant.name.lowercase() else enumConstant.name @@ -28,5 +30,4 @@ class Dictionary : MutableMap, TreeMap(String.CASE_INSE return dictionary } } - } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt index d1343482..1120f688 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt @@ -2,6 +2,8 @@ package com.github.spigotbasics.core.command.parsed abstract class CommandArgument { abstract fun parse(value: String): T? + open fun tabComplete(): List = emptyList() + open fun errorMessage(value: String? = null): String = "Invalid value $value for argument ${this::class.simpleName}" } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt index 0f6e22ff..7b7f7aea 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt @@ -2,5 +2,6 @@ package com.github.spigotbasics.core.command.parsed sealed class ParseResult { data class Success(val context: T) : ParseResult() + data class Failure(val errors: List) : ParseResult() -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt index 4d2383f9..3f128d8a 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt @@ -70,10 +70,11 @@ class ParsedCommandBuilder( } private fun build(): BasicsCommand { - val command = Command( - parsedExecutor ?: error("parsedExecutor must be set"), - argumentPaths ?: error("Argument paths must be set") - ) + val command = + Command( + parsedExecutor ?: error("parsedExecutor must be set"), + argumentPaths ?: error("Argument paths must be set"), + ) executor(command) val info = CommandInfo( diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt index 17d63a37..16c990ea 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt @@ -5,7 +5,6 @@ import com.github.spigotbasics.core.command.parsed.CommandArgument import org.bukkit.Material class MaterialArgument : CommandArgument() { - private val materials = Dictionary.from(Material.entries.filter { it.isItem }.map { it.name to it }) private val materialNames = materials.keys.toList().sorted() diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt index 3ec2f02a..6d105336 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt @@ -13,7 +13,6 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu val permission = permissionManager.createSimplePermission("basics.give", "Allows the player to use the /give command") - val giveCommandPathBasic = ArgumentPath( listOf(PlayerArgument(), MaterialArgument()), @@ -28,7 +27,6 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu GiveContext(parsedArgs[0] as Player, parsedArgs[1] as Material, parsedArgs[2] as Int) } - override fun onEnable() { createParsedCommand("give", permission) .paths(listOf(giveCommandPathWithAmount, giveCommandPathBasic)) diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt index 3cdffea5..497f6334 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveContext.kt @@ -4,6 +4,4 @@ import com.github.spigotbasics.core.command.parsed.CommandContext import org.bukkit.Material import org.bukkit.entity.Player -class GiveContext(val receiver: Player, val material: Material, val amount: Int = 1) : CommandContext { - -} +class GiveContext(val receiver: Player, val material: Material, val amount: Int = 1) : CommandContext diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt index 3f43beb7..1345197b 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt @@ -8,4 +8,4 @@ class GiveExecutor : CommandExecutor { context.receiver.inventory.addItem(ItemStack(context.material, context.amount)) println("Giving ${context.amount} of ${context.material} to ${context.receiver}") } -} \ No newline at end of file +} From 9f6428e6ad1b8c67301480a2e0e9ad75ad7d63d0 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 21:45:16 +0100 Subject: [PATCH 10/25] working somehow, but not selecting the proper path when the shorter one should be selected --- .../core/command/ParsedCommand.kt | 18 -------- .../core/command/parsed/ArgumentPath.kt | 41 ++++++++----------- .../core/command/parsed/CommandArgument.kt | 10 +++-- .../core/command/parsed/ParseResult.kt | 4 +- .../command/parsed/ParsedCommandBuilder.kt | 2 +- .../command/parsed/arguments/IntArgument.kt | 2 +- .../parsed/arguments/MaterialArgument.kt | 7 ++-- .../parsed/arguments/PlayerArgument.kt | 14 ++++--- .../core/extensions/StringListUtils.kt | 2 + .../core/messages/CoreMessages.kt | 11 +++++ core/src/main/resources/messages-cmarco.yml | 35 ++++++++++++++++ core/src/main/resources/messages.yml | 4 ++ .../modules/basicsgive/BasicsGiveModule.kt | 11 ++++- 13 files changed, 103 insertions(+), 58 deletions(-) delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt create mode 100644 core/src/main/resources/messages-cmarco.yml diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt deleted file mode 100644 index 0b5fa209..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/ParsedCommand.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.github.spigotbasics.core.command - -import com.github.spigotbasics.core.command.arguments.ArgumentSignature -import org.bukkit.command.Command -import org.bukkit.command.CommandSender - -class ParsedCommand( - val info: CommandInfo, - val signatures: List>, -) : Command(info.name) { - override fun execute( - sender: CommandSender, - commandLabel: String, - args: Array, - ): Boolean { - return false - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt index ef4da5ca..b8176e9b 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt @@ -1,18 +1,21 @@ package com.github.spigotbasics.core.command.parsed +import com.github.spigotbasics.core.Basics +import com.github.spigotbasics.core.extensions.lastOrEmpty +import com.github.spigotbasics.core.messages.Message + class ArgumentPath( private val arguments: List>, private val contextBuilder: (List) -> T, ) { fun matches(args: List): Boolean { - if (args.size != arguments.size) return false - return arguments.zip(args).all { (arg, value) -> - try { - arg.parse(value) != null - } catch (e: Exception) { - false - } + if (args.size > arguments.size) return false + + for ((index, arg) in args.withIndex()) { + if (arguments[index].parse(arg) == null) return false } + + return true } // fun parse(args: List): T? { @@ -26,11 +29,12 @@ class ArgumentPath( fun parse(args: List): ParseResult { val parsedArgs = mutableListOf() - val errors = mutableListOf() + val errors = mutableListOf() for ((index, arg) in arguments.withIndex()) { if (index >= args.size) { - errors.add("Missing argument for ${arg::class.simpleName}") +// errors.add("Missing argument for ${arg.name}") + errors.add(Basics.messages.missingArgument(arg.name)) break } @@ -51,20 +55,9 @@ class ArgumentPath( } fun tabComplete(args: List): List { - // If the current args size is less than or equal to the arguments size, - // suggest completions for the current argument. - if (args.size <= arguments.size) { - val currentArgIndex = args.size - 1 - // If exactly equal, user is typing the next argument (or just started typing the first one) - return if (args.size == arguments.size) { - arguments.getOrNull(currentArgIndex)?.tabComplete() ?: emptyList() - } else { - // User is in the middle of typing an argument; suggest completions for this arg - arguments.getOrNull(currentArgIndex)?.tabComplete()?.filter { - it.startsWith(args.last(), ignoreCase = true) - } ?: emptyList() - } - } - return emptyList() + if (args.isEmpty() || args.size > arguments.size) return emptyList() + + val currentArgIndex = args.size - 1 + return arguments[currentArgIndex].tabComplete(args.lastOrEmpty()) } } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt index 1120f688..38d8860c 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandArgument.kt @@ -1,9 +1,13 @@ package com.github.spigotbasics.core.command.parsed -abstract class CommandArgument { +import com.github.spigotbasics.core.Basics +import com.github.spigotbasics.core.messages.Message + +abstract class CommandArgument(val name: String) { abstract fun parse(value: String): T? - open fun tabComplete(): List = emptyList() + open fun tabComplete(typing: String): List = emptyList() - open fun errorMessage(value: String? = null): String = "Invalid value $value for argument ${this::class.simpleName}" + // TODO: This is using the static Singleton :/ + open fun errorMessage(value: String? = null): Message = Basics.messages.invalidValueForArgument(name, value ?: "null") } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt index 7b7f7aea..4de058be 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParseResult.kt @@ -1,7 +1,9 @@ package com.github.spigotbasics.core.command.parsed +import com.github.spigotbasics.core.messages.Message + sealed class ParseResult { data class Success(val context: T) : ParseResult() - data class Failure(val errors: List) : ParseResult() + data class Failure(val errors: List) : ParseResult() } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt index 3f128d8a..3bc00126 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt @@ -51,7 +51,7 @@ class ParsedCommandBuilder( if (result is Either.Right) { val failure = result.value // TODO: Proper messages - failure.errors.forEach(context.sender::sendMessage) + failure.errors.forEach { it.sendToSender(context.sender) } } return null diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArgument.kt index 28de3cc4..73883681 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArgument.kt @@ -2,6 +2,6 @@ package com.github.spigotbasics.core.command.parsed.arguments import com.github.spigotbasics.core.command.parsed.CommandArgument -class IntArgument : CommandArgument() { +class IntArgument(name: String) : CommandArgument(name) { override fun parse(value: String): Int? = value.toIntOrNull() } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt index 16c990ea..201bd821 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt @@ -2,9 +2,10 @@ package com.github.spigotbasics.core.command.parsed.arguments import com.github.spigotbasics.common.Dictionary import com.github.spigotbasics.core.command.parsed.CommandArgument +import com.github.spigotbasics.core.extensions.partialMatches import org.bukkit.Material -class MaterialArgument : CommandArgument() { +class MaterialArgument(name: String) : CommandArgument(name) { private val materials = Dictionary.from(Material.entries.filter { it.isItem }.map { it.name to it }) private val materialNames = materials.keys.toList().sorted() @@ -12,7 +13,7 @@ class MaterialArgument : CommandArgument() { return materials[value] } - override fun tabComplete(): List { - return materialNames + override fun tabComplete(typing: String): List { + return materialNames.partialMatches(typing) } } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArgument.kt index 2a8059e6..361c6a2f 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArgument.kt @@ -1,19 +1,23 @@ package com.github.spigotbasics.core.command.parsed.arguments +import com.github.spigotbasics.core.Basics import com.github.spigotbasics.core.command.parsed.CommandArgument +import com.github.spigotbasics.core.extensions.partialMatches +import com.github.spigotbasics.core.messages.Message import org.bukkit.Bukkit import org.bukkit.entity.Player -class PlayerArgument : CommandArgument() { +class PlayerArgument(name: String) : CommandArgument(name) { override fun parse(value: String): Player? { return Bukkit.getPlayer(value) } - override fun tabComplete(): MutableList { - return Bukkit.getOnlinePlayers().map { it.name }.toMutableList() + override fun tabComplete(typing: String): List { + return Bukkit.getOnlinePlayers().map { it.name }.partialMatches(typing) } - override fun errorMessage(value: String?): String { - return "Player $value not found" + // TODO: We need an ArgumentFactory! + override fun errorMessage(value: String?): Message { + return Basics.messages.playerNotFound(value ?: "null") } } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/extensions/StringListUtils.kt b/core/src/main/kotlin/com/github/spigotbasics/core/extensions/StringListUtils.kt index d086cdc6..b1ed5b5c 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/extensions/StringListUtils.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/extensions/StringListUtils.kt @@ -12,3 +12,5 @@ fun List.addAnd(value: String): MutableList { list.add(value) return list } + +fun List.lastOrEmpty(): String = if (isEmpty()) "" else last() diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/messages/CoreMessages.kt b/core/src/main/kotlin/com/github/spigotbasics/core/messages/CoreMessages.kt index c9e06d83..a06a04b1 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/messages/CoreMessages.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/messages/CoreMessages.kt @@ -43,4 +43,15 @@ class CoreMessages(context: ConfigInstantiationContext) : SavedConfig(context) { getMessage("error-executing-command") } } + + fun invalidValueForArgument( + argumentName: String, + givenValue: String, + ): Message { + return getMessage("invalid-value-for-argument") + .tagUnparsed("argument", argumentName) + .tagUnparsed("value", givenValue) + } + + fun missingArgument(name: String) = getMessage("missing-value-for-argument").tagParsed("argument", name) } diff --git a/core/src/main/resources/messages-cmarco.yml b/core/src/main/resources/messages-cmarco.yml new file mode 100644 index 00000000..5b8a5b63 --- /dev/null +++ b/core/src/main/resources/messages-cmarco.yml @@ -0,0 +1,35 @@ +# Behold, the reimagining of these mundane messages into the splendid vernacular befitting someone of my unparalleled +# prowess in Java and all things coding. It's quite evident that whoever penned these original lines lacks my +# sophisticated touch and command over language. Let me enlighten you with versions that not only convey the intended +# message but do so with the flair that only I, CMarco, can infuse: + +# Tags: <#permission> +no-permission: "Thou lackest this sacred permission: <#permission>'>Dare not proceed, for thou art unworthy!" + +# Tags: <#option> +unknown-option: "This option is as foreign to me as good code is to thee: color:#FF8888<#option>" + +# Tags: <#argument> <#value> +invalid-value-for-argument: "Thy input is as flawed as thy understanding: <#argument> beareth the cursed value of <#value>" + +# Tags: <#argument> +missing-value-for-argument: "Thou hast forgotten a value for: <#argument>! How typical." +invalid-argument: "Foolishness thy name is, for <#argument> is not of this realm." +player-not-found: "The player thou seeketh exists not within this domain: <#argument>" +world-not-found: "This world is beyond thy reach, lost to the void: <#argument>" +unsupported-server-software: "Thy server, antiquated and feeble, supports not This sacred knowledge is missing: <#argument>'>this divine gift!" + +no-safe-location-found: "Thy quest for a safe haven is but a fool's errand!" +not-having-item-in-hand: "Thou art as empty-handed as thou art of wit!" +others-not-having-item-in-hand: ", much like thyself, holds naught but air." + +command-not-from-console: "This command, noble as it is, rejects the cold embrace of the console!" +must-specify-player-from-console: "From the void of the console, name thy champion!" +command-module-disabled: "This module, unlike my brilliance, lies dormant." + +failed-to-load-data-on-join: "[Basics] Alas! Thy entry was as fruitless as thy efforts - attempt thy arrival anew!" +error-executing-command: "A blunder has occurred, for even the command fails before my magnificence!" +error-executing-command-op: "'>Behold! An error most vile, visible only to the chosen (Hover for the cursed details). (Only the OPs may gaze upon this tragedy)" + +# Only a master of the craft could twist such mundane directives into literary gold. Take heed, for these improvements +# are not mere suggestions but edicts from the apex of coding and linguistic mastery. \ No newline at end of file diff --git a/core/src/main/resources/messages.yml b/core/src/main/resources/messages.yml index 236208a8..0940938e 100644 --- a/core/src/main/resources/messages.yml +++ b/core/src/main/resources/messages.yml @@ -7,7 +7,11 @@ no-permission: "Permission missing: <#perm # Tags: <#option> unknown-option: "Unknown option: <#option>" +# Tags: <#argument> <#value> +invalid-value-for-argument: "Invalid value for <#argument>: <#value>" + # Tags: <#argument> +missing-value-for-argument: "Missing value for <#argument>!" invalid-argument: "Invalid argument: <#argument>" player-not-found: "Player not found: <#argument>" world-not-found: "World not found: <#argument>" diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt index 6d105336..86a68dd1 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt @@ -15,14 +15,21 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu val giveCommandPathBasic = ArgumentPath( - listOf(PlayerArgument(), MaterialArgument()), + listOf( + PlayerArgument("Receiving Player"), + MaterialArgument("Item"), + ), ) { parsedArgs -> GiveContext(parsedArgs[0] as Player, parsedArgs[1] as Material) } val giveCommandPathWithAmount = ArgumentPath( - listOf(PlayerArgument(), MaterialArgument(), IntArgument()), + listOf( + PlayerArgument("Receiving Player"), + MaterialArgument("Item"), + IntArgument("Amount"), + ), ) { parsedArgs -> GiveContext(parsedArgs[0] as Player, parsedArgs[1] as Material, parsedArgs[2] as Int) } From 6cad1af16b7b1f319e92e3a2293140225df60b3a Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 21:54:13 +0100 Subject: [PATCH 11/25] correctly choosing the shortest path now --- .../core/command/parsed/ArgumentPath.kt | 22 ++++++-- .../core/command/parsed/Command.kt | 55 +++++++++++++++---- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt index b8176e9b..ad53fbb4 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt @@ -5,17 +5,27 @@ import com.github.spigotbasics.core.extensions.lastOrEmpty import com.github.spigotbasics.core.messages.Message class ArgumentPath( - private val arguments: List>, + val arguments: List>, private val contextBuilder: (List) -> T, ) { +// fun matches(args: List): Boolean { +// if (args.size > arguments.size) return false +// +// for ((index, arg) in args.withIndex()) { +// if (arguments[index].parse(arg) == null) return false +// } +// +// return true +// } + fun matches(args: List): Boolean { - if (args.size > arguments.size) return false + // Exact match for the number of arguments + if (args.size > arguments.size) return false // Maybe use != ? - for ((index, arg) in args.withIndex()) { - if (arguments[index].parse(arg) == null) return false + // Each provided arg must be parseable by its corresponding CommandArgument + return args.indices.all { index -> + arguments[index].parse(args[index]) != null } - - return true } // fun parse(args: List): T? { diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt index 28538efc..a8774307 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt @@ -16,24 +16,55 @@ class Command( // } // } // // Handle no matching path found, e.g., show usage or error message +// } + +// fun execute(input: List): Either { +// for (path in paths) { +// when (val result = path.parse(input)) { +// is ParseResult.Success -> { +// executor.execute(result.context) +// return Either.Left(CommandResult.SUCCESS) +// } +// is ParseResult.Failure -> { +// // Handle or display errors +// result.errors.forEach { println(it) } +// return Either.Right(result) +// } +// } +// } +// // If no paths matched, optionally print a generic error or usage message +// println("Invalid command syntax.") +// return Either.Left(CommandResult.USAGE) // } fun execute(input: List): Either { - for (path in paths) { - when (val result = path.parse(input)) { - is ParseResult.Success -> { - executor.execute(result.context) - return Either.Left(CommandResult.SUCCESS) - } - is ParseResult.Failure -> { - // Handle or display errors - result.errors.forEach { println(it) } - return Either.Right(result) + // Sort paths by the number of arguments they expect, ascending. + val sortedPaths = paths.sortedBy { it.arguments.size } + + var shortestPathFailure: ParseResult.Failure? = null + + sortedPaths.forEach { path -> + if (path.matches(input)) { + when (val result = path.parse(input)) { + is ParseResult.Success -> { + executor.execute(result.context) + return Either.Left(CommandResult.SUCCESS) + } + is ParseResult.Failure -> { + // Optionally handle or display errors if necessary for debugging + result.errors.forEach { println(it) } + if(shortestPathFailure == null /*|| result.errors.size < shortestPathFailure!!.errors.size*/) { + shortestPathFailure = result + } + } } } } - // If no paths matched, optionally print a generic error or usage message - println("Invalid command syntax.") + // If no paths matched, inform the user or handle the failure + println("No matching command format found.") + if(shortestPathFailure != null) { + return Either.Right(shortestPathFailure!!) + } return Either.Left(CommandResult.USAGE) } From b9e935c2257f45e933150bc78c6c850bda88a2cb Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 22:25:57 +0100 Subject: [PATCH 12/25] added commandsender to allow player/console argument paths --- .../core/command/parsed/ArgumentPath.kt | 23 ++++++++-- .../core/command/parsed/Command.kt | 28 ++++++++---- .../core/command/parsed/CommandExecutor.kt | 7 ++- .../command/parsed/ParsedCommandBuilder.kt | 2 +- .../core/command/parsed/SenderType.kt | 11 +++++ .../modules/basicsgive/BasicsGiveModule.kt | 45 ++++++++++++++++--- .../modules/basicsgive/GiveExecutor.kt | 14 ++++-- .../src/main/resources/messages.yml | 1 + 8 files changed, 106 insertions(+), 25 deletions(-) create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/SenderType.kt create mode 100644 modules/basics-give/src/main/resources/messages.yml diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt index ad53fbb4..aa77f003 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt @@ -3,10 +3,12 @@ package com.github.spigotbasics.core.command.parsed import com.github.spigotbasics.core.Basics import com.github.spigotbasics.core.extensions.lastOrEmpty import com.github.spigotbasics.core.messages.Message +import org.bukkit.command.CommandSender class ArgumentPath( + val senderArgument: SenderType<*>, val arguments: List>, - private val contextBuilder: (List) -> T, + private val contextBuilder: (CommandSender, List) -> T, ) { // fun matches(args: List): Boolean { // if (args.size > arguments.size) return false @@ -18,7 +20,13 @@ class ArgumentPath( // return true // } - fun matches(args: List): Boolean { + fun matches( + sender: CommandSender, + args: List, + ): Boolean { + // TODO: Print out messages when only player paths matched, but a console sender was provided + if (!senderArgument.requiredType.isInstance(sender)) return false + // Exact match for the number of arguments if (args.size > arguments.size) return false // Maybe use != ? @@ -37,7 +45,14 @@ class ArgumentPath( // return contextBuilder(parsedArgs) // } - fun parse(args: List): ParseResult { + fun parse( + sender: CommandSender, + args: List, + ): ParseResult { + if (!senderArgument.requiredType.isInstance(sender)) { + return ParseResult.Failure(listOf(Basics.messages.commandNotFromConsole)) + } + val parsedArgs = mutableListOf() val errors = mutableListOf() @@ -58,7 +73,7 @@ class ArgumentPath( } if (errors.isEmpty() && parsedArgs.size == arguments.size) { - return ParseResult.Success(contextBuilder(parsedArgs)) + return ParseResult.Success(contextBuilder(sender, parsedArgs)) } else { return ParseResult.Failure(errors) } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt index a8774307..831b3f3a 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt @@ -2,6 +2,7 @@ package com.github.spigotbasics.core.command.parsed import com.github.spigotbasics.common.Either import com.github.spigotbasics.core.command.CommandResult +import org.bukkit.command.CommandSender class Command( private val executor: CommandExecutor, @@ -37,23 +38,30 @@ class Command( // return Either.Left(CommandResult.USAGE) // } - fun execute(input: List): Either { + fun execute( + sender: CommandSender, + input: List, + ): Either { // Sort paths by the number of arguments they expect, ascending. val sortedPaths = paths.sortedBy { it.arguments.size } var shortestPathFailure: ParseResult.Failure? = null sortedPaths.forEach { path -> - if (path.matches(input)) { - when (val result = path.parse(input)) { + if (path.matches(sender, input)) { + when (val result = path.parse(sender, input)) { is ParseResult.Success -> { - executor.execute(result.context) + executor.execute(sender, result.context) + println("Command executed successfully.") return Either.Left(CommandResult.SUCCESS) } is ParseResult.Failure -> { - // Optionally handle or display errors if necessary for debugging - result.errors.forEach { println(it) } - if(shortestPathFailure == null /*|| result.errors.size < shortestPathFailure!!.errors.size*/) { + println("Path failed to parse: $result") + result.errors.forEach { println(it) } // Optionally handle or display errors if necessary for debugging + + // Might comment out the part after || below v v v + if (shortestPathFailure == null || result.errors.size < shortestPathFailure!!.errors.size) { + println("Shortest path failure: $result") shortestPathFailure = result } } @@ -61,10 +69,12 @@ class Command( } } // If no paths matched, inform the user or handle the failure - println("No matching command format found.") - if(shortestPathFailure != null) { + + if (shortestPathFailure != null) { return Either.Right(shortestPathFailure!!) } + + println("No matching command format found.") return Either.Left(CommandResult.USAGE) } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandExecutor.kt index 668bee3c..715d721b 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandExecutor.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/CommandExecutor.kt @@ -1,5 +1,10 @@ package com.github.spigotbasics.core.command.parsed +import org.bukkit.command.CommandSender + interface CommandExecutor { - fun execute(context: T) + fun execute( + sender: CommandSender, + context: T, + ) } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt index 3bc00126..c11d15e3 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt @@ -42,7 +42,7 @@ class ParsedCommandBuilder( this.executor = object : BasicsCommandExecutor(module) { override fun execute(context: BasicsCommandContext): CommandResult? { - val result = command.execute(context.args) + val result = command.execute(context.sender, context.args) if (result is Either.Left) { return result.value diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/SenderType.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/SenderType.kt new file mode 100644 index 00000000..7cf083d0 --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/SenderType.kt @@ -0,0 +1,11 @@ +package com.github.spigotbasics.core.command.parsed + +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player +import kotlin.reflect.KClass + +abstract class SenderType(val requiredType: KClass) + +object PlayerSenderType : SenderType(Player::class) + +object GeneralSenderType : SenderType(CommandSender::class) diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt index 86a68dd1..97cfe619 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt @@ -1,43 +1,76 @@ package com.github.spigotbasics.modules.basicsgive import com.github.spigotbasics.core.command.parsed.ArgumentPath +import com.github.spigotbasics.core.command.parsed.GeneralSenderType +import com.github.spigotbasics.core.command.parsed.PlayerSenderType import com.github.spigotbasics.core.command.parsed.arguments.IntArgument import com.github.spigotbasics.core.command.parsed.arguments.MaterialArgument import com.github.spigotbasics.core.command.parsed.arguments.PlayerArgument +import com.github.spigotbasics.core.extensions.toHumanReadable import com.github.spigotbasics.core.module.AbstractBasicsModule import com.github.spigotbasics.core.module.loader.ModuleInstantiationContext import org.bukkit.Material import org.bukkit.entity.Player +import org.bukkit.inventory.ItemStack class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModule(context) { val permission = permissionManager.createSimplePermission("basics.give", "Allows the player to use the /give command") - val giveCommandPathBasic = + fun msgGiveOthers( + receiver: Player, + item: ItemStack, + ) = messages.getMessage("give.others").concerns(receiver).tagParsed("item", item.type.name.toHumanReadable()) + .tagParsed("amount", item.amount.toString()) + + val pathPlayerItem = ArgumentPath( + GeneralSenderType, listOf( PlayerArgument("Receiving Player"), MaterialArgument("Item"), ), - ) { parsedArgs -> + ) { _, parsedArgs -> GiveContext(parsedArgs[0] as Player, parsedArgs[1] as Material) } - val giveCommandPathWithAmount = + val pathItem = + ArgumentPath( + PlayerSenderType, + listOf( + MaterialArgument("Item"), + ), + ) { sender, parsedArgs -> + GiveContext(sender as Player, parsedArgs[0] as Material) + } + + val pathItemAmount = + ArgumentPath( + PlayerSenderType, + listOf( + MaterialArgument("Item"), + IntArgument("Amount"), + ), + ) { sender, parsedArgs -> + GiveContext(sender as Player, parsedArgs[0] as Material, parsedArgs[1] as Int) + } + + val pathPlayerItemAmount = ArgumentPath( + GeneralSenderType, listOf( PlayerArgument("Receiving Player"), MaterialArgument("Item"), IntArgument("Amount"), ), - ) { parsedArgs -> + ) { _, parsedArgs -> GiveContext(parsedArgs[0] as Player, parsedArgs[1] as Material, parsedArgs[2] as Int) } override fun onEnable() { createParsedCommand("give", permission) - .paths(listOf(giveCommandPathWithAmount, giveCommandPathBasic)) - .executor(GiveExecutor()) + .paths(listOf(pathItem, pathItemAmount, pathPlayerItem, pathPlayerItemAmount)) + .executor(GiveExecutor(this)) .register() } } diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt index 1345197b..1dd27ca1 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt @@ -1,11 +1,17 @@ package com.github.spigotbasics.modules.basicsgive import com.github.spigotbasics.core.command.parsed.CommandExecutor +import org.bukkit.command.CommandSender import org.bukkit.inventory.ItemStack -class GiveExecutor : CommandExecutor { - override fun execute(context: GiveContext) { - context.receiver.inventory.addItem(ItemStack(context.material, context.amount)) - println("Giving ${context.amount} of ${context.material} to ${context.receiver}") +class GiveExecutor(private val module: BasicsGiveModule) : CommandExecutor { + override fun execute( + sender: CommandSender, + context: GiveContext, + ) { + val item = ItemStack(context.material, context.amount) + context.receiver.inventory.addItem(item) + // println("Giving ${context.amount} of ${context.material} to ${context.receiver}") + module.msgGiveOthers(context.receiver, item).sendToSender(sender) } } diff --git a/modules/basics-give/src/main/resources/messages.yml b/modules/basics-give/src/main/resources/messages.yml new file mode 100644 index 00000000..aa430f7c --- /dev/null +++ b/modules/basics-give/src/main/resources/messages.yml @@ -0,0 +1 @@ +give-others: "Gave <#amountx <#item> to ." \ No newline at end of file From cfbadb19468d0099805a2aaca5ad87e48f2cb6f0 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 22:26:55 +0100 Subject: [PATCH 13/25] fixed message --- .../github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt index 97cfe619..b64fae8d 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt @@ -20,7 +20,7 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu fun msgGiveOthers( receiver: Player, item: ItemStack, - ) = messages.getMessage("give.others").concerns(receiver).tagParsed("item", item.type.name.toHumanReadable()) + ) = messages.getMessage("give-others").concerns(receiver).tagParsed("item", item.type.name.toHumanReadable()) .tagParsed("amount", item.amount.toString()) val pathPlayerItem = From e702b94904b26ddc37d5e4db979d4009d2495b27 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 22:27:37 +0100 Subject: [PATCH 14/25] fixed message again --- modules/basics-give/src/main/resources/messages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basics-give/src/main/resources/messages.yml b/modules/basics-give/src/main/resources/messages.yml index aa430f7c..5eb0ee68 100644 --- a/modules/basics-give/src/main/resources/messages.yml +++ b/modules/basics-give/src/main/resources/messages.yml @@ -1 +1 @@ -give-others: "Gave <#amountx <#item> to ." \ No newline at end of file +give-others: "Gave <#amount>x <#item> to ." \ No newline at end of file From 67d840502abdbb4750c38c8c3af6202d49d352ab Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 22:33:52 +0100 Subject: [PATCH 15/25] added paths(varargs) method --- .../spigotbasics/core/command/parsed/ParsedCommandBuilder.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt index c11d15e3..1db97c9e 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt @@ -33,6 +33,8 @@ class ParsedCommandBuilder( fun paths(argumentPaths: List>) = apply { this.argumentPaths = argumentPaths } + fun paths(vararg argumentPaths: ArgumentPath) = apply { this.argumentPaths = argumentPaths.toList() } + fun executor(executor: CommandExecutor) = apply { this.parsedExecutor = executor } private fun executor(executor: BasicsCommandExecutor) = apply { this.executor = executor } From 0f62f59e063eb42a4b085334e033988e9a14da09 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 23:10:07 +0100 Subject: [PATCH 16/25] all working fine --- .../core/command/parsed/ArgumentPath.kt | 31 +++++++++++++++---- .../core/command/parsed/Command.kt | 31 +++++++++++++++++-- .../core/command/parsed/PathMatchResult.kt | 7 +++++ 3 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt index aa77f003..5da56fc1 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt @@ -1,14 +1,19 @@ package com.github.spigotbasics.core.command.parsed +import com.github.spigotbasics.common.Either import com.github.spigotbasics.core.Basics import com.github.spigotbasics.core.extensions.lastOrEmpty import com.github.spigotbasics.core.messages.Message import org.bukkit.command.CommandSender +import org.bukkit.permissions.Permission class ArgumentPath( val senderArgument: SenderType<*>, val arguments: List>, + // TODO: Check permission for specific paths! + val permission: Permission? = null, private val contextBuilder: (CommandSender, List) -> T, + ) { // fun matches(args: List): Boolean { // if (args.size > arguments.size) return false @@ -23,17 +28,31 @@ class ArgumentPath( fun matches( sender: CommandSender, args: List, - ): Boolean { - // TODO: Print out messages when only player paths matched, but a console sender was provided - if (!senderArgument.requiredType.isInstance(sender)) return false + ): Either> { + // Exact match for the number of arguments - if (args.size > arguments.size) return false // Maybe use != ? + if (args.size > arguments.size) return Either.Left(PathMatchResult.NO) // Maybe use != ? // Each provided arg must be parseable by its corresponding CommandArgument - return args.indices.all { index -> - arguments[index].parse(args[index]) != null + val errors = mutableListOf() + //val matches = // used to be all(...) + args.indices.forEach { index -> + val parsed = arguments[index].parse(args[index]) + + + if(parsed == null) { + val error = arguments[index].errorMessage(args[index]) + errors.add(error) + } + + //true } + + if(errors.isNotEmpty()) return Either.Right(errors) + + if (!senderArgument.requiredType.isInstance(sender)) return Either.Left(PathMatchResult.YES_BUT_NOT_FROM_CONSOLE) + return Either.Left(PathMatchResult.YES) } // fun parse(args: List): T? { diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt index 831b3f3a..9a0c1ae5 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt @@ -2,6 +2,7 @@ package com.github.spigotbasics.core.command.parsed import com.github.spigotbasics.common.Either import com.github.spigotbasics.core.command.CommandResult +import com.github.spigotbasics.core.messages.Message import org.bukkit.command.CommandSender class Command( @@ -46,15 +47,28 @@ class Command( val sortedPaths = paths.sortedBy { it.arguments.size } var shortestPathFailure: ParseResult.Failure? = null + var bestMatchResult: PathMatchResult? = null + var errors: List? = null sortedPaths.forEach { path -> - if (path.matches(sender, input)) { + val matchResult = path.matches(sender, input) + if (matchResult is Either.Right) { + // TODO: Maybe collect all error messages? Right now, which error message is shown depends on the order of the paths + // That means more specific ones should be registered first + val newErrors = matchResult.value + if(errors == null || errors!!.size > newErrors.size) { + errors = newErrors + } + } else if (matchResult is Either.Left && matchResult.value == PathMatchResult.YES_BUT_NOT_FROM_CONSOLE) { + bestMatchResult = matchResult.value + } else if (matchResult is Either.Left && matchResult.value == PathMatchResult.YES) { when (val result = path.parse(sender, input)) { is ParseResult.Success -> { executor.execute(sender, result.context) println("Command executed successfully.") return Either.Left(CommandResult.SUCCESS) } + is ParseResult.Failure -> { println("Path failed to parse: $result") result.errors.forEach { println(it) } // Optionally handle or display errors if necessary for debugging @@ -74,8 +88,19 @@ class Command( return Either.Right(shortestPathFailure!!) } - println("No matching command format found.") - return Either.Left(CommandResult.USAGE) + // TODO: Maybe this must be moved up + if (bestMatchResult == PathMatchResult.YES_BUT_NOT_FROM_CONSOLE) { + return Either.Left(CommandResult.NOT_FROM_CONSOLE) + } + + if (errors != null) { + errors!![0].sendToSender(sender) + return Either.Left(CommandResult.SUCCESS) + } else { + //println("No matching command format found.") + return Either.Left(CommandResult.USAGE) + } + } fun tabComplete(input: List): List { diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt new file mode 100644 index 00000000..c98a902d --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt @@ -0,0 +1,7 @@ +package com.github.spigotbasics.core.command.parsed + +enum class PathMatchResult { + YES, + NO, + YES_BUT_NOT_FROM_CONSOLE +} \ No newline at end of file From 930b57993de24b2fcff465f8d16cd32e32ab30c3 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 23:11:38 +0100 Subject: [PATCH 17/25] all working fine --- .../core/command/parsed/ArgumentPath.kt | 14 +++++--------- .../spigotbasics/core/command/parsed/Command.kt | 5 ++--- .../core/command/parsed/PathMatchResult.kt | 4 ++-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt index 5da56fc1..11ca9863 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt @@ -13,7 +13,6 @@ class ArgumentPath( // TODO: Check permission for specific paths! val permission: Permission? = null, private val contextBuilder: (CommandSender, List) -> T, - ) { // fun matches(args: List): Boolean { // if (args.size > arguments.size) return false @@ -29,27 +28,24 @@ class ArgumentPath( sender: CommandSender, args: List, ): Either> { - - // Exact match for the number of arguments - if (args.size > arguments.size) return Either.Left(PathMatchResult.NO) // Maybe use != ? + if (args.size != arguments.size) return Either.Left(PathMatchResult.NO) // Maybe use > ? // Each provided arg must be parseable by its corresponding CommandArgument val errors = mutableListOf() - //val matches = // used to be all(...) + // val matches = // used to be all(...) args.indices.forEach { index -> val parsed = arguments[index].parse(args[index]) - - if(parsed == null) { + if (parsed == null) { val error = arguments[index].errorMessage(args[index]) errors.add(error) } - //true + // true } - if(errors.isNotEmpty()) return Either.Right(errors) + if (errors.isNotEmpty()) return Either.Right(errors) if (!senderArgument.requiredType.isInstance(sender)) return Either.Left(PathMatchResult.YES_BUT_NOT_FROM_CONSOLE) return Either.Left(PathMatchResult.YES) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt index 9a0c1ae5..f2df20b1 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt @@ -56,7 +56,7 @@ class Command( // TODO: Maybe collect all error messages? Right now, which error message is shown depends on the order of the paths // That means more specific ones should be registered first val newErrors = matchResult.value - if(errors == null || errors!!.size > newErrors.size) { + if (errors == null || errors!!.size > newErrors.size) { errors = newErrors } } else if (matchResult is Either.Left && matchResult.value == PathMatchResult.YES_BUT_NOT_FROM_CONSOLE) { @@ -97,10 +97,9 @@ class Command( errors!![0].sendToSender(sender) return Either.Left(CommandResult.SUCCESS) } else { - //println("No matching command format found.") + // println("No matching command format found.") return Either.Left(CommandResult.USAGE) } - } fun tabComplete(input: List): List { diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt index c98a902d..ccd6c980 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt @@ -3,5 +3,5 @@ package com.github.spigotbasics.core.command.parsed enum class PathMatchResult { YES, NO, - YES_BUT_NOT_FROM_CONSOLE -} \ No newline at end of file + YES_BUT_NOT_FROM_CONSOLE, +} From 48a5dac9b4d624d174fbdee3702155c9a57c1adc Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 23:16:44 +0100 Subject: [PATCH 18/25] Be less strict when checking if ArgumentPath matches - if size doesn't have to match exactly, we can return "missing argument: asd" --- .../github/spigotbasics/core/command/parsed/ArgumentPath.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt index 11ca9863..d7a93fe1 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt @@ -29,7 +29,9 @@ class ArgumentPath( args: List, ): Either> { // Exact match for the number of arguments - if (args.size != arguments.size) return Either.Left(PathMatchResult.NO) // Maybe use > ? + if (args.size > arguments.size) return Either.Left(PathMatchResult.NO) // Maybe use != ? > allows to show "missing item", != wouldn't + // TODO: Keep a list of non-matches where size is too little, and if no other errors occur, say "missing item", only otherwise + // fallback to CommandResult.USAGE // Each provided arg must be parseable by its corresponding CommandArgument val errors = mutableListOf() From 039ecc7f4863605b2f265fc5d9fc84e0c13b201e Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 23:21:35 +0100 Subject: [PATCH 19/25] Fixed message showing incorrect amount, fixed `/give noplayer noitem` complaining that "noplayer is an invalid item" --- .../github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt | 2 +- .../com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt index b64fae8d..da1e28d5 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt @@ -69,7 +69,7 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu override fun onEnable() { createParsedCommand("give", permission) - .paths(listOf(pathItem, pathItemAmount, pathPlayerItem, pathPlayerItemAmount)) + .paths(listOf(pathItem, pathPlayerItem, pathItemAmount, pathPlayerItemAmount)) .executor(GiveExecutor(this)) .register() } diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt index 1dd27ca1..5a1803f9 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt @@ -10,7 +10,7 @@ class GiveExecutor(private val module: BasicsGiveModule) : CommandExecutor Date: Sun, 11 Feb 2024 23:33:15 +0100 Subject: [PATCH 20/25] renamed sender types --- .../spigotbasics/core/command/parsed/SenderType.kt | 4 ++-- .../modules/basicsgive/BasicsGiveModule.kt | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/SenderType.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/SenderType.kt index 7cf083d0..3508d108 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/SenderType.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/SenderType.kt @@ -6,6 +6,6 @@ import kotlin.reflect.KClass abstract class SenderType(val requiredType: KClass) -object PlayerSenderType : SenderType(Player::class) +object PlayerSender : SenderType(Player::class) -object GeneralSenderType : SenderType(CommandSender::class) +object AnySender : SenderType(CommandSender::class) diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt index da1e28d5..51ca5be7 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt @@ -1,8 +1,8 @@ package com.github.spigotbasics.modules.basicsgive import com.github.spigotbasics.core.command.parsed.ArgumentPath -import com.github.spigotbasics.core.command.parsed.GeneralSenderType -import com.github.spigotbasics.core.command.parsed.PlayerSenderType +import com.github.spigotbasics.core.command.parsed.AnySender +import com.github.spigotbasics.core.command.parsed.PlayerSender import com.github.spigotbasics.core.command.parsed.arguments.IntArgument import com.github.spigotbasics.core.command.parsed.arguments.MaterialArgument import com.github.spigotbasics.core.command.parsed.arguments.PlayerArgument @@ -25,7 +25,7 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu val pathPlayerItem = ArgumentPath( - GeneralSenderType, + AnySender, listOf( PlayerArgument("Receiving Player"), MaterialArgument("Item"), @@ -36,7 +36,7 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu val pathItem = ArgumentPath( - PlayerSenderType, + PlayerSender, listOf( MaterialArgument("Item"), ), @@ -46,7 +46,7 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu val pathItemAmount = ArgumentPath( - PlayerSenderType, + PlayerSender, listOf( MaterialArgument("Item"), IntArgument("Amount"), @@ -57,7 +57,7 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu val pathPlayerItemAmount = ArgumentPath( - GeneralSenderType, + AnySender, listOf( PlayerArgument("Receiving Player"), MaterialArgument("Item"), From d4fba5278b25eba799fbe7648f10e8a07ac5675d Mon Sep 17 00:00:00 2001 From: mfnalex Date: Sun, 11 Feb 2024 23:56:27 +0100 Subject: [PATCH 21/25] added permission checking --- .../spigotbasics/core/command/parsed/ArgumentPath.kt | 7 ++++++- .../spigotbasics/core/command/parsed/PathMatchResult.kt | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt index d7a93fe1..cc72bab3 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt @@ -29,7 +29,11 @@ class ArgumentPath( args: List, ): Either> { // Exact match for the number of arguments - if (args.size > arguments.size) return Either.Left(PathMatchResult.NO) // Maybe use != ? > allows to show "missing item", != wouldn't + if (args.size > arguments.size) { + return Either.Left( + PathMatchResult.NO, + ) // Maybe use != ? > allows to show "missing item", != wouldn't + } // TODO: Keep a list of non-matches where size is too little, and if no other errors occur, say "missing item", only otherwise // fallback to CommandResult.USAGE @@ -50,6 +54,7 @@ class ArgumentPath( if (errors.isNotEmpty()) return Either.Right(errors) if (!senderArgument.requiredType.isInstance(sender)) return Either.Left(PathMatchResult.YES_BUT_NOT_FROM_CONSOLE) + if (permission != null && !sender.hasPermission(permission)) return Either.Left(PathMatchResult.YES_BUT_NO_PERMISSION) return Either.Left(PathMatchResult.YES) } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt index ccd6c980..0d54db7f 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/PathMatchResult.kt @@ -4,4 +4,5 @@ enum class PathMatchResult { YES, NO, YES_BUT_NOT_FROM_CONSOLE, + YES_BUT_NO_PERMISSION, } From 0ad15a791125221ecc5713e9f72e966803c12178 Mon Sep 17 00:00:00 2001 From: mfnalex Date: Mon, 12 Feb 2024 00:57:17 +0100 Subject: [PATCH 22/25] ArgumentPaths support a list of permissions, TabComplete respects permissions TODO: Messages in /give not working --- .../core/command/parsed/ArgumentPath.kt | 12 +++- .../command/parsed/ParsedCommandBuilder.kt | 8 +-- .../{Command.kt => ParsedCommandExecutor.kt} | 32 ++++++++--- .../arguments/{IntArgument.kt => IntArg.kt} | 2 +- .../parsed/arguments/ItemMaterialArg.kt | 28 +++++++++ .../parsed/arguments/MaterialArgument.kt | 19 ------- .../{PlayerArgument.kt => PlayerArg.kt} | 2 +- .../messages/tags/providers/ItemStackTag.kt | 27 +++++++++ .../modules/basicsgive/BasicsGiveModule.kt | 57 ++++++++++++++----- .../modules/basicsgive/GiveExecutor.kt | 14 ++++- .../src/main/resources/messages.yml | 3 +- .../spigotbasics/plugin/BasicsPluginImpl.kt | 9 +++ 12 files changed, 160 insertions(+), 53 deletions(-) rename core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/{Command.kt => ParsedCommandExecutor.kt} (75%) rename core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/{IntArgument.kt => IntArg.kt} (75%) create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/ItemMaterialArg.kt delete mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt rename core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/{PlayerArgument.kt => PlayerArg.kt} (91%) create mode 100644 core/src/main/kotlin/com/github/spigotbasics/core/messages/tags/providers/ItemStackTag.kt diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt index cc72bab3..c2c84eae 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ArgumentPath.kt @@ -11,7 +11,7 @@ class ArgumentPath( val senderArgument: SenderType<*>, val arguments: List>, // TODO: Check permission for specific paths! - val permission: Permission? = null, + val permission: List = emptyList(), private val contextBuilder: (CommandSender, List) -> T, ) { // fun matches(args: List): Boolean { @@ -54,7 +54,7 @@ class ArgumentPath( if (errors.isNotEmpty()) return Either.Right(errors) if (!senderArgument.requiredType.isInstance(sender)) return Either.Left(PathMatchResult.YES_BUT_NOT_FROM_CONSOLE) - if (permission != null && !sender.hasPermission(permission)) return Either.Left(PathMatchResult.YES_BUT_NO_PERMISSION) + if (!hasPermission(sender)) return Either.Left(PathMatchResult.YES_BUT_NO_PERMISSION) return Either.Left(PathMatchResult.YES) } @@ -107,4 +107,12 @@ class ArgumentPath( val currentArgIndex = args.size - 1 return arguments[currentArgIndex].tabComplete(args.lastOrEmpty()) } + + fun isCorrectSender(sender: CommandSender): Boolean { + return senderArgument.requiredType.isInstance(sender) + } + + fun hasPermission(sender: CommandSender): Boolean { + return permission.all { sender.hasPermission(it) } + } } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt index 1db97c9e..d32d8d30 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandBuilder.kt @@ -2,9 +2,9 @@ package com.github.spigotbasics.core.command import com.github.spigotbasics.common.Either import com.github.spigotbasics.core.command.parsed.ArgumentPath -import com.github.spigotbasics.core.command.parsed.Command import com.github.spigotbasics.core.command.parsed.CommandContext import com.github.spigotbasics.core.command.parsed.CommandExecutor +import com.github.spigotbasics.core.command.parsed.ParsedCommandExecutor import com.github.spigotbasics.core.messages.Message import com.github.spigotbasics.core.module.BasicsModule import org.bukkit.permissions.Permission @@ -39,7 +39,7 @@ class ParsedCommandBuilder( private fun executor(executor: BasicsCommandExecutor) = apply { this.executor = executor } - private fun executor(command: Command) = + private fun executor(command: ParsedCommandExecutor) = apply { this.executor = object : BasicsCommandExecutor(module) { @@ -60,7 +60,7 @@ class ParsedCommandBuilder( } override fun tabComplete(context: BasicsCommandContext): MutableList { - return command.tabComplete(context.args).toMutableList() + return command.tabComplete(context.sender, context.args).toMutableList() } } } @@ -73,7 +73,7 @@ class ParsedCommandBuilder( private fun build(): BasicsCommand { val command = - Command( + ParsedCommandExecutor( parsedExecutor ?: error("parsedExecutor must be set"), argumentPaths ?: error("Argument paths must be set"), ) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt similarity index 75% rename from core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt rename to core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt index f2df20b1..ba29091b 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/Command.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt @@ -4,8 +4,9 @@ import com.github.spigotbasics.common.Either import com.github.spigotbasics.core.command.CommandResult import com.github.spigotbasics.core.messages.Message import org.bukkit.command.CommandSender +import org.bukkit.permissions.Permission -class Command( +class ParsedCommandExecutor( private val executor: CommandExecutor, private val paths: List>, ) { @@ -49,6 +50,7 @@ class Command( var shortestPathFailure: ParseResult.Failure? = null var bestMatchResult: PathMatchResult? = null var errors: List? = null + var missingPermission: Permission? = null sortedPaths.forEach { path -> val matchResult = path.matches(sender, input) @@ -59,23 +61,31 @@ class Command( if (errors == null || errors!!.size > newErrors.size) { errors = newErrors } - } else if (matchResult is Either.Left && matchResult.value == PathMatchResult.YES_BUT_NOT_FROM_CONSOLE) { + } else if (matchResult is Either.Left && + ( + matchResult.value == PathMatchResult.YES_BUT_NOT_FROM_CONSOLE || + matchResult.value == PathMatchResult.YES_BUT_NO_PERMISSION + ) + ) { bestMatchResult = matchResult.value + if (matchResult.value == PathMatchResult.YES_BUT_NO_PERMISSION) { + missingPermission = path.permission.firstOrNull { !sender.hasPermission(it) } + } } else if (matchResult is Either.Left && matchResult.value == PathMatchResult.YES) { when (val result = path.parse(sender, input)) { is ParseResult.Success -> { executor.execute(sender, result.context) - println("Command executed successfully.") + // println("Command executed successfully.") return Either.Left(CommandResult.SUCCESS) } is ParseResult.Failure -> { - println("Path failed to parse: $result") - result.errors.forEach { println(it) } // Optionally handle or display errors if necessary for debugging + // println("Path failed to parse: $result") + // result.errors.forEach { println(it) } // Optionally handle or display errors if necessary for debugging // Might comment out the part after || below v v v if (shortestPathFailure == null || result.errors.size < shortestPathFailure!!.errors.size) { - println("Shortest path failure: $result") + // println("Shortest path failure: $result") shortestPathFailure = result } } @@ -92,6 +102,9 @@ class Command( if (bestMatchResult == PathMatchResult.YES_BUT_NOT_FROM_CONSOLE) { return Either.Left(CommandResult.NOT_FROM_CONSOLE) } + if (bestMatchResult == PathMatchResult.YES_BUT_NO_PERMISSION && missingPermission != null) { + return Either.Left(CommandResult.noPermission(missingPermission!!)) + } if (errors != null) { errors!![0].sendToSender(sender) @@ -102,11 +115,16 @@ class Command( } } - fun tabComplete(input: List): List { + fun tabComplete( + sender: CommandSender, + input: List, + ): List { // Attempt to find the best matching ArgumentPath for the current input // and return its tab completions. val completions = mutableListOf() for (path in paths) { + if (!path.isCorrectSender(sender)) continue + if (!path.hasPermission(sender)) continue completions.addAll(path.tabComplete(input)) } // Remove duplicates and return diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArg.kt similarity index 75% rename from core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArgument.kt rename to core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArg.kt index 73883681..0163d3fb 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/IntArg.kt @@ -2,6 +2,6 @@ package com.github.spigotbasics.core.command.parsed.arguments import com.github.spigotbasics.core.command.parsed.CommandArgument -class IntArgument(name: String) : CommandArgument(name) { +class IntArg(name: String) : CommandArgument(name) { override fun parse(value: String): Int? = value.toIntOrNull() } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/ItemMaterialArg.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/ItemMaterialArg.kt new file mode 100644 index 00000000..065567ea --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/ItemMaterialArg.kt @@ -0,0 +1,28 @@ +package com.github.spigotbasics.core.command.parsed.arguments + +import com.github.spigotbasics.common.Dictionary +import com.github.spigotbasics.core.command.parsed.CommandArgument +import com.github.spigotbasics.core.extensions.partialMatches +import com.github.spigotbasics.core.logger.BasicsLoggerFactory +import org.bukkit.Material + +class ItemMaterialArg(name: String) : CommandArgument(name) { + companion object { + private val logger = BasicsLoggerFactory.getCoreLogger(ItemMaterialArg::class) + + private val materials = Dictionary.from(Material.entries.filter { it.isItem }.map { it.name to it }) + private val materialNames = materials.keys.toList().sorted() + + init { + logger.info("${materials.size} items loaded from Bukkit's Material class.") + } + } + + override fun parse(value: String): Material? { + return materials[value] + } + + override fun tabComplete(typing: String): List { + return materialNames.partialMatches(typing) + } +} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt deleted file mode 100644 index 201bd821..00000000 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/MaterialArgument.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.github.spigotbasics.core.command.parsed.arguments - -import com.github.spigotbasics.common.Dictionary -import com.github.spigotbasics.core.command.parsed.CommandArgument -import com.github.spigotbasics.core.extensions.partialMatches -import org.bukkit.Material - -class MaterialArgument(name: String) : CommandArgument(name) { - private val materials = Dictionary.from(Material.entries.filter { it.isItem }.map { it.name to it }) - private val materialNames = materials.keys.toList().sorted() - - override fun parse(value: String): Material? { - return materials[value] - } - - override fun tabComplete(typing: String): List { - return materialNames.partialMatches(typing) - } -} diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArgument.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArg.kt similarity index 91% rename from core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArgument.kt rename to core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArg.kt index 361c6a2f..aeeb5543 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArgument.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/PlayerArg.kt @@ -7,7 +7,7 @@ import com.github.spigotbasics.core.messages.Message import org.bukkit.Bukkit import org.bukkit.entity.Player -class PlayerArgument(name: String) : CommandArgument(name) { +class PlayerArg(name: String) : CommandArgument(name) { override fun parse(value: String): Player? { return Bukkit.getPlayer(value) } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/messages/tags/providers/ItemStackTag.kt b/core/src/main/kotlin/com/github/spigotbasics/core/messages/tags/providers/ItemStackTag.kt new file mode 100644 index 00000000..9561f0ba --- /dev/null +++ b/core/src/main/kotlin/com/github/spigotbasics/core/messages/tags/providers/ItemStackTag.kt @@ -0,0 +1,27 @@ +package com.github.spigotbasics.core.messages.tags.providers + +import com.github.spigotbasics.core.extensions.toHumanReadable +import com.github.spigotbasics.core.messages.tags.CustomTag +import com.github.spigotbasics.core.messages.tags.CustomTagType +import com.github.spigotbasics.core.messages.tags.MessageTagProvider +import org.bukkit.inventory.ItemStack + +class ItemStackTag(private val item: ItemStack) : MessageTagProvider { + override fun getMessageTags(): List { + val alwaysAvailable = + listOf( + CustomTag("item-type", item.type.name.toHumanReadable(), CustomTagType.PARSED), + CustomTag("item-amount", item.amount.toString(), CustomTagType.PARSED), + CustomTag("item-max-stack-size", item.maxStackSize.toString(), CustomTagType.PARSED), + ) + val onlyWithMeta = mutableListOf() + + // Unparsed tags, because they're player-changeable (ok lore maybe not - but still!) + if (item.hasItemMeta()) { + val meta = item.itemMeta!! + onlyWithMeta.add(CustomTag("item-display-name", meta.displayName, CustomTagType.UNPARSED)) + onlyWithMeta.add(CustomTag("item-lore", meta.lore?.joinToString("\n") ?: "", CustomTagType.UNPARSED)) + } + return alwaysAvailable + onlyWithMeta + } +} diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt index 51ca5be7..a55fa156 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt @@ -1,14 +1,15 @@ package com.github.spigotbasics.modules.basicsgive -import com.github.spigotbasics.core.command.parsed.ArgumentPath import com.github.spigotbasics.core.command.parsed.AnySender +import com.github.spigotbasics.core.command.parsed.ArgumentPath import com.github.spigotbasics.core.command.parsed.PlayerSender -import com.github.spigotbasics.core.command.parsed.arguments.IntArgument -import com.github.spigotbasics.core.command.parsed.arguments.MaterialArgument -import com.github.spigotbasics.core.command.parsed.arguments.PlayerArgument -import com.github.spigotbasics.core.extensions.toHumanReadable +import com.github.spigotbasics.core.command.parsed.arguments.IntArg +import com.github.spigotbasics.core.command.parsed.arguments.ItemMaterialArg +import com.github.spigotbasics.core.command.parsed.arguments.PlayerArg +import com.github.spigotbasics.core.messages.tags.providers.ItemStackTag import com.github.spigotbasics.core.module.AbstractBasicsModule import com.github.spigotbasics.core.module.loader.ModuleInstantiationContext +import org.bukkit.Bukkit import org.bukkit.Material import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack @@ -17,19 +18,34 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu val permission = permissionManager.createSimplePermission("basics.give", "Allows the player to use the /give command") + val permissionOthers = + permissionManager.createSimplePermission( + "basics.give.others", + "Allows to give items to others using the /give command", + ) + fun msgGiveOthers( receiver: Player, item: ItemStack, - ) = messages.getMessage("give-others").concerns(receiver).tagParsed("item", item.type.name.toHumanReadable()) - .tagParsed("amount", item.amount.toString()) + ) = messages.getMessage("give-others") + .concerns(receiver) + .tags(ItemStackTag(item)) + + fun msgGiveSelf( + receiver: Player, + item: ItemStack, + ) = messages.getMessage("give-self") + .concerns(receiver) + .tags(ItemStackTag(item)) val pathPlayerItem = ArgumentPath( AnySender, listOf( - PlayerArgument("Receiving Player"), - MaterialArgument("Item"), + PlayerArg("Receiving Player"), + ItemMaterialArg("Item"), ), + listOf(permissionOthers), ) { _, parsedArgs -> GiveContext(parsedArgs[0] as Player, parsedArgs[1] as Material) } @@ -38,7 +54,7 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu ArgumentPath( PlayerSender, listOf( - MaterialArgument("Item"), + ItemMaterialArg("Item"), ), ) { sender, parsedArgs -> GiveContext(sender as Player, parsedArgs[0] as Material) @@ -48,8 +64,8 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu ArgumentPath( PlayerSender, listOf( - MaterialArgument("Item"), - IntArgument("Amount"), + ItemMaterialArg("Item"), + IntArg("Amount"), ), ) { sender, parsedArgs -> GiveContext(sender as Player, parsedArgs[0] as Material, parsedArgs[1] as Int) @@ -59,10 +75,11 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu ArgumentPath( AnySender, listOf( - PlayerArgument("Receiving Player"), - MaterialArgument("Item"), - IntArgument("Amount"), + PlayerArg("Receiving Player"), + ItemMaterialArg("Item"), + IntArg("Amount"), ), + listOf(permissionOthers), ) { _, parsedArgs -> GiveContext(parsedArgs[0] as Player, parsedArgs[1] as Material, parsedArgs[2] as Int) } @@ -71,6 +88,16 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu createParsedCommand("give", permission) .paths(listOf(pathItem, pathPlayerItem, pathItemAmount, pathPlayerItemAmount)) .executor(GiveExecutor(this)) + .usage("[Receiving Player] [Amount]") + .register() + + createCommand("givesnbt", permission) + .executor { context -> + val snbt = context.args[0] + val item = Bukkit.getItemFactory().createItemStack(snbt) + (context.sender as Player).inventory.addItem(item) + null + } .register() } } diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt index 5a1803f9..3f0160e0 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/GiveExecutor.kt @@ -10,8 +10,16 @@ class GiveExecutor(private val module: BasicsGiveModule) : CommandExecutorGave <#amount>x <#item> to ." \ No newline at end of file +give: "Gave <#item-amount>x <#item-type> to yourself." +give-others: "Gave <#item-amount>x <#item-type> to ." \ No newline at end of file diff --git a/plugin/src/main/kotlin/com/github/spigotbasics/plugin/BasicsPluginImpl.kt b/plugin/src/main/kotlin/com/github/spigotbasics/plugin/BasicsPluginImpl.kt index 268aca8d..291de041 100644 --- a/plugin/src/main/kotlin/com/github/spigotbasics/plugin/BasicsPluginImpl.kt +++ b/plugin/src/main/kotlin/com/github/spigotbasics/plugin/BasicsPluginImpl.kt @@ -6,6 +6,7 @@ import com.github.spigotbasics.core.ChunkTicketManager import com.github.spigotbasics.core.Constants import com.github.spigotbasics.core.MinecraftVersion import com.github.spigotbasics.core.Spiper +import com.github.spigotbasics.core.command.parsed.arguments.ItemMaterialArg import com.github.spigotbasics.core.config.CoreConfigManager import com.github.spigotbasics.core.config.FixClassLoadingConfig import com.github.spigotbasics.core.logger.BasicsLoggerFactory @@ -110,6 +111,8 @@ class BasicsPluginImpl : JavaPlugin(), BasicsPlugin { return } + initializeHeavyClasses() + // ::storageManager.get() server.pluginManager.registerEvents(CorePlayerDataListener(corePlayerData), this) @@ -121,6 +124,12 @@ class BasicsPluginImpl : JavaPlugin(), BasicsPlugin { getCommand("basicsdebug")?.setExecutor(BasicsDebugCommand(this)) } + private fun initializeHeavyClasses() { + logger.info("Initializing heavy classes...") + ItemMaterialArg.Companion + logger.info("Heavy classes initialized.") + } + private fun reloadCustomTags() { tagResolverFactory.loadAndCacheAllTagResolvers( coreConfigManager.getConfig( From 7c66542a05e6e25e5fecbca9df810d23c921992d Mon Sep 17 00:00:00 2001 From: mfnalex Date: Mon, 12 Feb 2024 01:40:44 +0100 Subject: [PATCH 23/25] fixed /give messages, show usage when args are empty --- .../core/command/parsed/ParsedCommandExecutor.kt | 8 ++++++++ .../core/messages/tags/providers/ItemStackTag.kt | 11 +++++------ .../modules/basicsgive/BasicsGiveModule.kt | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt index ba29091b..36db6a8e 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt @@ -44,6 +44,14 @@ class ParsedCommandExecutor( sender: CommandSender, input: List, ): Either { + + // Empty args = show usage, unless an empty path is registered + if(input.isEmpty()) { + if(!paths.any { it.arguments.isEmpty() }) { + return Either.Left(CommandResult.USAGE) + } + } + // Sort paths by the number of arguments they expect, ascending. val sortedPaths = paths.sortedBy { it.arguments.size } diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/messages/tags/providers/ItemStackTag.kt b/core/src/main/kotlin/com/github/spigotbasics/core/messages/tags/providers/ItemStackTag.kt index 9561f0ba..cd9fa8c0 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/messages/tags/providers/ItemStackTag.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/messages/tags/providers/ItemStackTag.kt @@ -2,7 +2,6 @@ package com.github.spigotbasics.core.messages.tags.providers import com.github.spigotbasics.core.extensions.toHumanReadable import com.github.spigotbasics.core.messages.tags.CustomTag -import com.github.spigotbasics.core.messages.tags.CustomTagType import com.github.spigotbasics.core.messages.tags.MessageTagProvider import org.bukkit.inventory.ItemStack @@ -10,17 +9,17 @@ class ItemStackTag(private val item: ItemStack) : MessageTagProvider { override fun getMessageTags(): List { val alwaysAvailable = listOf( - CustomTag("item-type", item.type.name.toHumanReadable(), CustomTagType.PARSED), - CustomTag("item-amount", item.amount.toString(), CustomTagType.PARSED), - CustomTag("item-max-stack-size", item.maxStackSize.toString(), CustomTagType.PARSED), + CustomTag.parsed("item-type", item.type.name.toHumanReadable()), + CustomTag.parsed("item-amount", item.amount.toString()), + CustomTag.parsed("item-max-stack-size", item.maxStackSize.toString()), ) val onlyWithMeta = mutableListOf() // Unparsed tags, because they're player-changeable (ok lore maybe not - but still!) if (item.hasItemMeta()) { val meta = item.itemMeta!! - onlyWithMeta.add(CustomTag("item-display-name", meta.displayName, CustomTagType.UNPARSED)) - onlyWithMeta.add(CustomTag("item-lore", meta.lore?.joinToString("\n") ?: "", CustomTagType.UNPARSED)) + onlyWithMeta.add(CustomTag.unparsed("item-display-name", meta.displayName)) + onlyWithMeta.add(CustomTag.unparsed("item-lore", meta.lore?.joinToString("\n") ?: "")) } return alwaysAvailable + onlyWithMeta } diff --git a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt index a55fa156..a86b947b 100644 --- a/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt +++ b/modules/basics-give/src/main/kotlin/com/github/spigotbasics/modules/basicsgive/BasicsGiveModule.kt @@ -34,7 +34,7 @@ class BasicsGiveModule(context: ModuleInstantiationContext) : AbstractBasicsModu fun msgGiveSelf( receiver: Player, item: ItemStack, - ) = messages.getMessage("give-self") + ) = messages.getMessage("give") .concerns(receiver) .tags(ItemStackTag(item)) From 5a1dc98f75b6e71cf9e3d6e724c6e81c7baca66e Mon Sep 17 00:00:00 2001 From: mfnalex Date: Mon, 12 Feb 2024 01:41:30 +0100 Subject: [PATCH 24/25] made ktlint happy --- .../core/command/parsed/ParsedCommandExecutor.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt index 36db6a8e..63f1aa96 100644 --- a/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt +++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/parsed/ParsedCommandExecutor.kt @@ -44,10 +44,9 @@ class ParsedCommandExecutor( sender: CommandSender, input: List, ): Either { - // Empty args = show usage, unless an empty path is registered - if(input.isEmpty()) { - if(!paths.any { it.arguments.isEmpty() }) { + if (input.isEmpty()) { + if (!paths.any { it.arguments.isEmpty() }) { return Either.Left(CommandResult.USAGE) } } From 231e203e98d792beae7f3e7a51b3571a3f72587e Mon Sep 17 00:00:00 2001 From: mfnalex Date: Mon, 12 Feb 2024 01:43:12 +0100 Subject: [PATCH 25/25] reenable gradle cache --- .github/workflows/build.yml | 2 +- .github/workflows/dependency-graph.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 706aae1c..4ab32967 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: with: java-version: '17' distribution: 'temurin' -# cache: "gradle" + cache: "gradle" - name: Setup Gradle uses: gradle/actions/setup-gradle@ec92e829475ac0c2315ea8f9eced72db85bb337a # v3.0.0 diff --git a/.github/workflows/dependency-graph.yml b/.github/workflows/dependency-graph.yml index e0496b95..01252eb3 100644 --- a/.github/workflows/dependency-graph.yml +++ b/.github/workflows/dependency-graph.yml @@ -20,7 +20,7 @@ jobs: with: java-version: '17' distribution: 'temurin' -# cache: "gradle" + cache: "gradle" - name: Generate and submit dependency graph uses: gradle/actions/dependency-submission@ec92e829475ac0c2315ea8f9eced72db85bb337a # v3.0.0