From 382da33eb5a3d999bdf229b5336b54323c54fe99 Mon Sep 17 00:00:00 2001 From: MattMX Date: Sun, 7 Jul 2024 14:55:18 +0100 Subject: [PATCH] Fixed argument processing + placeholders api wrapper TODO still need to fix options/flags and finally suggestion invocations --- .../caches/paperweight/taskCache/reobfJar.log | 2 +- .../declarative/ChainCommandBuilder.kt | 6 +- .../declarative/DeclarativeCommandBuilder.kt | 17 +++- .../commands/declarative/arg/Argument.kt | 4 +- .../declarative/arg/ArgumentConsumer.kt | 41 ++++----- .../declarative/arg/impl/FlagArgument.kt | 2 +- .../arg/impl/MultiChoiceArgument.kt | 2 +- .../arg/impl/RelativeCoordinateArgument.kt | 4 +- .../commands/declarative/arg/impl/args.kt | 3 + .../ktgui/papi/PlaceholderExpansionWrapper.kt | 8 +- .../kotlin/com/mattmx/ktgui/utils/color.kt | 4 +- .../caches/paperweight/taskCache/reobfJar.log | 2 +- .../main/kotlin/com/mattmx/ktgui/KotlinGui.kt | 92 ++----------------- .../mattmx/ktgui/designer/DesignerManager.kt | 74 +++++++++++++++ .../com/mattmx/ktgui/designer/GuiDesigner.kt | 8 +- .../ktgui/designer/GuiDesignerButton.kt | 6 +- 16 files changed, 143 insertions(+), 132 deletions(-) create mode 100644 plugin/src/main/kotlin/com/mattmx/ktgui/designer/DesignerManager.kt diff --git a/api/.gradle/caches/paperweight/taskCache/reobfJar.log b/api/.gradle/caches/paperweight/taskCache/reobfJar.log index c36ff98..73f8e1d 100644 --- a/api/.gradle/caches/paperweight/taskCache/reobfJar.log +++ b/api/.gradle/caches/paperweight/taskCache/reobfJar.log @@ -1,2 +1,2 @@ Command: C:\Program Files\Java\jdk-17\bin\java.exe -Xmx1G -classpath C:\Users\Mangr\.gradle\caches\modules-2\files-2.1\net.fabricmc\tiny-remapper\0.10.1\c293b2384ae12af74f407fa3aaa553bba4ac6763\tiny-remapper-0.10.1-fat.jar net.fabricmc.tinyremapper.Main D:\PC\Projects\KtBukkitGui\api\build\libs\ktgui-2.4.1-dev-all.jar D:\PC\Projects\KtBukkitGui\api\build\libs\api-2.4.1.jar C:\Users\Mangr\.gradle\caches\paperweight-userdev\ff775525efc29c3503a07d1006e63e5695a742b7505cf63e157d49d32419c69f\module\io.papermc.paper\dev-bundle\1.20.4-R0.1-SNAPSHOT\paperweight\setupCache\extractDevBundle.dir\data\mojang+yarn-spigot-reobf.tiny mojang+yarn spigot C:\Users\Mangr\.gradle\caches\paperweight-userdev\ff775525efc29c3503a07d1006e63e5695a742b7505cf63e157d49d32419c69f\module\io.papermc.paper\dev-bundle\1.20.4-R0.1-SNAPSHOT\paperweight\setupCache\applyMojangMappedPaperclipPatch.jar --threads=1 -Finished after 2525.50 ms. +Finished after 2839.29 ms. diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/ChainCommandBuilder.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/ChainCommandBuilder.kt index 09f6af9..003de58 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/ChainCommandBuilder.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/ChainCommandBuilder.kt @@ -20,9 +20,6 @@ class ChainCommandBuilder(val name: String) { subcommands.addAll(command) } - inline infix fun runs(noinline block: RunnableCommandContext.() -> Unit) = - build().runs(block) - fun build() = build(DeclarativeCommandBuilder(name)) fun build(existing: T) = existing.apply { @@ -31,6 +28,9 @@ class ChainCommandBuilder(val name: String) { } } +inline infix fun ChainCommandBuilder.runs(noinline block: RunnableCommandContext.() -> Unit) = + build().runs(block) + inline operator fun ChainCommandBuilder.invoke(block: DeclarativeCommandBuilder.() -> Unit) = build().apply(block) diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeCommandBuilder.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeCommandBuilder.kt index 26e7aa5..f238413 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeCommandBuilder.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeCommandBuilder.kt @@ -22,7 +22,6 @@ import org.bukkit.permissions.PermissionDefault import java.time.Duration import java.util.* import java.util.function.Consumer -import kotlin.math.exp open class DeclarativeCommandBuilder( val name: String @@ -152,6 +151,12 @@ open class DeclarativeCommandBuilder( inline operator fun ChainCommandBuilder.invoke(block: DeclarativeSubCommandBuilder.() -> Unit) = subcommand(this, block) + inline infix fun ChainCommandBuilder.runs(noinline block: RunnableCommandContext.() -> Unit) = + build().runs(block).let { + this@DeclarativeCommandBuilder.subcommands += it + it + } + inline operator fun String.invoke(block: DeclarativeSubCommandBuilder.() -> Unit) = fromString(this).let { val subCommand = DeclarativeSubCommandBuilder(it.name) @@ -334,15 +339,19 @@ open class DeclarativeCommandBuilder( val processorClone = argumentProcessor.clone() val result = arg.consumer.consume(processorClone) - val actualValue = arg.getValueOfString(this, context, result.stringValue) + val actualValue = arg.getValueOfString( + this, + context, + result.args + ) if (actualValue != null || arg.isOptional()) { - argumentValues[arg.name()] = arg.createContext(result.stringValue, actualValue) + argumentValues[arg.name()] = arg.createContext(result.argsAsStringValue, actualValue) argumentProcessor.pointer = processorClone.pointer argumentProcessor.optionsAndFlagsValues = processorClone.optionsAndFlagsValues } else { val invalidArgumentContext = - InvalidArgContext(context.sender, context.alias, context.rawArgs, arg, result.stringValue) + InvalidArgContext(context.sender, context.alias, context.rawArgs, arg, result.argsAsStringValue) if (arg.invokeInvalid(invalidArgumentContext)) { return diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/Argument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/Argument.kt index 4b81d9a..ec8e9e1 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/Argument.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/Argument.kt @@ -115,9 +115,9 @@ open class Argument( open fun getValueOfString( cmd: DeclarativeCommandBuilder?, context: BaseCommandContext<*>?, - split: List + split: List? ): T? { - return getValueOfString(cmd, context, split.joinToString(" ")) + return getValueOfString(cmd, context, split?.joinToString(" ")) } open fun getValueOfString( diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ArgumentConsumer.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ArgumentConsumer.kt index 6457a18..924081f 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ArgumentConsumer.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ArgumentConsumer.kt @@ -5,15 +5,18 @@ fun interface ArgumentConsumer { fun consume(processor: ArgumentProcessor): Result class Result( - val stringValue: String?, - val consumed: List + val args: List? ) { - fun isEmpty() = stringValue == null + constructor(single: String?) : this(single?.let { listOf(it) }) - override fun toString() = "Result('$stringValue', [${consumed.joinToString(", ")}])" + val argsAsStringValue = args?.joinToString(" ") + + fun isEmpty() = args.isNullOrEmpty() + + override fun toString() = "Result($args)" companion object { - private val EMPTY = Result(null, emptyList()) + private val EMPTY = Result(emptyList()) fun empty() = EMPTY } @@ -21,7 +24,7 @@ fun interface ArgumentConsumer { companion object { private val NONE = ArgumentConsumer { _ -> Result.empty() } - private val SINGLE = ArgumentConsumer { processor -> Result(processor.next(), listOf(processor.pointer)) } + private val SINGLE = ArgumentConsumer { processor -> ArgumentConsumer.Result(processor.next()) } @JvmStatic fun none() = NONE @@ -29,10 +32,9 @@ fun interface ArgumentConsumer { fun single() = SINGLE @JvmStatic - infix fun untilFalse(predicate: (ArgumentProcessor, String) -> Boolean) = ArgumentConsumer { processor -> + infix fun untilFalse(predicate: (ArgumentProcessor, List) -> Boolean) = ArgumentConsumer { processor -> var current: String? = "" - val startIndex = processor.pointer + 1 - var fullString = "" + val consumed = arrayListOf() while (current != null) { current = processor.next() @@ -41,40 +43,37 @@ fun interface ArgumentConsumer { return@ArgumentConsumer Result.empty() } - fullString += "$current " - fullString = fullString.trim() + consumed += current - if (!predicate(processor, fullString)) { - return@ArgumentConsumer Result(fullString, (startIndex..processor.pointer).toList()) + if (!predicate(processor, consumed)) { + return@ArgumentConsumer Result(consumed) } } Result.empty() } @JvmStatic - infix fun until(predicate: (ArgumentProcessor, String) -> Boolean) = untilFalse { p, s -> !predicate(p, s) } + infix fun until(predicate: (ArgumentProcessor, List) -> Boolean) = untilFalse { p, s -> !predicate(p, s) } @JvmStatic infix fun untilFalsePartial(predicate: (ArgumentProcessor, String) -> Boolean) = ArgumentConsumer { processor -> var current: String? = null - val startIndex = processor.pointer + 1 - var fullString = "" + val consumed = arrayListOf() while (current != null) { current = processor.next() if (current == null) { - return@ArgumentConsumer Result(fullString, (startIndex..processor.pointer).toList()) + return@ArgumentConsumer Result(consumed) } - fullString += "$current " - fullString = fullString.trim() + consumed += current if (!predicate(processor, current)) { - return@ArgumentConsumer Result(fullString, (startIndex..processor.pointer).toList()) + return@ArgumentConsumer Result(consumed) } } - Result(fullString, (startIndex..processor.pointer).toList()) + Result(consumed) } @JvmStatic diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/FlagArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/FlagArgument.kt index 1443032..d8fe287 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/FlagArgument.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/FlagArgument.kt @@ -27,7 +27,7 @@ class FlagArgument( override fun getValueOfString( cmd: DeclarativeCommandBuilder?, context: BaseCommandContext<*>?, - split: List + split: List? ): Boolean { // todo context should contain included flags/options return false diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/MultiChoiceArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/MultiChoiceArgument.kt index 8b1536d..194d3e5 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/MultiChoiceArgument.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/MultiChoiceArgument.kt @@ -15,7 +15,7 @@ class MultiChoiceArgument( init { this.consumes( ArgumentConsumer.until { argumentProcessor, s -> - choices().containsKey(s) + choices().containsKey(s.joinToString(" ")) } ) suggests { choices().keys.toList() } diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/RelativeCoordinateArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/RelativeCoordinateArgument.kt index 820850b..41ee7f5 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/RelativeCoordinateArgument.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/RelativeCoordinateArgument.kt @@ -20,9 +20,9 @@ class RelativeCoordinateArgument( override fun getValueOfString( cmd: DeclarativeCommandBuilder?, context: BaseCommandContext<*>?, - split: List + split: List? ): Location? { - if (split.size != 3) return null + if (split?.size != 3) return null val entity = (context?.sender as Entity?) ?: return null diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/args.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/args.kt index 68ccba3..4a694cf 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/args.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/args.kt @@ -56,6 +56,9 @@ fun multiChoiceArgument(choices: HashMap) = fun multiChoiceArgument(choiceSupplier: () -> HashMap) = delegateArgument(MultiChoiceArgument(DELEGATED_ARG_NAME) { choiceSupplier() }) +fun multiChoiceStringArgument(choiceSupplier: List) = + delegateArgument(MultiChoiceArgument(DELEGATED_ARG_NAME) { choiceSupplier.associateWithTo(HashMap()) { it } }) + fun multiChoiceStringArgument(vararg choiceSupplier: String) = delegateArgument(MultiChoiceArgument(DELEGATED_ARG_NAME) { choiceSupplier.associateWithTo(HashMap()) { it } }) diff --git a/api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderExpansionWrapper.kt b/api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderExpansionWrapper.kt index 95d53a1..bb2b487 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderExpansionWrapper.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderExpansionWrapper.kt @@ -83,15 +83,15 @@ class PlaceholderExpansionWrapper( for (expArg in placeholder.match.arguments) { if (invalid) continue - val stringValue = expArg.consume(argumentParser) + val consumeResult = expArg.consume(argumentParser) - if (expArg.isRequired() && stringValue.isEmpty()) { + if (expArg.isRequired() && consumeResult.isEmpty()) { invalid = true if (isDebug) { owner.logger.warning( "Placeholder(${ identifier - }) Failed parsing for arg $expArg in placeholder $name - $stringValue" + }) Failed parsing for arg $expArg in placeholder $name - $consumeResult" ) } continue @@ -99,7 +99,7 @@ class PlaceholderExpansionWrapper( args[expArg.name()] = expArg.createContext( emptyCommand, baseContext, - stringValue.stringValue?.split("_", " ") ?: emptyList() + consumeResult.args ?: emptyList() ) } } diff --git a/api/src/main/kotlin/com/mattmx/ktgui/utils/color.kt b/api/src/main/kotlin/com/mattmx/ktgui/utils/color.kt index bf70407..d19ac8d 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/utils/color.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/utils/color.kt @@ -27,7 +27,8 @@ fun Component.json() = gsonSerializer.serialize(this) fun Component.legacy() = legacySerializer.serialize(this) fun String.jsonToComponent() = gsonSerializer.deserialize(this) fun JsonElement.component() = gsonSerializer.deserializeFromTree(this) -fun String.component() = serializer.deserialize(this) +fun String.component() = component(null) +infix fun String.component(player: OfflinePlayer?) = serializer.deserialize(this.placeholders(null)) val String.component: Component get() = component() fun String.legacyToComponent() = legacySerializer.deserialize(this) @@ -53,6 +54,7 @@ operator fun Component.plus(component: Component) = this.append(component) infix fun Component.clickEvent(event: ClickEvent) = clickEvent(event) infix fun Component.hoverEvent(event: HoverEvent) = hoverEvent(event) operator fun String.not() = component() +operator fun String.minus(player: OfflinePlayer?) = component(player) val String.translatable get() = Component.translatable(this) diff --git a/plugin/.gradle/caches/paperweight/taskCache/reobfJar.log b/plugin/.gradle/caches/paperweight/taskCache/reobfJar.log index c9559bd..b10cd69 100644 --- a/plugin/.gradle/caches/paperweight/taskCache/reobfJar.log +++ b/plugin/.gradle/caches/paperweight/taskCache/reobfJar.log @@ -1,2 +1,2 @@ Command: C:\Program Files\Java\jdk-17\bin\java.exe -Xmx1G -classpath C:\Users\Mangr\.gradle\caches\modules-2\files-2.1\net.fabricmc\tiny-remapper\0.10.1\c293b2384ae12af74f407fa3aaa553bba4ac6763\tiny-remapper-0.10.1-fat.jar net.fabricmc.tinyremapper.Main D:\PC\Projects\KtBukkitGui\plugin\build\libs\ktgui-plugin-2.4.1-dev-all.jar D:\PC\Projects\KtBukkitGui\plugin\build\libs\plugin-unspecified.jar C:\Users\Mangr\.gradle\caches\paperweight-userdev\ff775525efc29c3503a07d1006e63e5695a742b7505cf63e157d49d32419c69f\module\io.papermc.paper\dev-bundle\1.20.4-R0.1-SNAPSHOT\paperweight\setupCache\extractDevBundle.dir\data\mojang+yarn-spigot-reobf.tiny mojang+yarn spigot C:\Users\Mangr\.gradle\caches\paperweight-userdev\ff775525efc29c3503a07d1006e63e5695a742b7505cf63e157d49d32419c69f\module\io.papermc.paper\dev-bundle\1.20.4-R0.1-SNAPSHOT\paperweight\setupCache\applyMojangMappedPaperclipPatch.jar --threads=1 -Finished after 1601.92 ms. +Finished after 1655.39 ms. diff --git a/plugin/src/main/kotlin/com/mattmx/ktgui/KotlinGui.kt b/plugin/src/main/kotlin/com/mattmx/ktgui/KotlinGui.kt index 1ecbdc9..4b9d24b 100644 --- a/plugin/src/main/kotlin/com/mattmx/ktgui/KotlinGui.kt +++ b/plugin/src/main/kotlin/com/mattmx/ktgui/KotlinGui.kt @@ -5,10 +5,12 @@ import com.mattmx.ktgui.commands.declarative.arg.suggestsTopLevel import com.mattmx.ktgui.commands.declarative.arg.withArgs import com.mattmx.ktgui.commands.declarative.div import com.mattmx.ktgui.commands.declarative.invoke +import com.mattmx.ktgui.commands.declarative.runs import com.mattmx.ktgui.commands.rawCommand import com.mattmx.ktgui.commands.usage.CommandUsageOptions import com.mattmx.ktgui.components.screen.GuiScreen import com.mattmx.ktgui.cooldown.ActionCoolDown +import com.mattmx.ktgui.designer.DesignerManager import com.mattmx.ktgui.designer.GuiDesigner import com.mattmx.ktgui.examples.* import com.mattmx.ktgui.papi.placeholder @@ -108,7 +110,8 @@ class KotlinGui : JavaPlugin() { } placeholder("font-ph" / fontType / stringToConvert) { - val string = PlaceholderAPI.setPlaceholders(requestedBy, stringToConvert()) + val formatted = "%${stringToConvert().replace(" ", "_")}%" + val string = PlaceholderAPI.setPlaceholders(requestedBy, formatted) fontType()(string) } @@ -138,7 +141,6 @@ class KotlinGui : JavaPlugin() { } permission "ktgui.command.font" register this sync { - val cachedDesigners = hashMapOf() rawCommand("ktgui") { permission = "ktgui.command" playerOnly = true @@ -190,90 +192,6 @@ class KotlinGui : JavaPlugin() { } }.register(false) - "designer" { - buildAutomaticPermissions("ktgui.command") - withDefaultUsageSubCommand(defaultUsageOptions) - - val typeOrRowArgMessage = !"&cYou must provide an InventoryType or an amount of rows." - val typeOrRowArg by argument("type_or_row") - val id by argument("unique_id") - - typeOrRowArg suggestsTopLevel { InventoryType.values().map { it.name.lowercase() } } - typeOrRowArg invalid { reply(typeOrRowArgMessage) } - id missing { reply(!"&cMissing argument 'id'. Need an identifier for the designer UI.") } - - val create = ("create" / typeOrRowArg / id) { - runs { - val type = runCatching { - InventoryType.valueOf(typeOrRowArg().uppercase()) - }.getOrNull() - val rows = typeOrRowArg().toIntOrNull() - - if (type == null && rows == null) { - reply(typeOrRowArgMessage) - return@runs - } - - if (cachedDesigners.containsKey(id())) { - return@runs reply("&cThere is already a designer by that name.") - } - - val designer = - cachedDesigners.getOrPut(id()) { GuiDesigner(id(), type = type, rows = rows ?: 1) } - designer.open(sender) - } - } - - ("open" / id) { - - id suggests { cachedDesigners.keys.toList() } - - runs { - val designer = cachedDesigners[id()] - ?: return@runs reply( - !"&cInvalid id, create one using &7/&fdesigner ${ - create.getUsage( - defaultUsageOptions, - false - ) - }" - ) - designer.open(sender) - } - } - - val newTitle by argument("string") - ("set-title" / id / newTitle) { - - id suggests { cachedDesigners.keys.toList() } - - runs { - val designer = cachedDesigners[id()] - ?: return@runs reply( - !"&cInvalid id, create one using &7/&fdesigner ${ - create.getUsage( - defaultUsageOptions, - false - ) - }" - ) - designer.exportTitle = newTitle() - reply(!"&aSet title of ${id()} to ${newTitle()}") - } - } - - subcommand("export" / id) { - - id suggests { cachedDesigners.keys.toList() } - - runs { - val designer = cachedDesigners.getOrPut(id()) { GuiDesigner(id()) } - val file = designer.save(this@KotlinGui) - reply(!"&aSaved to /plugins/KtGUI/designer/${file.name}") - } - } - } register this@KotlinGui - "ktgui-cmd-examples" { buildAutomaticPermissions("ktgui.examples.command") @@ -464,6 +382,8 @@ class KotlinGui : JavaPlugin() { reply(!getUsage(defaultUsageOptions)) } } register this@KotlinGui + + DesignerManager(this@KotlinGui) } } diff --git a/plugin/src/main/kotlin/com/mattmx/ktgui/designer/DesignerManager.kt b/plugin/src/main/kotlin/com/mattmx/ktgui/designer/DesignerManager.kt new file mode 100644 index 0000000..cac6db8 --- /dev/null +++ b/plugin/src/main/kotlin/com/mattmx/ktgui/designer/DesignerManager.kt @@ -0,0 +1,74 @@ +package com.mattmx.ktgui.designer + +import com.mattmx.ktgui.KotlinGui +import com.mattmx.ktgui.commands.declarative.arg.impl.* +import com.mattmx.ktgui.commands.declarative.arg.suggestsTopLevel +import com.mattmx.ktgui.commands.declarative.div +import com.mattmx.ktgui.commands.declarative.invoke +import com.mattmx.ktgui.utils.not +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player +import org.bukkit.event.inventory.InventoryType + +class DesignerManager( + private val plugin: KotlinGui +) { + private val cachedDesigners = hashMapOf() + + init { + "designer" { + buildAutomaticPermissions("ktgui.command") + withDefaultUsageSubCommand(KotlinGui.defaultUsageOptions) + + val typeOrRowArgMessage = !"&cYou must provide an InventoryType or an amount of rows." + val typeOrRow by multiChoiceStringArgument( + (1..6).toList().map(Int::toString) + + InventoryType.values().map { it.name.lowercase() } + ) + typeOrRow invalid { reply(typeOrRowArgMessage) } + + val id by stringArgument() + id matches "[0-9a-z]{3,16}".toRegex(RegexOption.IGNORE_CASE) + id invalid { reply(!"&cMissing argument 'id'. Need an identifier for the designer UI.") } + + ("create" / typeOrRow / id).runs { + val type = runCatching { + InventoryType.valueOf(typeOrRow().uppercase()) + }.getOrNull() + val rows = typeOrRow().toIntOrNull() + + if (type == null && rows == null) { + return@runs reply(typeOrRowArgMessage) + } + + if (cachedDesigners.containsKey(id())) { + return@runs reply("&cThere is already a designer by that name.") + } + + val designer = + cachedDesigners.getOrPut(id()) { GuiDesigner(id(), type = type, rows = rows ?: 1) } + designer.open(sender) + reply(!"&aCreated a designer called ${id()}") + } + + val existingDesigner by multiChoiceArgument { cachedDesigners } + existingDesigner invalid { reply(!"&cInvalid id, create one using &7/designer create") } + + ("open" / existingDesigner).runs { + existingDesigner().open(sender) + } + + val newTitle by greedyStringArgument() + ("setTitle" / existingDesigner / newTitle).runs { + existingDesigner().exportTitle = newTitle() + reply(!"&aSet title of ${existingDesigner().id} to ${newTitle()}") + } + + ("export" / existingDesigner).runs { + val file = existingDesigner().save(plugin) + reply(!"&aSaved to /plugins/KtGUI/designer/${file.name}") + } + } register this + } + +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/com/mattmx/ktgui/designer/GuiDesigner.kt b/plugin/src/main/kotlin/com/mattmx/ktgui/designer/GuiDesigner.kt index 75a69a4..4bef8b6 100644 --- a/plugin/src/main/kotlin/com/mattmx/ktgui/designer/GuiDesigner.kt +++ b/plugin/src/main/kotlin/com/mattmx/ktgui/designer/GuiDesigner.kt @@ -82,12 +82,12 @@ class GuiDesigner( } fun export(): String { - val start = "gui(!\"$exportTitle\") {\n" - val guiOption = if (type == null) " rows = $rows" else "type = InventoryType.${type!!.name}" + val guiOption = if (type == null) "rows = $rows" else "type = InventoryType.${type!!.name}" + val start = "gui(!\"$exportTitle\", ${guiOption}) {\n" val middle = items.values .filterIsInstance() - .filter { it.getItemStack()?.type != Material.AIR } - .joinToString("\n ") { it.full + " childOf this" } + .filter { it.formatIntoItemStack()?.type != Material.AIR } + .joinToString("\n ") { it.full } val end = "\n}" return "$start$guiOption\n$middle$end" diff --git a/plugin/src/main/kotlin/com/mattmx/ktgui/designer/GuiDesignerButton.kt b/plugin/src/main/kotlin/com/mattmx/ktgui/designer/GuiDesignerButton.kt index 1b43680..484a296 100644 --- a/plugin/src/main/kotlin/com/mattmx/ktgui/designer/GuiDesignerButton.kt +++ b/plugin/src/main/kotlin/com/mattmx/ktgui/designer/GuiDesignerButton.kt @@ -34,7 +34,11 @@ class GuiDesignerButton(item: ItemStack) : GuiButton(item) { val namedPart: String get() { - val name = getItemStack()!!.displayName().legacy().replace("§", "&") + val name = getItemStack()!! + .displayName() + .legacy() + .replace("§", "&") + return "named(!\"$name\")" }