From d32afc50c94806883ce3c7858b00684957f9c8a8 Mon Sep 17 00:00:00 2001 From: MattMX Date: Fri, 28 Jun 2024 13:06:48 +0100 Subject: [PATCH] Revert "Resolve merge conflicts hopefully" This reverts commit dfd9341b5bf832cd88ae01ae217b54fe1f9c7b3d, reversing changes made to 3578a8a0ca5ccc4fa69a136580a89b4dd1fa3546. --- .idea/gradle.xml | 1 + .idea/misc.xml | 4 - .idea/modules/plugin/ktgui.plugin.test.iml | 15 - .../caches/paperweight/taskCache/reobfJar.log | 2 - api/build.gradle.kts | 26 -- .../ktgui/commands/alpha/ArgumentType.kt | 7 + .../ktgui/commands/alpha/CommandSender.kt | 3 + .../ktgui/commands/alpha/KtCommandBuilder.kt | 118 ++++++++ .../declarative/ChainCommandBuilder.kt | 30 +- .../declarative/DeclarativeCommandBuilder.kt | 274 ++++++++---------- .../declarative/DeclarativeCommandWrapper.kt | 10 +- .../DeclarativeSubCommandBuilder.kt | 3 - .../commands/declarative/arg/Argument.kt | 89 +----- .../declarative/arg/ArgumentContext.kt | 4 +- .../declarative/arg/ProvidedArgsBlock.kt | 34 --- .../commands/declarative/arg/argTests.kt | 88 ------ .../arg/consumer/ArgumentConsumer.kt | 9 - .../arg/consumer/GreedyArgumentConsumer.kt | 7 - .../arg/consumer/SingleArgumentConsumer.kt | 7 - .../arg/consumer/VariableArgumentConsumer.kt | 9 - .../declarative/arg/impl/DoubleArgument.kt | 44 --- .../declarative/arg/impl/EnumArgument.kt | 32 -- .../declarative/arg/impl/FlagArgument.kt | 23 -- .../declarative/arg/impl/IntArgument.kt | 44 --- .../declarative/arg/impl/LongArgument.kt | 44 --- .../declarative/arg/impl/MultiArgument.kt | 20 -- .../arg/impl/MultiChoiceArgument.kt | 14 - .../arg/impl/OnlinePlayerArgument.kt | 10 - .../declarative/arg/impl/OptionArgument.kt | 11 - .../declarative/arg/impl/OptionSyntax.kt | 11 - .../arg/impl/RelativeCoordinateArgument.kt | 49 ---- .../declarative/arg/impl/SimpleArgument.kt | 30 -- .../declarative/arg/impl/StringArgument.kt | 70 ----- .../commands/declarative/arg/impl/args.kt | 60 ---- .../invocation/SuggestionInvocation.kt | 1 - .../syntax/VariableDeclarationSyntax.kt | 6 +- .../declarative/syntax/VariableType.kt | 4 +- .../mattmx/ktgui/commands/declarative/t.kt | 81 ++++++ .../commands/suggestions/CommandSuggestion.kt | 4 - .../suggestions/SimpleCommandSuggestion.kt | 2 +- .../impl/MaterialCommandSuggestion.kt | 2 +- .../impl/OnlinePlayersCommandSuggestion.kt | 3 +- .../refactor/ConversationWrapper.kt | 4 - .../mattmx/ktgui/conversation/refactor/t.kt | 6 +- .../mattmx/ktgui/cooldown/ActionCoolDown.kt | 5 - .../ktgui/event/ContinuousEventCallback.kt | 4 - .../com/mattmx/ktgui/event/EventCallback.kt | 5 - .../ktgui/guiconfig/GuiConfigManager.kt | 6 - .../com/mattmx/ktgui/papi/Placeholder.kt | 12 - .../ktgui/papi/PlaceholderExpansionWrapper.kt | 54 ---- .../ktgui/papi/PlaceholderParseContext.kt | 13 - .../main/kotlin/com/mattmx/ktgui/papi/dsl.kt | 13 - .../mattmx/ktgui/scheduling/IteratingTask.kt | 15 - .../mattmx/ktgui/scheduling/TaskTracker.kt | 57 +--- .../ktgui/scheduling/TaskTrackerTask.kt | 12 +- .../scheduling/builder/LaterTaskBuilder.kt | 36 --- .../builder/RepeatingTaskBuilder.kt | 53 ---- .../mattmx/ktgui/scheduling/builder/Task.kt | 35 --- .../ktgui/scheduling/builder/TaskBuilder.kt | 34 --- .../com/mattmx/ktgui/scheduling/scheduling.kt | 32 +- .../mattmx/ktgui/sound/ChainSoundBuilder.kt | 170 ----------- .../ktgui/utils/InstancePackageClassCache.kt | 42 --- .../com/mattmx/ktgui/utils/InstanceTest.kt | 20 ++ .../com/mattmx/ktgui/utils/Invokable.kt | 5 +- .../kotlin/com/mattmx/ktgui/utils/misc.kt | 13 - .../kotlin/com/mattmx/ktgui/utils/time.kt | 19 +- build.gradle.kts | 38 +-- gradle.properties | 2 - gradle/wrapper/gradle-wrapper.properties | 4 - .../caches/paperweight/taskCache/reobfJar.log | 2 - plugin/build.gradle.kts | 33 +-- .../mattmx/ktgui/examples/JavaScheduling.java | 22 -- .../examples/JavaUpdateCommandExample.java | 27 +- .../main/kotlin/com/mattmx/ktgui/KotlinGui.kt | 226 +-------------- .../mattmx/ktgui/examples/GuiHookExample.kt | 31 +- plugin/src/main/resources/plugin.yml | 5 - settings.gradle.kts | 26 +- 77 files changed, 444 insertions(+), 1942 deletions(-) delete mode 100644 api/.gradle/caches/paperweight/taskCache/reobfJar.log create mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/ArgumentType.kt create mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/CommandSender.kt create mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/KtCommandBuilder.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeSubCommandBuilder.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ProvidedArgsBlock.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/argTests.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/ArgumentConsumer.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/GreedyArgumentConsumer.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/SingleArgumentConsumer.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/VariableArgumentConsumer.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/DoubleArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/EnumArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/FlagArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/IntArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/LongArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/MultiArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/MultiChoiceArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OnlinePlayerArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionSyntax.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/RelativeCoordinateArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/SimpleArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/StringArgument.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/args.kt create mode 100644 api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/t.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/papi/Placeholder.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderExpansionWrapper.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderParseContext.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/papi/dsl.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/scheduling/IteratingTask.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/LaterTaskBuilder.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/RepeatingTaskBuilder.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/Task.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/TaskBuilder.kt delete mode 100644 api/src/main/kotlin/com/mattmx/ktgui/sound/ChainSoundBuilder.kt create mode 100644 api/src/main/kotlin/com/mattmx/ktgui/utils/InstanceTest.kt delete mode 100644 plugin/.gradle/caches/paperweight/taskCache/reobfJar.log delete mode 100644 plugin/src/main/java/com/mattmx/ktgui/examples/JavaScheduling.java diff --git a/.idea/gradle.xml b/.idea/gradle.xml index c52e764..291d995 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,6 +4,7 @@ -<<<<<<< HEAD -======= - ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb \ No newline at end of file diff --git a/.idea/modules/plugin/ktgui.plugin.test.iml b/.idea/modules/plugin/ktgui.plugin.test.iml index b1f816c..5e1e9ee 100644 --- a/.idea/modules/plugin/ktgui.plugin.test.iml +++ b/.idea/modules/plugin/ktgui.plugin.test.iml @@ -1,19 +1,4 @@ - - - - - PAPER - MCP - ADVENTURE - - 1 - - - - - \ No newline at end of file diff --git a/api/.gradle/caches/paperweight/taskCache/reobfJar.log b/api/.gradle/caches/paperweight/taskCache/reobfJar.log deleted file mode 100644 index 491225f..0000000 --- a/api/.gradle/caches/paperweight/taskCache/reobfJar.log +++ /dev/null @@ -1,2 +0,0 @@ -Command: C:\Users\Mangr\.gradle\jdks\adoptium-21-x64-hotspot-windows\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.0-dev-all.jar D:\PC\Projects\KtBukkitGui\api\build\libs\api-2.4.0.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 2887.82 ms. diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 4c9e92a..c4cfdd6 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -4,26 +4,11 @@ plugins { `maven-publish` } -<<<<<<< HEAD dependencies { compileOnly(libs.paper.api) compileOnly(libs.placeholder.api) implementation(libs.kotlin.reflect) compileOnly(libs.kotlin.stdlib) -======= -val paper_version: String by rootProject - -repositories { - mavenCentral() -} - -dependencies { -// compileOnly(kotlin("reflect")) - shadow(implementation(kotlin("reflect"))!!) -// implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10") - - paperweight.paperDevBundle(paper_version) ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb } tasks.test { @@ -34,13 +19,8 @@ version = rootProject.version sourceSets["main"].resources.srcDir("src/resources/") -<<<<<<< HEAD kotlin { jvmToolchain(JavaVersion.VERSION_17.ordinal) -======= -tasks.withType { - kotlinOptions.jvmTarget = "21" ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb } tasks { @@ -49,18 +29,12 @@ tasks { } shadowJar { mergeServiceFiles() -<<<<<<< HEAD // exclude { //// it.path.startsWith("kotlin") && !it.path.contains("reactive") // it.name.startsWith("kotlin") // } archiveBaseName.set("ktgui") mergeServiceFiles() -======= - } - assemble { - dependsOn(reobfJar) ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb } } diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/ArgumentType.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/ArgumentType.kt new file mode 100644 index 0000000..5627018 --- /dev/null +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/ArgumentType.kt @@ -0,0 +1,7 @@ +package com.mattmx.ktgui.commands.alpha + +enum class ArgumentType { + REQUIRED_SINGLE, + OPTIONAL_SINGLE, + GREEDY +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/CommandSender.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/CommandSender.kt new file mode 100644 index 0000000..e740085 --- /dev/null +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/CommandSender.kt @@ -0,0 +1,3 @@ +package com.mattmx.ktgui.commands.alpha + +class CommandSender \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/KtCommandBuilder.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/KtCommandBuilder.kt new file mode 100644 index 0000000..486ee31 --- /dev/null +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/alpha/KtCommandBuilder.kt @@ -0,0 +1,118 @@ +package com.mattmx.ktgui.commands.alpha + +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty + +open class KtCommandBuilder(val name: String) { + val aliases = arrayOf() + val subcommands = arrayOf>() + var expectedArguments = arrayOf>() + private lateinit var permission: (CommandContext) -> Boolean + private lateinit var runs: (CommandContext) -> Unit + + fun permission(block: CommandContext.() -> Boolean) = apply { permission = block } + fun runs(block: CommandContext.() -> Unit) = apply { runs = block } + open fun register() { + + } + + fun getSuggestions(context: CommandContext): List { + val currentArgument = getCurrentArgument(context) + val suggestions = currentArgument?.suggests?.invoke(context) ?: return emptyList() + val lastArgument = context.args.lastOrNull() ?: "" + return suggestions.filter { suggestion -> suggestion.startsWith(lastArgument, true) }.toList() + } + + /** + * Used to find the current argument, presuming we are on the current sub-command + * + * @param args the current arguments of the command invocation + * @param sender command sender + * @return the current argument or null if it is invalid + */ + private fun getCurrentArgument(context: CommandContext): Argument? { + if (expectedArguments.isEmpty()) return null + // Greedy arguments will eat the rest of the arguments + if (expectedArguments.first().type == ArgumentType.GREEDY) return expectedArguments.first() + + repeat(expectedArguments.size) { argIndex -> + val registered = expectedArguments.getOrNull(argIndex) ?: return null + val comparing = context.args.getOrNull(argIndex) ?: return null + // todo need to think about optional args!!! wtf do we do there + } + + return null + } + + /** + * Used to find the current sub-command + * + * @param args of the current command invocation + * @param sender command sender + * @return the current sub-command or null if it is invalid + */ + private fun getCurrentSubcommand(context: CommandContext): KtCommandBuilder<*>? { + if (subcommands.isEmpty()) return null + val firstArg = context.args.getOrNull(0) + return subcommands.firstOrNull { it.name == firstArg || it.aliases.contains(firstArg) } + } + + private lateinit var context: CommandContext + + operator fun Argument.provideDelegate( + thisRef: Any?, + property: KProperty<*>, + ): ReadOnlyProperty { + id = property.name + + println("invoked eooeeo") + + return ReadOnlyProperty { thisRef, property -> context.getValue(this) as V } + } + + operator fun invoke(context: CommandContext) { + // save values of args + this.context = context + val values = expectedArguments.map { it.id to it.getValue(context) } + runs.invoke(context.withValues(values)) + } + + /** + * Builds a usage for this command. + * You can create your own method with the [Configuration] class. + * + * @return a formatted string for usage of the command + */ + fun getUsage(showDescriptions: Boolean = false, maxArgumentOptionsDisplayed: Int = 5): String { + var builder = "$name " + if (subcommands.isNotEmpty()) + builder += subcommands.joinToString("|") { subcommand -> subcommand.name } + else { + var end = "" + builder += expectedArguments.joinToString(" ") { arg -> + val suggestions = arg.getDefaultSuggestions()?.let { + if (it.size <= maxArgumentOptionsDisplayed) " = [" + it.joinToString("|") + "]" + else " = [...]" + } ?: "" + + // Apply descriptions + if (showDescriptions && arg.description() != null) { + val extra = when (arg.type) { + ArgumentType.REQUIRED_SINGLE -> "(Required)" + ArgumentType.OPTIONAL_SINGLE -> "(Optional)" + else -> "(Sentence)" + } + end += "\n> ${arg.id} - ${arg.description()} $extra" + } + + when (arg.type) { + ArgumentType.REQUIRED_SINGLE -> "<${arg.id}!$suggestions>" + ArgumentType.OPTIONAL_SINGLE -> "<${arg.id}?$suggestions>" + else -> "<${arg.id}...>" + } + } + builder += end + } + return builder + } +} \ No newline at end of file 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 558b87f..b154302 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 @@ -1,15 +1,12 @@ package com.mattmx.ktgui.commands.declarative import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.impl.MultiArgument -import com.mattmx.ktgui.commands.declarative.invocation.RunnableCommandContext import com.mattmx.ktgui.utils.JavaCompatibility -import org.bukkit.block.data.type.Chain import org.bukkit.command.CommandSender class ChainCommandBuilder(val name: String) { val arguments = arrayListOf>() - val subcommands = arrayListOf() + val subcommands = arrayListOf>() @JavaCompatibility fun argument(argument: Argument<*>) = apply { @@ -17,25 +14,18 @@ class ChainCommandBuilder(val name: String) { } @JavaCompatibility - fun subcommand(vararg command: DeclarativeCommandBuilder) = apply { + fun subcommand(vararg command: DeclarativeCommandBuilder<*>) = apply { 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 { + inline fun build() = DeclarativeCommandBuilder(name, T::class.java).apply { this.expectedArguments += arguments this.subcommands += this@ChainCommandBuilder.subcommands } } -inline operator fun ChainCommandBuilder.invoke(block: DeclarativeCommandBuilder.() -> Unit) = - build().apply(block) - -val ChainCommandBuilder.command - get() = build() +inline operator fun ChainCommandBuilder.invoke(block: DeclarativeCommandBuilder.() -> Unit) = + build().apply(block) operator fun String.div(argument: Argument<*>) = ChainCommandBuilder(this).apply { arguments.add(argument) @@ -43,18 +33,14 @@ operator fun String.div(argument: Argument<*>) = ChainCommandBuilder(this).apply @JvmName("div1") operator fun String.div(argument: List>) = ChainCommandBuilder(this).apply { - arguments.add(MultiArgument("multi-argument", *argument.toTypedArray())) -} - -operator fun String.div(s: String) = ChainCommandBuilder(this).apply { - subcommands.add(DeclarativeCommandBuilder(s)) + arguments.addAll(argument) } -operator fun String.div(subs: List) = ChainCommandBuilder(this).apply { +operator fun String.div(subs: List>) = ChainCommandBuilder(this).apply { subcommands.addAll(subs) } -operator fun DeclarativeCommandBuilder.plus(other: DeclarativeCommandBuilder) = listOf(this, other) +operator fun DeclarativeCommandBuilder<*>.plus(other: DeclarativeCommandBuilder<*>) = listOf(this, other) operator fun ChainCommandBuilder.div(argument: Argument<*>) = this.apply { arguments.add(argument) 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 dd8e60b..a210904 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 @@ -3,61 +3,50 @@ package com.mattmx.ktgui.commands.declarative import com.mattmx.ktgui.GuiManager import com.mattmx.ktgui.commands.declarative.arg.Argument import com.mattmx.ktgui.commands.declarative.arg.ArgumentContext -import com.mattmx.ktgui.commands.declarative.arg.consumer.GreedyArgumentConsumer -import com.mattmx.ktgui.commands.declarative.arg.consumer.SingleArgumentConsumer -import com.mattmx.ktgui.commands.declarative.invocation.* +import com.mattmx.ktgui.commands.declarative.invocation.InvalidArgContext +import com.mattmx.ktgui.commands.declarative.invocation.RunnableCommandContext +import com.mattmx.ktgui.commands.declarative.invocation.StorageCommandContext +import com.mattmx.ktgui.commands.declarative.invocation.SuggestionInvocation import com.mattmx.ktgui.commands.declarative.syntax.* import com.mattmx.ktgui.commands.suggestions.CommandSuggestion import com.mattmx.ktgui.commands.usage.CommandUsageOptions -import com.mattmx.ktgui.cooldown.ActionCoolDown import com.mattmx.ktgui.utils.JavaCompatibility import com.mattmx.ktgui.utils.not -import com.mattmx.ktgui.utils.pretty import org.bukkit.Bukkit import org.bukkit.command.CommandSender import org.bukkit.permissions.Permission import org.bukkit.permissions.PermissionDefault -import java.time.Duration import java.util.* import java.util.function.Consumer +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty -open class DeclarativeCommandBuilder( - val name: String +class DeclarativeCommandBuilder( + val name: String, + val senderClass: Class ) { var description = "Command '$name'" var aliases = arrayOf() - var subcommands = setOf() + var subcommands = setOf>() var expectedArguments = arrayOf>() var localArgumentSuggestions = hashMapOf>() - var coolDown = Optional.empty>() - private set - var coolDownCallback = Optional.empty<(StorageCommandContext<*>) -> Unit>() - private set var buildAutomaticPermissions = Optional.empty() private set var permission: Optional<(StorageCommandContext<*>) -> Boolean> = Optional.empty() private set - - // todo give this T -// var runs: Optional<(RunnableCommandContext<*>) -> Unit> = Optional.empty() -// private set - var runs = hashMapOf, (RunnableCommandContext<*>) -> Unit>() - var missing: Optional<(InvalidArgContext<*>) -> Unit> = Optional.empty() + var runs: Optional<(RunnableCommandContext) -> Unit> = Optional.empty() + private set + var missing: Optional<(InvalidArgContext) -> Unit> = Optional.empty() private set - var invalid: Optional<(InvalidArgContext<*>) -> Unit> = Optional.empty() + var invalid: Optional<(InvalidArgContext) -> Unit> = Optional.empty() private set var incorrectExecutor: Optional<(StorageCommandContext<*>) -> Unit> = Optional.empty() private set var invalidPermissions: Optional<(StorageCommandContext<*>) -> Unit> = Optional.empty() private set - var unknownCommand: Optional<(StorageCommandContext<*>) -> Unit> = Optional.empty() + var unknownCommand: Optional<(StorageCommandContext) -> Unit> = Optional.empty() private set - fun cooldown(duration: Duration, block: (StorageCommandContext<*>.() -> Unit)? = null) = apply { - this.coolDown = Optional.of(ActionCoolDown(duration)) - this.coolDownCallback = Optional.ofNullable(block) - } - infix fun permission(block: StorageCommandContext<*>.() -> Boolean) = apply { this.permission = Optional.of(block) } @@ -70,70 +59,43 @@ open class DeclarativeCommandBuilder( this.invalidPermissions = Optional.of(block) } - infix fun unknownCommand(block: StorageCommandContext<*>.() -> Unit) = apply { + infix fun unknownCommand(block: StorageCommandContext.() -> Unit) = apply { this.unknownCommand = Optional.of(block) } - infix fun buildAutomaticPermissions(root: String?) = apply { - this.buildAutomaticPermissions = Optional.ofNullable(root) + infix fun buildAutomaticPermissions(root: String) = apply { + this.buildAutomaticPermissions = Optional.of(root) } infix fun incorrectExecutor(block: (StorageCommandContext<*>.() -> Unit)?) = apply { this.incorrectExecutor = Optional.ofNullable(block) } - infix fun missing(block: InvalidArgContext<*>.() -> Unit) = apply { + infix fun missing(block: InvalidArgContext.() -> Unit) = apply { this.missing = Optional.of(block) } - infix fun invalid(block: InvalidArgContext<*>.() -> Unit) = apply { + infix fun invalid(block: InvalidArgContext.() -> Unit) = apply { this.invalid = Optional.of(block) } - inline infix fun runs(noinline block: RunnableCommandContext.() -> Unit) = apply { - runs(T::class.javaObjectType, block) - } - - fun runs(senderClass: Class, block: RunnableCommandContext.() -> Unit) = apply { - this.runs[senderClass] = block as (RunnableCommandContext<*>) -> Unit - } - - inline fun runs( - vararg argsProvided: Argument<*>, - noinline block: RunnableCommandContext.() -> Unit - ) = apply { - runs(T::class.javaObjectType, *argsProvided, block = block) - } - - fun runs( - senderClass: Class, - vararg argsProvided: Argument<*>, - block: RunnableCommandContext.() -> Unit - ) = apply { - TODO("Not yet implemented, use runs without argsProvided") - this.runs[senderClass] = block as (RunnableCommandContext<*>) -> Unit - } - - @JavaCompatibility - fun runs(senderClass: Class, block: Consumer>) = apply { - runs(senderClass) { - block.accept(this) - } + infix fun runs(block: RunnableCommandContext.() -> Unit) = apply { + this.runs = Optional.of(block) } fun withDefaultUsageSubCommand(options: CommandUsageOptions = CommandUsageOptions()) = apply { val self = this - subcommand("usage") { + subcommand("usage") { aliases += "help" - runs { + runs { reply(!self.getUsage(options)) } } } - infix fun Argument<*>.suggests(suggest: CommandSuggestion<*>) = apply { + infix fun Argument<*>.suggests(suggest: CommandSuggestion) = apply { localArgumentSuggestions[name()] = suggest } @@ -143,46 +105,55 @@ open class DeclarativeCommandBuilder( ?: argument.suggests.orElse(null) } - inline operator fun ChainCommandBuilder.invoke(block: DeclarativeSubCommandBuilder.() -> Unit) = - subcommand(this, block) + @JavaCompatibility + fun runs(block: Consumer>) = apply { + this.runs = Optional.of { + block.accept(it) + } + } - inline operator fun String.invoke(block: DeclarativeSubCommandBuilder.() -> Unit) = - fromString(this).let { - val subCommand = DeclarativeSubCommandBuilder(it.name) - .apply { - expectedArguments += it.expectedArguments - subcommands += it.subcommands - } - .apply(block) - subcommands += subCommand + fun checkSender(sender: S) = + senderClass.isAssignableFrom(sender::class.java) + + inline operator fun String.invoke(block: DeclarativeCommandBuilder.() -> Unit) = + fromString(this).apply(block).let { + subcommands += it + it } - inline fun subcommand( + inline fun subcommand( chain: ChainCommandBuilder, - block: DeclarativeSubCommandBuilder.() -> Unit + block: DeclarativeCommandBuilder.() -> Unit ) = - chain.build(DeclarativeSubCommandBuilder(chain.name)).apply(block).let { + chain.build().apply(block).let { subcommands += it it } - fun subcommand(name: String, block: DeclarativeSubCommandBuilder.() -> Unit) = - subcommand(DeclarativeSubCommandBuilder(name).apply(block)) + inline fun subcommand(name: String, block: DeclarativeCommandBuilder.() -> Unit) = + subcommand(DeclarativeCommandBuilder(name, T::class.javaObjectType).apply(block)) - fun subcommand(cmd: DeclarativeSubCommandBuilder) = + fun subcommand(cmd: DeclarativeCommandBuilder) = cmd.let { subcommands += it it } - fun getCurrentCommand(context: SuggestionInvocation<*>): Pair, DeclarativeCommandBuilder?> { + fun getCurrentCommandAnySender(context: SuggestionInvocation<*>): Pair, DeclarativeCommandBuilder<*>?> { + if (context.sender.isPresent) { + if (!checkSender(context.sender.get())) return context to null + } + return getCurrentCommand(context as SuggestionInvocation) + } + + private fun getCurrentCommand(context: SuggestionInvocation): Pair, DeclarativeCommandBuilder<*>?> { val firstArg = context.rawArgs.firstOrNull() ?: return context to this for (cmd in subcommands) { if (cmd.nameEquals(firstArg)) { - return cmd.getCurrentCommand(context.clone(context.rawArgs.subList(1, context.rawArgs.size))) + return cmd.getCurrentCommandAnySender(context.clone(context.rawArgs.subList(1, context.rawArgs.size))) } } @@ -195,20 +166,8 @@ open class DeclarativeCommandBuilder( .map { listOf(it.name) + it.aliases } val cmdsList = cmds.flatten() - val list = context.rawArgs.toMutableList() - var suggestedArgs: List? = null - for (arg in expectedArguments) { - val consumed = arg.consumer.consume(list) - list.removeAll(consumed) - - if (list.isEmpty()) { - // This is the last argument - suggestedArgs = getSuggestions(arg)?.getLastArgSuggestion(context) - } - } - -// val arg = expectedArguments.getOrNull(context.rawArgs.size - 1) -// val suggestedArgs = getSuggestions(arg)?.getLastArgSuggestion(context) + val arg = expectedArguments.getOrNull(context.rawArgs.size - 1) + val suggestedArgs = getSuggestions(arg)?.getLastArgSuggestion(context) return if (suggestedArgs != null) { cmdsList + suggestedArgs @@ -219,7 +178,7 @@ open class DeclarativeCommandBuilder( fun nameStarts(arg: String) = name.startsWith(arg, true) || aliases.any { it.startsWith(arg, true) } - infix fun register(localObject: Any) = apply { + infix fun register(localObject: Any) { val permissionNodePrefix = buildAutomaticPermissions.orElse(null) if (permissionNodePrefix != null) { registerPermissionWithPrefixRecursively(permissionNodePrefix) @@ -229,7 +188,7 @@ open class DeclarativeCommandBuilder( GuiManager.registerCommand(localObject::class.javaObjectType, wrapper) } - fun registerPermissionWithPrefixRecursively(prefix: String) { + private fun registerPermissionWithPrefixRecursively(prefix: String) { val finalPrefix = "$prefix.$name" for (sub in subcommands) { sub.registerPermissionWithPrefixRecursively(finalPrefix) @@ -249,7 +208,21 @@ open class DeclarativeCommandBuilder( } } - fun invoke(context: StorageCommandContext<*>) { + fun invokeAnySender(context: StorageCommandContext<*>) { + val result = runCatching { + // todo we should find the command before invoking it + invoke(context as StorageCommandContext) + } + if (result.isFailure) { + if (incorrectExecutor.isPresent) { + incorrectExecutor.get().invoke(context) + } else { + context.reply(!"&cThis command can only be ran by ${senderClass.simpleName}s.") + } + } + } + + fun invoke(context: StorageCommandContext) { if (permission.isPresent && !permission.get().invoke(context)) { if (invalidPermissions.isPresent) { @@ -261,42 +234,26 @@ open class DeclarativeCommandBuilder( return } - if (coolDown.isPresent && !coolDown.get().test(context.sender)) { - coolDownCallback.ifPresentOrElse({ it.invoke(context) }) { - context.reply( - !"&cPlease wait ${ - coolDown.get().durationRemaining(context.sender).pretty() - } before running the command again." - ) - } - return - } - val argumentValues = hashMapOf>() - var expectedArgumentIndex = 0 - var providedArgumentIndex = 0 - while (providedArgumentIndex < context.rawArgs.size) { - val arg = context.rawArgs[providedArgumentIndex] + for ((index, arg) in context.rawArgs.withIndex()) { // Check sub-commands // todo could match multiple subcommands val cmd = subcommands.firstOrNull { it.nameEquals(arg) } if (cmd != null) { - return cmd.invoke( + return cmd.invokeAnySender( context.clone(context.rawArgs.subList(1, context.rawArgs.size)) ) } // Check arguments - val expectedArg = expectedArguments.getOrNull(expectedArgumentIndex) + val expectedArg = expectedArguments.getOrNull(index) if (expectedArg != null) { - // Get full argument string using consumer - val consumed = - expectedArg.consumer.consume(context.rawArgs.subList(providedArgumentIndex, context.rawArgs.size)) - providedArgumentIndex += consumed.size + val value = if (expectedArg.type().isVararg) { + context.rawArgs.subList(index, context.rawArgs.size).joinToString(" ") + } else context.rawArgs.getOrNull(index) - // If the value is empty and IS required - if (expectedArg.isRequired() && consumed.isEmpty()) { + if (expectedArg.isRequired() && value == null) { val missingArgContext = InvalidArgContext(context.sender, context.alias, context.rawArgs, expectedArg, null) @@ -316,16 +273,15 @@ open class DeclarativeCommandBuilder( return } else { - var isValid = expectedArg.validate(consumed) + val actualValue = if (localArgumentSuggestions.contains(expectedArg.name())) { + localArgumentSuggestions[expectedArg.name()]?.getValue(value.toString()) + } else if (expectedArg.suggests.isPresent) { + expectedArg.suggests.get().getValue(value.toString()) + } else value - val stringValue = consumed.joinToString(" ") - val actualValue = expectedArg.getValueOfString(this, context, consumed) - - isValid = isValid && (expectedArg.isOptional() || actualValue != null) - - if (!isValid) { + if (actualValue == null) { val invalidArgumentContext = - InvalidArgContext(context.sender, context.alias, context.rawArgs, expectedArg, stringValue) + InvalidArgContext(context.sender, context.alias, context.rawArgs, expectedArg, value) if (expectedArg.invokeInvalid(invalidArgumentContext)) { return @@ -335,9 +291,15 @@ open class DeclarativeCommandBuilder( return } - argumentValues[expectedArg.name()] = expectedArg.createContext(stringValue, actualValue) + argumentValues[expectedArg.name()] = expectedArg.createContext(value, actualValue) - expectedArgumentIndex++ + // todo args types should have a method to "eat up" arguments at will + // e.g when calling arg.createContext we should return what arguments have been used in this argument + // hence, the index in the list should be adjusted to match. This way varargs can be limited lengths. + + if (expectedArg.type().isVararg) { + break + } } } else { if (unknownCommand.isPresent) { @@ -370,14 +332,7 @@ open class DeclarativeCommandBuilder( val runnableContext = RunnableCommandContext(context.sender, context.alias, context.rawArgs, argumentValues) - - val executor = - runs.entries.firstOrNull { (clazz, _) -> - clazz.isAssignableFrom(context.sender.javaClass) - } - ?: return context.reply(!"&cThis command can only be ran by ${runs.values.joinToString("/") { "${it.javaClass.simpleName}s" }}.") - - executor.value.invoke(runnableContext) + runs.ifPresent { it.invoke(runnableContext) } } /** @@ -405,8 +360,8 @@ open class DeclarativeCommandBuilder( if (!suggestions.isNullOrEmpty()) { val opt = options.arguments "${opt.suggestionsChar}${opt.suggestionsPrefix}${suggestions.joinToString(opt.suggestionsDivider)}${opt.suggestionsSuffix}" - } else "${options.arguments.typeChar}${arg.type()}${if (arg.consumer.isVarArg()) "..." else ""}" - } else "${options.arguments.typeChar}${arg.type()}${if (arg.consumer.isVarArg()) "..." else ""}" + } else "${options.arguments.typeChar}${arg.type().typeName}${if (arg.type().isVararg) "..." else ""}" + } else "${options.arguments.typeChar}${arg.type().typeName}${if (arg.type().isVararg) "..." else ""}" // Apply descriptions if (options.arguments.showDescriptions) { @@ -423,8 +378,12 @@ open class DeclarativeCommandBuilder( companion object { + inline fun fromString(source: String): DeclarativeCommandBuilder = + fromString(T::class.javaObjectType, source) + @JvmStatic - fun fromString(source: String): DeclarativeCommandBuilder { + @JavaCompatibility + fun fromString(targetSender: Class, source: String): DeclarativeCommandBuilder { var name: String? = null val expectedArguments = arrayListOf>() val parsed = Parser(source).parse() @@ -435,8 +394,9 @@ open class DeclarativeCommandBuilder( expectedArguments += Argument( syntax.getName(), syntax.getType(), - if (syntax.isGreedy()) GreedyArgumentConsumer() else SingleArgumentConsumer() - ).apply { optional(syntax.isOptional()) } + null, + !syntax.getType().isOptional + ) } is CommandDeclarationSyntax -> { @@ -451,7 +411,7 @@ open class DeclarativeCommandBuilder( } if (name == null) error("Name cannot be null for a command!") - return DeclarativeCommandBuilder(name) + return DeclarativeCommandBuilder(name, targetSender) .apply { this.expectedArguments += expectedArguments } @@ -459,11 +419,21 @@ open class DeclarativeCommandBuilder( } } -inline operator fun String.invoke(block: DeclarativeCommandBuilder.() -> Unit) = - DeclarativeCommandBuilder(this).apply(block) +inline operator fun String.invoke(block: DeclarativeCommandBuilder.() -> Unit) = + DeclarativeCommandBuilder.fromString(this).apply(block) + +inline fun command(name: String, block: DeclarativeCommandBuilder.() -> Unit) = + DeclarativeCommandBuilder(name, T::class.java).apply(block) + +fun argument(type: String, isVarArg: Boolean = false): ReadOnlyProperty> { + val arg = argument(type, "delegated_arg", isVarArg) -inline fun command(name: String, block: DeclarativeCommandBuilder.() -> Unit) = - DeclarativeCommandBuilder(name).apply(block) + return ReadOnlyProperty { ref: Nothing?, property: KProperty<*> -> + arg.apply { + name(property.name) + } + } +} -@JavaCompatibility -fun command(name: String) = DeclarativeCommandBuilder(name) \ No newline at end of file +fun argument(type: String, name: String, isVarArg: Boolean) = + Argument(name, VariableType(type, isVarArg, false)) \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeCommandWrapper.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeCommandWrapper.kt index b7c59af..58343e4 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeCommandWrapper.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeCommandWrapper.kt @@ -6,22 +6,22 @@ import com.mattmx.ktgui.commands.wrapper.CommandWrapper import org.bukkit.command.CommandSender import java.util.* -class DeclarativeCommandWrapper( +class DeclarativeCommandWrapper( name: String, - val builder: DeclarativeCommandBuilder + val builder: DeclarativeCommandBuilder ) : CommandWrapper(name) { override fun execute(sender: CommandSender, commandLabel: String, args: Array): Boolean { val context = StorageCommandContext(sender, commandLabel, args.toList()) - builder.invoke(context) + builder.invokeAnySender(context) return true } override fun tabComplete(sender: CommandSender, alias: String, args: Array): MutableList { - val context = SuggestionInvocation(Optional.of(sender), alias, args.toList().subList(0, args.size - 1)) + val context = SuggestionInvocation(Optional.of(sender), alias, args.toList()) - val (newContext, finalCommand) = builder.getCurrentCommand(context) + val (newContext, finalCommand) = builder.getCurrentCommandAnySender(context) val outArgs = finalCommand?.getSuggestions(newContext) return outArgs?.toMutableList() ?: mutableListOf() diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeSubCommandBuilder.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeSubCommandBuilder.kt deleted file mode 100644 index c8eeb08..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/DeclarativeSubCommandBuilder.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.mattmx.ktgui.commands.declarative - -class DeclarativeSubCommandBuilder(name: String) : DeclarativeCommandBuilder(name) \ No newline at end of file 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 254068b..b7feb0a 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 @@ -1,34 +1,23 @@ package com.mattmx.ktgui.commands.declarative.arg -<<<<<<< HEAD -======= -import com.mattmx.ktgui.commands.declarative.DeclarativeCommandBuilder -import com.mattmx.ktgui.commands.declarative.arg.consumer.ArgumentConsumer -import com.mattmx.ktgui.commands.declarative.invocation.BaseCommandContext ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb import com.mattmx.ktgui.commands.declarative.invocation.InvalidArgContext -import com.mattmx.ktgui.commands.declarative.invocation.RunnableCommandContext import com.mattmx.ktgui.commands.declarative.invocation.SuggestionInvocation +import com.mattmx.ktgui.commands.declarative.syntax.VariableType import com.mattmx.ktgui.commands.suggestions.CommandSuggestion import com.mattmx.ktgui.commands.suggestions.CommandSuggestionRegistry import com.mattmx.ktgui.event.EventCallback import com.mattmx.ktgui.utils.Invokable -import com.mattmx.ktgui.utils.JavaCompatibility import java.util.* -open class Argument( +class Argument( private var name: String, - private val typeName: String, - val consumer: ArgumentConsumer + private val type: VariableType, + var description: String? = null, + private val required: Boolean = true ) : Invokable> { - var description: String? = null var suggests = Optional.empty>() - var missingCallback = EventCallback>() - protected set - var invalidCallback = EventCallback>() - protected set - private var optional = false - // todo impl default value + val missingCallback = EventCallback>() + val invalidCallback = EventCallback>() init { withTypeSuggestions() @@ -42,27 +31,9 @@ open class Argument( fun description() = description ?: "" - fun type() = typeName + fun type() = type - fun isRequired() = !optional - - fun isOptional() = optional - - fun required() = apply { - this.optional = false - } - - infix fun required(value: Boolean) = apply { - this.optional = !value - } - - fun optional() = apply { - this.optional = true - } - - infix fun optional(value: Boolean) = apply { - this.optional = value - } + fun isRequired() = required infix fun missing(block: InvalidArgContext<*>.() -> Unit) = apply { this.missingCallback.callbacks.add(block) @@ -83,42 +54,19 @@ open class Argument( } fun withTypeSuggestions() = apply { - suggests = CommandSuggestionRegistry.get(typeName) as Optional> + suggests = CommandSuggestionRegistry.get(type.typeName) as Optional> } - // todo this should be called with [validate] for efficiency, as well as the consumer - open fun getValueOfString(cmd: DeclarativeCommandBuilder, context: BaseCommandContext<*>, split: List): T? { - return getValueOfString(cmd, context, split.joinToString(" ")) - } - - open fun getValueOfString(cmd: DeclarativeCommandBuilder, context: BaseCommandContext<*>, stringValue: String?): T? { - return if (cmd.localArgumentSuggestions.contains(name())) { - cmd.localArgumentSuggestions[name()]?.getValue(stringValue) as T? - } else if (suggests.isPresent) { - suggests.get().getValue(stringValue) - } else null - } - - @JavaCompatibility - fun getContext(context: RunnableCommandContext<*>) = context.getArgumentContext(name()); - - @JavaCompatibility - fun getValue(context: RunnableCommandContext<*>) = context.getArgumentContext(name())?.getOrNull() - fun createContext(stringValue: String?, actualValue: Any?): ArgumentContext { return ArgumentContext(stringValue, Optional.ofNullable(actualValue as T?), this) } - open fun validate(split: List) = validate(split.joinToString(" ")) - - open fun validate(stringValue: String?) = true - fun getDefaultSuggestions(): List? { val context = SuggestionInvocation(Optional.empty(), "", emptyList()) return if (suggests.isPresent) { suggests.get().getSuggestion(context) } else { - val suggestion = CommandSuggestionRegistry.get(typeName) + val suggestion = CommandSuggestionRegistry.get(type.typeName) if (suggestion.isPresent) suggestion.get().getSuggestion(context) else null } } @@ -126,20 +74,7 @@ open class Argument( infix fun nameEquals(other: Argument<*>) = name() == other.name() override fun toString() = - "<$name${if (isOptional()) "?" else ""}:${typeName}${if (consumer.isVarArg()) "..." else ""}>" - - open fun applyToClone(cloned: Argument) = cloned - - fun clone() : Argument { - return Argument(name, typeName, consumer) - .let { - it.invalidCallback = invalidCallback.clone() - it.missingCallback = missingCallback.clone() - it.suggests = suggests - it.description = description - applyToClone(it) - } - } + "<$name${if (type.isOptional) "?" else ""}:${type.typeName}${if (type.isVararg) "..." else ""}>" } infix fun Argument.suggests(suggest: CommandSuggestion) = apply { diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ArgumentContext.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ArgumentContext.kt index 7aa468c..133f150 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ArgumentContext.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ArgumentContext.kt @@ -11,15 +11,13 @@ class ArgumentContext( fun isEmpty() = value.isEmpty - fun isPresent() = value.isPresent - fun getOrNull(): T? = value.orElse(null) fun orElse(other: T?) = value.orElse(other) fun stringValue() = stringValue - fun asOptional() = value + fun optional() = value override fun toString() = getOrNull().toString() } \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ProvidedArgsBlock.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ProvidedArgsBlock.kt deleted file mode 100644 index a968b28..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/ProvidedArgsBlock.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg - -import com.mattmx.ktgui.commands.declarative.invocation.RunnableCommandContext -import org.bukkit.command.CommandSender - -class ProvidedArgsBlock( - val context: RunnableCommandContext<*> -) { - var hasAlreadyRan = false - - infix fun or(block: () -> Unit) = apply { - if (hasAlreadyRan) return@apply - - invoke(block) - } - - fun withArgs(vararg args: Argument<*>, block: () -> Unit) = apply { - if (hasAlreadyRan) return@apply - - if (args.all { context.getArgumentContext(it.name())?.isPresent() == true }) { - invoke(block) - } - } - - private fun invoke(block: () -> Unit) { - hasAlreadyRan = true - block() - } -} - -fun RunnableCommandContext.withArgs(vararg args: Argument<*>, block: () -> Unit) = - ProvidedArgsBlock(this).apply { - withArgs(*args, block = block) - } \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/argTests.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/argTests.kt deleted file mode 100644 index 60219d0..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/argTests.kt +++ /dev/null @@ -1,88 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg - -import com.google.gson.JsonParser -import com.mattmx.ktgui.commands.declarative.arg.impl.* -import kotlin.math.min - -class ArgumentProcessor( - val args: List -) { - var pointer = 0 - // Should be added to the command context - val values = hashMapOf() - - // Should be in the [DeclarativeCommandBuilder] class - val permittedFlags = arrayListOf() - val options = OptionSyntax() - - fun peek(i: Int) = args.getOrNull(pointer + i) - fun current() = peek(0) - fun next(): String? { - // Check if it is a flag - pointer++ - while (current().let { it != null && options.match(it) }) { - val optionOrPointerId = options.removePrefixFrom(current()!!) - - // TODO check if expected id is expected and if it is a flag or option - if (permittedFlags.any { it.chatName() == optionOrPointerId }) { - values[optionOrPointerId] = true.toString() - } else { - // TODO this should read the argument type args (does that make sense?) - // e.g '--test "hello world"' -> hello world - val value = peek(1) ?: continue - values[optionOrPointerId] = value - pointer++ - } - - pointer++ - } - - return current() - } - - fun takeOne(argId: String) { - values[argId] = next() ?: return - } - - fun takeWhile(argId: String, block: String.() -> Boolean) { - var current = next() - val list = arrayListOf() - - if (current != null) { - list.add(current) - } - - while (current != null && block(current)) { - current = next() - if (current != null) { - list.add(current) - } - } - values[argId] = list.joinToString(" ") - } - - fun takeRemaining(argId: String) { - takeWhile(argId) { pointer < args.size } - } -} - -fun main() { - val ping by flag() - val option by optionArgument() - val t by optionArgument() - - val args = "msg MattMX foo bar --t 5 --ping --option 'hello world'".split(" ") - val processor = ArgumentProcessor(args) - - processor.permittedFlags.add(ping) - - // We should abstract this using the `ArgumentConsumer` interface - processor.takeOne("username") - processor.takeRemaining("msg") - -// username consumes single() -// msg consumes until { false } -// msg consumes remaining() - - println(processor) -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/ArgumentConsumer.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/ArgumentConsumer.kt deleted file mode 100644 index ff942da..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/ArgumentConsumer.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.consumer - -fun interface ArgumentConsumer { - - fun consume(args: List) : List - - fun isVarArg() = false - -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/GreedyArgumentConsumer.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/GreedyArgumentConsumer.kt deleted file mode 100644 index c4afdf0..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/GreedyArgumentConsumer.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.consumer - -class GreedyArgumentConsumer : ArgumentConsumer { - override fun consume(args: List): List { - return args - } -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/SingleArgumentConsumer.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/SingleArgumentConsumer.kt deleted file mode 100644 index 36d8d75..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/SingleArgumentConsumer.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.consumer - -class SingleArgumentConsumer : ArgumentConsumer { - override fun consume(args: List): List { - return args.firstOrNull()?.let { listOf(it) } ?: emptyList() - } -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/VariableArgumentConsumer.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/VariableArgumentConsumer.kt deleted file mode 100644 index b39a8f9..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/consumer/VariableArgumentConsumer.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.consumer - -class VariableArgumentConsumer( - val to: Int -) : ArgumentConsumer { - override fun consume(args: List): List { - return args.subList(0, to) - } -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/DoubleArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/DoubleArgument.kt deleted file mode 100644 index 2550b69..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/DoubleArgument.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.DeclarativeCommandBuilder -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.SingleArgumentConsumer -import com.mattmx.ktgui.commands.declarative.invocation.BaseCommandContext - -class DoubleArgument( - name: String, - typeName: String -) : Argument(name, typeName, SingleArgumentConsumer()) { - var min: Double = Double.MIN_VALUE - var max: Double = Double.MAX_VALUE - - override fun validate(stringValue: String?): Boolean { - stringValue ?: return isOptional() - - val doubleValue = stringValue.toDoubleOrNull() ?: return false - - return doubleValue in (min..max) - } - - override fun getValueOfString( - cmd: DeclarativeCommandBuilder, - context: BaseCommandContext<*>, - stringValue: String? - ): Double? { - return stringValue?.toDoubleOrNull() - } - - infix fun range(range: ClosedRange) = apply { - this.min = range.start - this.max = range.endInclusive - } - - infix fun min(min: Double) = apply { - this.min = min - } - - infix fun max(max: Double) = apply { - this.max = max - } - -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/EnumArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/EnumArgument.kt deleted file mode 100644 index f32a765..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/EnumArgument.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.DeclarativeCommandBuilder -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.SingleArgumentConsumer -import com.mattmx.ktgui.commands.declarative.invocation.BaseCommandContext -import java.util.* - -class EnumArgument>( - val enumClass: Class, - name: String, - typeName: String -) : Argument(name, typeName, SingleArgumentConsumer()) { - var stringMethod: Optional<(E) -> String> = Optional.empty() - private set - - infix fun stringMethod(method: E.() -> String) = apply { - this.stringMethod = Optional.of(method) - } - - override fun getValueOfString( - cmd: DeclarativeCommandBuilder, - context: BaseCommandContext<*>, - stringValue: String? - ): E? { - return if (stringMethod.isEmpty) { - enumClass.enumConstants.firstOrNull { stringMethod.get()(it).equals(stringValue, true) } - } else { - enumClass.enumConstants.firstOrNull { it.name.equals(stringValue, true) } - } - } -} \ No newline at end of file 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 deleted file mode 100644 index e1e75a6..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/FlagArgument.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.DeclarativeCommandBuilder -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.SingleArgumentConsumer -import com.mattmx.ktgui.commands.declarative.invocation.BaseCommandContext - -class FlagArgument( - name: String -) : Argument(name, "boolean", SingleArgumentConsumer()) { - - fun chatName() = name().replace("_", "-") - - override fun getValueOfString( - cmd: DeclarativeCommandBuilder, - context: BaseCommandContext<*>, - split: List - ): Boolean? { - // todo context should contain included flags/options - return false - } - -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/IntArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/IntArgument.kt deleted file mode 100644 index d68d1b5..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/IntArgument.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.DeclarativeCommandBuilder -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.SingleArgumentConsumer -import com.mattmx.ktgui.commands.declarative.invocation.BaseCommandContext - -class IntArgument( - name: String, - typeName: String -) : Argument(name, typeName, SingleArgumentConsumer()) { - var min: Int = Int.MIN_VALUE - var max: Int = Int.MAX_VALUE - - override fun validate(stringValue: String?): Boolean { - stringValue ?: return isOptional() - - val intValue = stringValue.toIntOrNull() ?: return false - - return intValue in (min..max) - } - - override fun getValueOfString( - cmd: DeclarativeCommandBuilder, - context: BaseCommandContext<*>, - stringValue: String? - ): Int? { - return stringValue?.toIntOrNull() - } - - infix fun range(range: IntRange) = apply { - this.min = range.first - this.max = range.last - } - - infix fun min(min: Int) = apply { - this.min = min - } - - infix fun max(max: Int) = apply { - this.max = max - } - -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/LongArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/LongArgument.kt deleted file mode 100644 index 5466ba4..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/LongArgument.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.DeclarativeCommandBuilder -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.SingleArgumentConsumer -import com.mattmx.ktgui.commands.declarative.invocation.BaseCommandContext - -class LongArgument( - name: String, - typeName: String -) : Argument(name, typeName, SingleArgumentConsumer()) { - var min: Long = Long.MIN_VALUE - var max: Long = Long.MAX_VALUE - - override fun validate(stringValue: String?): Boolean { - stringValue ?: return isOptional() - - val intValue = stringValue.toIntOrNull() ?: return false - - return intValue in (min..max) - } - - override fun getValueOfString( - cmd: DeclarativeCommandBuilder, - context: BaseCommandContext<*>, - stringValue: String? - ): Long? { - return stringValue?.toLongOrNull() - } - - infix fun range(range: LongRange) = apply { - this.min = range.first - this.max = range.last - } - - infix fun min(min: Long) = apply { - this.min = min - } - - infix fun max(max: Long) = apply { - this.max = max - } - -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/MultiArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/MultiArgument.kt deleted file mode 100644 index bf35e51..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/MultiArgument.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.ArgumentConsumer - -class MultiArgument( - name: String, - vararg val args: Argument<*> -) : Argument>(name, "any", MultiArgConsumer(*args)) { - class MultiArgConsumer(vararg val args: Argument<*>) : ArgumentConsumer { - override fun consume(args: List): List { - val all = this.args.map { it.consumer.consume(args).size } - - val largest = all.maxOf { it } - - return args.subList(0, largest) - } - - } -} \ No newline at end of file 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 deleted file mode 100644 index 686eda5..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/MultiChoiceArgument.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.ArgumentConsumer - -class MultiChoiceArgument( - name: String, - typeName: String, - consumer: ArgumentConsumer -) : Argument(name, typeName, consumer) { - - - -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OnlinePlayerArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OnlinePlayerArgument.kt deleted file mode 100644 index e2825ec..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OnlinePlayerArgument.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.SingleArgumentConsumer -import org.bukkit.entity.Player - -class OnlinePlayerArgument( - name: String, - typeName: String = "player" -) : Argument(name, typeName, SingleArgumentConsumer()) \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionArgument.kt deleted file mode 100644 index d360b79..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionArgument.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.ArgumentConsumer - -class OptionArgument( - name: String, - typeName: String, - consumer: ArgumentConsumer -) : Argument(name, typeName, consumer) { -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionSyntax.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionSyntax.kt deleted file mode 100644 index e760899..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/OptionSyntax.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -data class OptionSyntax( - val prefix: String = "--" -) { - fun regex() = "$prefix.+".toRegex() - - fun match(str: String) = str.matches(regex()) - - fun removePrefixFrom(str: String) = str.replaceFirst(prefix, "") -} \ No newline at end of file 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 deleted file mode 100644 index a8004f6..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/RelativeCoordinateArgument.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.DeclarativeCommandBuilder -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.VariableArgumentConsumer -import com.mattmx.ktgui.commands.declarative.invocation.BaseCommandContext -import org.bukkit.Location -import org.bukkit.entity.Entity -import org.bukkit.util.Vector - -class RelativeCoordinateArgument( - name: String, - typeName: String -) : Argument(name, typeName, VariableArgumentConsumer(3)) { - - init { - - } - - override fun getValueOfString( - cmd: DeclarativeCommandBuilder, - context: BaseCommandContext<*>, - split: List - ): Location? { - if (split.size != 3) return null - - val entity = (context.sender as Entity) - val location = entity.location.clone().toVector().list() - - var i = 0 - val coords = split.map { s -> - val doubleValue = s.replace("~", "").toDoubleOrNull() - ?: return null - val finalValue = if (s.startsWith("~")) { - doubleValue + location[i] - } else { - doubleValue - } - i++ - - finalValue - } - - return Location(entity.location.world, coords[0], coords[1], coords[2]) - } - - private fun Vector.list() = listOf(x, y, z) - -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/SimpleArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/SimpleArgument.kt deleted file mode 100644 index 670ab68..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/SimpleArgument.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.DeclarativeCommandBuilder -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.ArgumentConsumer -import com.mattmx.ktgui.commands.declarative.invocation.BaseCommandContext -import java.util.* - -class SimpleArgument( - name: String, - typeName: String, - consumer: ArgumentConsumer -) : Argument(name, typeName, consumer) { - var valueFromString = Optional.empty<(String) -> T?>() - private set - - infix fun getValue(supplier: String.() -> T?) = apply { - this.valueFromString = Optional.of(supplier) - } - - override fun getValueOfString( - cmd: DeclarativeCommandBuilder, - context: BaseCommandContext<*>, - stringValue: String? - ): T? { - stringValue ?: return null - return if (valueFromString.isPresent) valueFromString.get()(stringValue) else null - } - -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/StringArgument.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/StringArgument.kt deleted file mode 100644 index 9e36c04..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/StringArgument.kt +++ /dev/null @@ -1,70 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.DeclarativeCommandBuilder -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.ArgumentConsumer -import com.mattmx.ktgui.commands.declarative.invocation.BaseCommandContext - -class StringArgument( - name: String, - type: String, - consumer: ArgumentConsumer -) : Argument(name, type, consumer) { - var min: Int = 0 - var max: Int = Int.MAX_VALUE - lateinit var regex: Regex - val allowed = arrayListOf() - val disallow = arrayListOf() - - override fun validate(stringValue: String?): Boolean { - stringValue ?: return false - - val range = (min..max) - - val matchesRange = stringValue.length in range - val matchesAllowed = allowed.any { it.matches(stringValue) } - val meetsDisallowed = disallow.none { it.matches(stringValue) } - - return matchesRange && matchesAllowed && meetsDisallowed - } - - override fun getValueOfString( - cmd: DeclarativeCommandBuilder, - context: BaseCommandContext<*>, - stringValue: String? - ): String? { - return stringValue - } - - infix fun allow(regex: List) = apply { - this.allowed += regex - } - - infix fun disallow(regex: List) = apply { - this.disallow += regex - } - - infix fun allow(regex: Regex) = apply { - this.allowed += regex - } - - infix fun disallow(regex: Regex) = apply { - this.disallow += regex - } - - infix fun matches(regex: Regex) = allow(regex) - - infix fun range(range: IntRange) = apply { - this.min = range.first - this.max = range.last - } - - infix fun min(min: Int) = apply { - this.min = min - } - - infix fun max(max: Int) = apply { - this.max = max - } - -} \ No newline at end of file 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 deleted file mode 100644 index f23a708..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/arg/impl/args.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.mattmx.ktgui.commands.declarative.arg.impl - -import com.mattmx.ktgui.commands.declarative.arg.Argument -import com.mattmx.ktgui.commands.declarative.arg.consumer.GreedyArgumentConsumer -import com.mattmx.ktgui.commands.declarative.arg.consumer.SingleArgumentConsumer -import net.kyori.adventure.bossbar.BossBar.Flag -import kotlin.properties.ReadOnlyProperty -import kotlin.reflect.KProperty - -const val DELEGATED_ARG_NAME = "delegated_arg" - -fun argument(type: String, isVarArg: Boolean = false) = - delegateArgument(argument(type, DELEGATED_ARG_NAME, isVarArg)) - -fun > delegateArgument(arg: T) = ReadOnlyProperty { ref: Nothing?, property: KProperty<*> -> - arg.apply { - name(property.name) - } -} - -fun argument(type: String, name: String, isVarArg: Boolean) = - Argument(name, type, if (isVarArg) GreedyArgumentConsumer() else SingleArgumentConsumer()) - -fun stringArgument(type: String = "string", isVarArg: Boolean = false) = - delegateArgument( - StringArgument( - DELEGATED_ARG_NAME, - type, - if (isVarArg) GreedyArgumentConsumer() else SingleArgumentConsumer() - ) - ) - -fun greedyStringArgument(type: String = "string") = - stringArgument(type, true) - -fun intArgument(type: String = "int") = - delegateArgument(IntArgument(DELEGATED_ARG_NAME, type)) - -fun longArgument(type: String = "long") = - delegateArgument(LongArgument(DELEGATED_ARG_NAME, type)) - -fun doubleArgument(type: String = "double") = - delegateArgument(DoubleArgument(DELEGATED_ARG_NAME, type)) - -fun relativeCoords(type: String = "coords") = - delegateArgument(RelativeCoordinateArgument(DELEGATED_ARG_NAME, type)) - -fun playerArgument() = - delegateArgument(OnlinePlayerArgument(DELEGATED_ARG_NAME)) - -fun simpleArgument(type: String = "") = - delegateArgument(SimpleArgument(DELEGATED_ARG_NAME, type, SingleArgumentConsumer())) - -inline fun > enumArgument(type: String = E::class.java.simpleName) = - delegateArgument(EnumArgument(E::class.javaObjectType, DELEGATED_ARG_NAME, type)) - -fun flag() = delegateArgument(FlagArgument(DELEGATED_ARG_NAME)) - -inline fun optionArgument(type: String = T::class.java.simpleName) = - delegateArgument(OptionArgument(DELEGATED_ARG_NAME, type, SingleArgumentConsumer())) \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/invocation/SuggestionInvocation.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/invocation/SuggestionInvocation.kt index dd3495d..96e0d57 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/invocation/SuggestionInvocation.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/invocation/SuggestionInvocation.kt @@ -8,7 +8,6 @@ class SuggestionInvocation( val alias: String, val rawArgs: List ) { - lateinit var consumed: List val last: String get() = rawArgs.lastOrNull() ?: "" diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/syntax/VariableDeclarationSyntax.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/syntax/VariableDeclarationSyntax.kt index c8c0705..19661b2 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/syntax/VariableDeclarationSyntax.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/syntax/VariableDeclarationSyntax.kt @@ -13,11 +13,7 @@ class VariableDeclarationSyntax( fun getName() = varNameToken.text!! - fun getType() = typeToken.text!! - - fun isGreedy() = ellipsisToken.text != null - - fun isOptional() = optional.text != null + fun getType() = VariableType(typeToken.text!!, ellipsisToken.text != null, optional.text != null) override fun children() = listOf(openDiamondBracesToken, varNameToken, colonToken, typeToken, closeDiamondBracesToken) diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/syntax/VariableType.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/syntax/VariableType.kt index 43cbaec..45d531e 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/syntax/VariableType.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/syntax/VariableType.kt @@ -1,5 +1,7 @@ package com.mattmx.ktgui.commands.declarative.syntax data class VariableType( - val typeName: String + val typeName: String, + val isVararg: Boolean, + val isOptional: Boolean ) \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/t.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/t.kt new file mode 100644 index 0000000..1c40bd1 --- /dev/null +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/declarative/t.kt @@ -0,0 +1,81 @@ +package com.mattmx.ktgui.commands.declarative + +import com.mattmx.ktgui.commands.usage.CommandUsageOptions +import org.bukkit.command.CommandSender + +fun main() { + val player by argument("fakePlayer") + val msg by argument("string", true) + + val msgcmd = ("msg" / player / msg) { + runs { + println("[${player().name}]: ${msg()}") + } + } invalid { + println("Invalid argument '${argument.name()}'.") + } + + val splitArgs = { s: String -> s.split(" ") } + +// msgcmd.invoke(RawCommandContext(splitArgs("MattMX hello world"))) +// msgcmd.invoke(RawCommandContext(splitArgs("1etho foo bar"))) + // Empty command invocation +// msgcmd.invoke(RawCommandContext(listOf("GabbySimon"))) +// msgcmd.invoke(RawCommandContext(listOf())) + + val myCommandUsage = CommandUsageOptions { + arguments { + showDescriptions = true + showSuggestions = true + descriptionsPrefix = "[] " + } + } + +// println(msgcmd.getUsage(myCommandUsage)) + val someArg by argument("fakePlayer") + val foo = command("foo") { + + subcommand("bar") { + runs { + println("bar") + } + } + + subcommand("fizz" / someArg) { + runs { + println("fizzzzz ${someArg().name}") + } + + invalid { + someArg { + println("$provided couldn't be found!") + } + } + } + + runs { + println("foo!") + } + } + + val foo1 = + ("foo" / + listOf( + ("fizz" / someArg) { + runs { + println("fizzzzz ${someArg().name}") + } + }, + ("bar") { + runs { + println("bar") + } + }) + ) { + runs { + println("foo!") + } + } + + println(foo.getUsage(myCommandUsage)) +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/CommandSuggestion.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/CommandSuggestion.kt index c88ff44..700a0a5 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/CommandSuggestion.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/CommandSuggestion.kt @@ -8,11 +8,7 @@ fun interface CommandSuggestion { fun getLastArgSuggestion(invocation: SuggestionInvocation<*>) = getSuggestion(invocation) ?.filter { it.startsWith((invocation.rawArgs.lastOrNull() ?: ""), true) } -<<<<<<< HEAD fun getValue(argumentString: String): V? { -======= - fun getValue(argumentString: String?) : V? { ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb return argumentString as V? } diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/SimpleCommandSuggestion.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/SimpleCommandSuggestion.kt index cf06412..215d0e0 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/SimpleCommandSuggestion.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/SimpleCommandSuggestion.kt @@ -15,7 +15,7 @@ open class SimpleCommandSuggestion( return list.map { obj -> field.getter.javaMethod?.invoke(obj).toString() } } - override fun getValue(argumentString: String?): V? { + override fun getValue(argumentString: String): V? { val list = list() return list.firstOrNull { obj -> field.getter.javaMethod?.invoke(obj) == argumentString } diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/impl/MaterialCommandSuggestion.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/impl/MaterialCommandSuggestion.kt index 272ebaf..6c6c581 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/impl/MaterialCommandSuggestion.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/impl/MaterialCommandSuggestion.kt @@ -9,7 +9,7 @@ class MaterialCommandSuggestion : CommandSuggestion { return Material.values().map { it.key.toString() } } - override fun getValue(argumentString: String?): Material? { + override fun getValue(argumentString: String): Material? { return Material.values().firstOrNull { it.key.toString() == argumentString } } } \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/impl/OnlinePlayersCommandSuggestion.kt b/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/impl/OnlinePlayersCommandSuggestion.kt index 2855dae..5f52275 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/impl/OnlinePlayersCommandSuggestion.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/commands/suggestions/impl/OnlinePlayersCommandSuggestion.kt @@ -13,8 +13,7 @@ class OnlinePlayersCommandSuggestion : CommandSuggestion { .toList() } - override fun getValue(argumentString: String?): Player? { - argumentString ?: return null + override fun getValue(argumentString: String): Player? { return Bukkit.getPlayer(argumentString) } } \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/conversation/refactor/ConversationWrapper.kt b/api/src/main/kotlin/com/mattmx/ktgui/conversation/refactor/ConversationWrapper.kt index 69a0547..a6fb01f 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/conversation/refactor/ConversationWrapper.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/conversation/refactor/ConversationWrapper.kt @@ -36,10 +36,6 @@ class ConversationWrapper( factory.withEscapeSequence(value) } - infix fun exitOn(name: String) = apply { - this.exitOn = name - } - infix fun exit(block: ConversationAbandonedEvent.() -> Unit) = apply { this.exit = Optional.of(block) factory.addConversationAbandonedListener { diff --git a/api/src/main/kotlin/com/mattmx/ktgui/conversation/refactor/t.kt b/api/src/main/kotlin/com/mattmx/ktgui/conversation/refactor/t.kt index b844a09..3fb88ce 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/conversation/refactor/t.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/conversation/refactor/t.kt @@ -6,13 +6,9 @@ import org.bukkit.Bukkit import org.bukkit.entity.Player fun main() { -<<<<<<< HEAD conversation { exitOn = "cancel" -======= - conversation { ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb exit { println("exit") } @@ -68,5 +64,5 @@ fun main() { println(result.get() * 2) } } - } timeout 30 exitOn "cancel" + } timeout 30 } \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/cooldown/ActionCoolDown.kt b/api/src/main/kotlin/com/mattmx/ktgui/cooldown/ActionCoolDown.kt index 48bcc84..ed35735 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/cooldown/ActionCoolDown.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/cooldown/ActionCoolDown.kt @@ -37,10 +37,6 @@ class ActionCoolDown( return max(-1L, expire - (System.currentTimeMillis() - cache.getOrDefault(user, 0))) } - fun durationRemaining(user: T) : Duration { - return Duration.ofMillis(timeRemaining(user)) - } - fun test(user: T, block: (Duration) -> Unit): Unit? { val timeLeft = timeRemaining(user) val valid = timeLeft < 0 @@ -50,7 +46,6 @@ class ActionCoolDown( if (valid) { block(Duration.ofMillis(timeLeft)) - return Unit } return null } diff --git a/api/src/main/kotlin/com/mattmx/ktgui/event/ContinuousEventCallback.kt b/api/src/main/kotlin/com/mattmx/ktgui/event/ContinuousEventCallback.kt index 2a2464a..2dc0741 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/event/ContinuousEventCallback.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/event/ContinuousEventCallback.kt @@ -2,10 +2,6 @@ package com.mattmx.ktgui.event import org.bukkit.event.Cancellable -/** - * Event Callback that will exit if the [Cancellable] is - * marked as cancelled. - */ class ContinuousEventCallback : EventCallback() { override operator fun invoke(value: T): Boolean { diff --git a/api/src/main/kotlin/com/mattmx/ktgui/event/EventCallback.kt b/api/src/main/kotlin/com/mattmx/ktgui/event/EventCallback.kt index 24fb895..e48b87b 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/event/EventCallback.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/event/EventCallback.kt @@ -1,8 +1,5 @@ package com.mattmx.ktgui.event -/** - * Stores a list of callbacks for [T], will invoke all of them. - */ open class EventCallback( val callbacks: ArrayList Unit> = arrayListOf() ) { @@ -20,8 +17,6 @@ open class EventCallback( fun isEmpty() = callbacks.isEmpty() - fun first() = callbacks.first() - open fun clone() = EventCallback(arrayListOf(*callbacks.map { it }.toTypedArray())) } \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/guiconfig/GuiConfigManager.kt b/api/src/main/kotlin/com/mattmx/ktgui/guiconfig/GuiConfigManager.kt index e9c3edb..1bcec5a 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/guiconfig/GuiConfigManager.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/guiconfig/GuiConfigManager.kt @@ -1,15 +1,9 @@ package com.mattmx.ktgui.guiconfig import com.mattmx.ktgui.utils.InstancePackageClassCache -import com.mattmx.ktgui.components.button.GuiButton import org.bukkit.configuration.file.FileConfiguration import org.bukkit.plugin.java.JavaPlugin -/** - * Helper class to cache instances of config files belonging to plugins. - * - * We can use this for [configGui] function to easily read [GuiButton] from config files. - */ class GuiConfigManager { val cache = InstancePackageClassCache() diff --git a/api/src/main/kotlin/com/mattmx/ktgui/papi/Placeholder.kt b/api/src/main/kotlin/com/mattmx/ktgui/papi/Placeholder.kt deleted file mode 100644 index 97d7d5a..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/papi/Placeholder.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.mattmx.ktgui.papi - -import com.mattmx.ktgui.commands.declarative.ChainCommandBuilder - -class Placeholder( - val match: ChainCommandBuilder, - val supplier: (PlaceholderParseContext) -> Any? -) { - var priority = 0 - - fun parse(context: PlaceholderParseContext) = supplier.invoke(context) -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderExpansionWrapper.kt b/api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderExpansionWrapper.kt deleted file mode 100644 index e0551e1..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderExpansionWrapper.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.mattmx.ktgui.papi - -import me.clip.placeholderapi.expansion.PlaceholderExpansion -import org.bukkit.entity.Player -import org.bukkit.plugin.java.JavaPlugin - -class PlaceholderExpansionWrapper( - private val owner: JavaPlugin -) : PlaceholderExpansion() { - private val placeholders = arrayListOf() - var id = owner.name - private set - var _author = owner.pluginMeta.authors.joinToString(", ") - private set - var _version = owner.pluginMeta.version - private set - var splitArgs = { params: String -> params.split("_") } - private set - - override fun getIdentifier() = id - override fun getAuthor() = _author - override fun getVersion() = _version - override fun getPlaceholders() = placeholders.map { it.toString() }.toMutableList() - - infix fun id(id: String) = apply { - this.id = id - } - - infix fun author(author: String) = apply { - this._author = author - } - - infix fun version(version: String) = apply { - this._version = version - } - - infix fun splitArgs(splitArgs: (String) -> List) = apply { - this.splitArgs = splitArgs - } - - infix fun registerPlaceholder(placeholder: Placeholder) = placeholders.add(placeholder) - - override fun onPlaceholderRequest(player: Player?, params: String): String? { - val context = PlaceholderParseContext(player, splitArgs(params)) - for (placeholder in placeholders.sortedByDescending { it.priority }) { - val content = placeholder.parse(context) - - if (content != null) { - return content.toString() - } - } - return null - } -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderParseContext.kt b/api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderParseContext.kt deleted file mode 100644 index f00a4f9..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/papi/PlaceholderParseContext.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.mattmx.ktgui.papi - -import com.mattmx.ktgui.commands.declarative.arg.Argument -import org.bukkit.entity.Player - -class PlaceholderParseContext( - val requestedBy: Player?, - val params: List -) { - - operator fun Argument.invoke(): T = TODO() - -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/papi/dsl.kt b/api/src/main/kotlin/com/mattmx/ktgui/papi/dsl.kt deleted file mode 100644 index db63fad..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/papi/dsl.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.mattmx.ktgui.papi - -import com.mattmx.ktgui.commands.declarative.ChainCommandBuilder -import org.bukkit.plugin.java.JavaPlugin - -inline fun JavaPlugin.placeholderExpansion(builder: PlaceholderExpansionWrapper.() -> Unit) = - PlaceholderExpansionWrapper(this).apply(builder).apply { register() } - -fun placeholder(string: String, supplier: PlaceholderParseContext.() -> Any?) = - Placeholder(ChainCommandBuilder(string), supplier) - -fun placeholder(chain: ChainCommandBuilder, supplier: PlaceholderParseContext.() -> Any?) = - Placeholder(chain, supplier) \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/IteratingTask.kt b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/IteratingTask.kt deleted file mode 100644 index f0ade0f..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/IteratingTask.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.mattmx.ktgui.scheduling - -import org.bukkit.scheduler.BukkitTask - -open class IteratingTask( - val task: BukkitTask -) { - /** - * How many times the task has repeated. - * Do not increment yourself. - */ - var iterations = 0 - - open fun cancel() = task.cancel() -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/TaskTracker.kt b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/TaskTracker.kt index 2c8d20f..87aa3fa 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/TaskTracker.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/TaskTracker.kt @@ -1,47 +1,41 @@ package com.mattmx.ktgui.scheduling -import com.mattmx.ktgui.utils.Invokable import org.bukkit.scheduler.BukkitTask import java.util.* -/** - * Utility class used as a "Task pool". - * - * Any scheduled tasks will be added to [list]. - */ -class TaskTracker : Invokable { - private val list = Collections.synchronizedList(arrayListOf()) +class TaskTracker { + private val list = Collections.synchronizedList(arrayListOf()) - infix fun runAsync(block: TaskTrackerTask.() -> Unit) { + fun runAsync(block: TaskTrackerTask.() -> Unit) { var task: TaskTrackerTask? = null task = TaskTrackerTask(this, async { block(task!!) - list.remove(task!!) - }).apply { list.add(this) } + list.remove(this) + }.apply { list.add(this) }) } - infix fun runSync(block: TaskTrackerTask.() -> Unit) { + fun runSync(block: TaskTrackerTask.() -> Unit) { var task: TaskTrackerTask? = null task = TaskTrackerTask(this, sync { block(task!!) - list.remove(task!!) - }).apply { list.add(this) } + list.remove(this) + }.apply { list.add(this) }) } fun runAsyncLater(period: Long, block: TaskTrackerTask.() -> Unit) { var task: TaskTrackerTask? = null task = TaskTrackerTask(this, asyncDelayed(period) { block(task!!) - list.remove(task!!) - }).apply { list.add(this) } + list.remove(this) + }.apply { list.add(this) }) } fun runSyncLater(period: Long, block: TaskTrackerTask.() -> Unit) { var task: TaskTrackerTask? = null task = TaskTrackerTask(this, syncDelayed(period) { block(task!!) - list.remove(task!!) - }).apply { list.add(this) } + list.remove(this) + }.apply { list.add(this) }) } fun runAsyncRepeat(delay: Long, period: Long = 0L, block: TaskTrackerTask.() -> Unit) { @@ -49,7 +43,7 @@ class TaskTracker : Invokable { task = TaskTrackerTask(this, asyncRepeat(delay, period) { block(task!!) task!!.iterations++ - }).apply { list.add(this) } + }.apply { list.add(this) }) } fun runSyncRepeat(delay: Long, period: Long = 0L, block: TaskTrackerTask.() -> Unit) { @@ -57,34 +51,15 @@ class TaskTracker : Invokable { task = TaskTrackerTask(this, syncRepeat(delay, period) { block(task!!) task!!.iterations++ - }).apply { list.add(this) } + }.apply { list.add(this) }) } fun cancelAll() = list.apply { - val temp = this.toList() - temp.forEach { it.cancel() } + forEach { it.cancel() } list.clear() } - infix fun cancelIf(predicate: (IteratingTask) -> Boolean): List { - val removed = arrayListOf() - val it = list.iterator() - while (it.hasNext()) { - val t = it.next() - if (predicate(t)) { - it.remove() - removed.add(t) - } - } - return removed.toList() - } - - inline fun cancelIfInstance() = - cancelIf { it is T } as List - - infix fun removeTask(task: BukkitTask) = cancelIf { it.task == task } - - infix fun removeTask(task: TaskTrackerTask) { + fun removeTask(task: BukkitTask) { list.remove(task) } diff --git a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/TaskTrackerTask.kt b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/TaskTrackerTask.kt index 0681d82..4c55a23 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/TaskTrackerTask.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/TaskTrackerTask.kt @@ -2,15 +2,13 @@ package com.mattmx.ktgui.scheduling import org.bukkit.scheduler.BukkitTask -/** - * Wrapper class for the [BukkitTask] task. - */ -open class TaskTrackerTask( +class TaskTrackerTask( private val owner: TaskTracker, - task: BukkitTask -) : IteratingTask(task) { + private val task: BukkitTask +) { + var iterations = 0 - override fun cancel() { + fun cancel() { owner.removeTask(task) task.cancel() } diff --git a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/LaterTaskBuilder.kt b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/LaterTaskBuilder.kt deleted file mode 100644 index 8f58977..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/LaterTaskBuilder.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.mattmx.ktgui.scheduling.builder - -import com.mattmx.ktgui.scheduling.* -import org.bukkit.scheduler.BukkitTask - -class LaterTaskBuilder( - val isAsync: Boolean -) { - var delay = 0L - private set - lateinit var block: (IteratingTask) -> Unit - private set - - infix fun delay(ticks: Long) = apply { - this.delay = ticks - } - - - infix fun runs(block: IteratingTask.() -> Unit) = apply { - this.block = block - } - - fun run(): IteratingTask { - var task: IteratingTask? = null - - val block: BukkitTask.() -> Unit = task@{ - block.invoke(task!!) - task!!.iterations++ - } - - task = IteratingTask(if (isAsync) asyncDelayed(delay, block) else syncDelayed(delay, block)) - - return task - } - -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/RepeatingTaskBuilder.kt b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/RepeatingTaskBuilder.kt deleted file mode 100644 index 0d15f5f..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/RepeatingTaskBuilder.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.mattmx.ktgui.scheduling.builder - -import com.mattmx.ktgui.scheduling.IteratingTask -import com.mattmx.ktgui.scheduling.asyncRepeat -import com.mattmx.ktgui.scheduling.syncRepeat -import org.bukkit.scheduler.BukkitTask - -class RepeatingTaskBuilder( - val isAsync: Boolean -) { - var max = -1L - private set - var delay = 0L - private set - var period = 0L - private set - lateinit var block: (IteratingTask) -> Unit - private set - - infix fun repeat(times: Long) = apply { - this.max = times - } - - infix fun delay(ticks: Long) = apply { - this.delay = ticks - } - - infix fun period(ticks: Long) = apply { - this.period = ticks - } - - infix fun runs(block: IteratingTask.() -> Unit) = apply { - this.block = block - } - - fun run(): IteratingTask { - var task: IteratingTask? = null - - val block: BukkitTask.() -> Unit = task@{ - if (task!!.iterations > max) { - cancel() - return@task - } - - block.invoke(task!!) - task!!.iterations++ - } - - task = IteratingTask(if (isAsync) asyncRepeat(period, delay, block) else syncRepeat(period, delay, block)) - - return task - } -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/Task.kt b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/Task.kt deleted file mode 100644 index afbe1ea..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/Task.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.mattmx.ktgui.scheduling.builder - -import com.mattmx.ktgui.utils.seconds - -object Task { - - @JvmStatic - fun async() = AsyncTaskBuilder() - - @JvmStatic - fun sync() = SyncTaskBuilder() -} - -fun main() { - val repeating = Task - .async() - .repeating() - .repeat(20) - .delay(2.seconds) - .period(1) - .runs { - println("Task repeating $iterations") - }.run() - - val later = Task - .sync() - .later() - .delay(1) - .runs { - println(iterations) - }.run() - - val dsl = Task.async() repeating { - } period 2 delay 2 repeat 20 -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/TaskBuilder.kt b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/TaskBuilder.kt deleted file mode 100644 index af62871..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/builder/TaskBuilder.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.mattmx.ktgui.scheduling.builder - -import com.mattmx.ktgui.scheduling.IteratingTask -import java.util.function.Consumer - -interface TaskBuilder { - - fun repeating() = RepeatingTaskBuilder(isAsync()) - - infix fun repeating(block: IteratingTask.() -> Unit) = - repeating().apply { runs(block) } - - infix fun repeating(block: Consumer) = - repeating().apply { runs { block(this) } } - - fun later() = LaterTaskBuilder(isAsync()) - - infix fun later(block: IteratingTask.() -> Unit) = - later().apply { runs(block) } - - infix fun later(block: Consumer) = - later().apply { runs { block(this) } } - - fun isAsync() : Boolean - -} - -class AsyncTaskBuilder : TaskBuilder { - override fun isAsync() = true -} - -class SyncTaskBuilder : TaskBuilder { - override fun isAsync() = false -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/scheduling.kt b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/scheduling.kt index 4e192d1..03a730c 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/scheduling/scheduling.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/scheduling/scheduling.kt @@ -7,8 +7,6 @@ import java.util.concurrent.CompletableFuture import java.util.concurrent.Future import java.util.concurrent.TimeUnit import kotlin.reflect.KFunction -import kotlin.reflect.KFunction1 -import kotlin.reflect.KFunction2 import kotlin.reflect.jvm.isAccessible /** @@ -23,30 +21,11 @@ object Scheduling { lateinit var plugin: JavaPlugin } -val KFunction.getAsync: CompletableFuture - get() = future { - async { - isAccessible = true - val result = runCatching(::call) - if (result.isSuccess) complete(result.getOrThrow()) else completeExceptionally(result.exceptionOrNull()) - } - } - -infix fun KFunction1.getAsync(arg: T) = future { - async { - isAccessible = true - val result = runCatching { call(arg) } - if (result.isSuccess) complete(result.getOrThrow()) else completeExceptionally(result.exceptionOrNull()) - } -} - -fun KFunction2.getAsync(arg: T, arg1: U) = future { - async { +val KFunction.asyncTask: BukkitTask + get() = async { isAccessible = true - val result = runCatching { call(arg, arg1) } - if (result.isSuccess) complete(result.getOrThrow()) else completeExceptionally(result.exceptionOrNull()) + call() } -} val KFunction.syncTask: BukkitTask get() = sync { @@ -172,7 +151,6 @@ fun asyncDelayed(delay: Long, task: BukkitTask.() -> Unit): BukkitTask { * @author MattMX * @param block that returns our value */ -<<<<<<< HEAD fun future(block: () -> T): CompletableFuture { val future = CompletableFuture() async { @@ -181,10 +159,6 @@ fun future(block: () -> T): CompletableFuture { } return future } -======= -fun future(block: CompletableFuture.() -> Unit): CompletableFuture = - CompletableFuture().apply(block) ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb /** * Similar to [future], will return a [Future] with the type you want. diff --git a/api/src/main/kotlin/com/mattmx/ktgui/sound/ChainSoundBuilder.kt b/api/src/main/kotlin/com/mattmx/ktgui/sound/ChainSoundBuilder.kt deleted file mode 100644 index b098c25..0000000 --- a/api/src/main/kotlin/com/mattmx/ktgui/sound/ChainSoundBuilder.kt +++ /dev/null @@ -1,170 +0,0 @@ -package com.mattmx.ktgui.sound - -import com.mattmx.ktgui.scheduling.TaskTracker -import com.mattmx.ktgui.scheduling.getAsync -import com.mattmx.ktgui.scheduling.future -import com.mattmx.ktgui.utils.ticks -import net.kyori.adventure.audience.Audience -import net.kyori.adventure.key.Key -import net.kyori.adventure.sound.Sound.* -import org.bukkit.Location -import org.bukkit.Sound -import org.bukkit.entity.Player -import java.util.* -import java.util.function.Supplier - -class ChainSoundBuilder { - private var defaultEmitter = EmitterType.SELF - private var location = Optional.empty>() - private var steps = arrayListOf() - - infix fun relative(value: Boolean) = apply { - defaultEmitter = if (value) EmitterType.SELF else EmitterType.LOCATION - } - - infix fun location(location: Location) = location { location } - - infix fun location(location: Supplier) = apply { - relative(false) - this.location = Optional.of(location) - } - - fun play(sound: Sound) = play(sound.key()) - - fun play(sound: Key) = - SoundBuilder(sound.key()).apply { steps.add(Step(Step.Type.SOUND, this)) } - - fun thenPlay(sound: Sound) = thenPlay(sound.key()) - - fun thenPlay(sound: Key) = thenPlay(SoundBuilder(sound)) - - fun thenPlay(sound: SoundBuilder) = apply { - steps.add(Step(Step.Type.SOUND, sound)) - } - - @JvmName("waitTicks") - fun wait(ticks: Long) { - this.steps.add(Step(Step.Type.WAIT, ticks)) - } - - fun thenWait(ticks: Long) = apply { - wait(ticks) - } - - fun playFor(audience: Audience) = TaskTracker() - .apply { - runAsync { - val it = steps.iterator() - - while (it.hasNext()) { - val step = it.next() - - when (step.type) { - Step.Type.SOUND -> { - val wrapper = step.sound() - val sound = wrapper.build() - if (wrapper.emitter == EmitterType.LOCATION && wrapper.location.isPresent) { - val location = wrapper.location.get().get() - audience.playSound(sound, location.x, location.z, location.z) - } else { - audience.playSound(sound(wrapper.sound, wrapper.source, wrapper.volume, wrapper.pitch), Emitter.self()) - } - } - else -> { - val delay = step.delay() - - // todo this will lead to thread starvation - instead build to a chain of tasks - future { - runAsyncLater(delay) { - complete(Unit) - } - }.get() - } - } - } - } - } - - enum class EmitterType { - LOCATION, - SELF - } - - class Step( - val type: Type, - val value: Any - ) { - fun delay() = value as Long - fun sound() = value as SoundBuilder - - enum class Type { - SOUND, - WAIT - } - } - - class SoundBuilder( - val sound: Key - ) { - var emitter = EmitterType.SELF - private set - var location = Optional.empty>() - private set - var volume: Float = 1f - private set - var pitch: Float = 1f - private set - var source: Source = Source.MASTER - private set - - infix fun volume(vol: Float) = apply { - volume = vol - } - - infix fun pitch(pit: Float) = apply { - pitch = pit - } - - infix fun source(src: Source) = apply { - this.source = src - } - - infix fun relative(value: Boolean) = apply { - emitter = if (value) EmitterType.SELF else EmitterType.LOCATION - } - - infix fun location(location: Location) = location { location } - - infix fun location(location: Supplier) = apply { - relative(false) - this.location = Optional.of(location) - } - - fun build() = net.kyori.adventure.sound.Sound.sound(sound, source, volume, pitch) - } -} - -fun soundBuilder(block: ChainSoundBuilder.() -> Unit) = - ChainSoundBuilder().apply(block) - -fun sound(sound: Sound) = sound(sound.key()) - -fun sound(key: Key) = ChainSoundBuilder.SoundBuilder(key) - -fun Audience.playSound(sound: ChainSoundBuilder) = sound.playFor(this) - -fun main(player: Player) { - ::soundBuilder.getAsync { - location { player.location.clone().add(0.0, 100.0, 0.0) } - - play(Sound.ENTITY_ENDER_DRAGON_DEATH) volume 1f pitch 2f relative true - wait(1.ticks) - play(Sound.BLOCK_NOTE_BLOCK_BANJO) volume 2f pitch 0f relative true - }.thenAccept { player.playSound(it) } - - val builder = ChainSoundBuilder() - .relative(true) - .thenPlay(Sound.ENTITY_ENDER_DRAGON_DEATH) - .thenWait(100) - .thenPlay(sound(Sound.BLOCK_NOTE_BLOCK_BANJO) volume 0.4f) -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/utils/InstancePackageClassCache.kt b/api/src/main/kotlin/com/mattmx/ktgui/utils/InstancePackageClassCache.kt index 36665b0..6c298b7 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/utils/InstancePackageClassCache.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/utils/InstancePackageClassCache.kt @@ -2,23 +2,9 @@ package com.mattmx.ktgui.utils import kotlin.math.min -/** - * Stores a single object per unique package. - * - * e.g If we supplied [StopWatch] to the [cacheInstance] function - * (with anything as the instance arg) then it would get the package - * to a sublist of 3 (com.mattmx.ktgui) and then cache the instance - * object. - */ class InstancePackageClassCache { private val packageList = hashMapOf() - /** - * Stores the package name to a sublist of 3 with [instance]. - * - * @param clazz any Class belonging to the package. - * @param instance the object to store. - */ fun cacheInstance(clazz: Class, instance: V) { val split = clazz.packageName.split(".") val three = split.subList(0, min(3, split.size)) @@ -27,43 +13,15 @@ class InstancePackageClassCache { packageList[packagePath] = instance } -<<<<<<< HEAD fun clearInstance(clazz: Class): V { return packageList.remove(getShortPackageName(clazz)) as V -======= - /** - * Removes package name cache of [clazz] previously stored - * by calling [cacheInstance]. - * - * @param clazz any Class belonging to a package. - * @return the cached instance if any. - */ - fun clearInstance(clazz: Class) : V? { - return packageList.remove(getShortPackageName(clazz)) as V? ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb } - /** - * Returns instance stored by package of [clazz] - * - * @param clazz any Class belonging to a package. - * @return the cached instance. - */ fun getInstance(clazz: Class): V { return packageList[getShortPackageName(clazz)]!! as V } -<<<<<<< HEAD fun getInstanceOrNull(clazz: Class): V? { -======= - /** - * Returns instance stored by package of [clazz] or null. - * - * @param clazz any Class belonging to a package. - * @return the cached instance or null. - */ - fun getInstanceOrNull(clazz: Class) : V? { ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb return packageList[getShortPackageName(clazz)] as V? } diff --git a/api/src/main/kotlin/com/mattmx/ktgui/utils/InstanceTest.kt b/api/src/main/kotlin/com/mattmx/ktgui/utils/InstanceTest.kt new file mode 100644 index 0000000..3cedcac --- /dev/null +++ b/api/src/main/kotlin/com/mattmx/ktgui/utils/InstanceTest.kt @@ -0,0 +1,20 @@ +package com.mattmx.ktgui.utils + +val cache = InstancePackageClassCache() + +inline fun T.test() { + cache.getInstance(T::class.java).hello() +} + +fun main() { + val plugin = MockPluginClass() + cache.cacheInstance(MockPluginClass::class.java, plugin) + + StopWatch().test() +} + +class MockPluginClass { + fun hello() { + println("hello world") + } +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/utils/Invokable.kt b/api/src/main/kotlin/com/mattmx/ktgui/utils/Invokable.kt index 46319cc..72452e2 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/utils/Invokable.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/utils/Invokable.kt @@ -1,8 +1,5 @@ package com.mattmx.ktgui.utils -/** - * Utility interface that allows for us to invoke the self object. - */ interface Invokable { - infix operator fun invoke(block: T.() -> Unit) = block.invoke(this as T) + operator fun invoke(block: T.() -> Unit) = block.invoke(this as T) } \ No newline at end of file diff --git a/api/src/main/kotlin/com/mattmx/ktgui/utils/misc.kt b/api/src/main/kotlin/com/mattmx/ktgui/utils/misc.kt index abe2aad..44ca5a6 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/utils/misc.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/utils/misc.kt @@ -3,19 +3,6 @@ package com.mattmx.ktgui.utils import org.bukkit.entity.Player import java.util.* -/** - * Utility function to get the highest permission level of a specified node. - * - * e.g a player has: - * - ktgui.permission.1 - * - ktgui.permission.4 - * - ktgui.permission.-1 - * - * If we call this function with [node] as "ktgui.permission" then it would return 4. - * - * @param node the prefix of the permission node. - * @return [Optional] with highest level or empty. - */ fun Player.highestPermissionLevel(node: String): Optional { val finalNode = if (node.endsWith(".")) node else "$node." var highest = Optional.empty() diff --git a/api/src/main/kotlin/com/mattmx/ktgui/utils/time.kt b/api/src/main/kotlin/com/mattmx/ktgui/utils/time.kt index 203e29a..2154e11 100644 --- a/api/src/main/kotlin/com/mattmx/ktgui/utils/time.kt +++ b/api/src/main/kotlin/com/mattmx/ktgui/utils/time.kt @@ -1,31 +1,16 @@ package com.mattmx.ktgui.utils -/** - * Amount of ticks in ticks (lol) - */ val Int.ticks get() = this.toLong() -/** - * Amount of ticks in seconds - */ val Int.seconds - get() = this * 20L + get() = ticks * 20L -/** - * Amount of ticks in seconds - */ val Double.seconds get() = (this * 20).toLong() -/** - * Amount of ticks in minutes - */ val Int.minutes get() = seconds * 60L -/** - * Amount of ticks in minutes - */ val Double.minutes - get() = (this * 60).toLong() \ No newline at end of file + get() = (this * 20 * 60).toLong() \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index c24a23b..ccec172 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,46 +1,10 @@ plugins { -<<<<<<< HEAD alias(libs.plugins.updateDeps) apply true alias(libs.plugins.kotlinJvm) apply false alias(libs.plugins.shadow) apply false alias(libs.plugins.grgit) apply false -======= - kotlin("jvm") version "1.7.10" - id("io.papermc.paperweight.userdev") version "1.7.1" apply false ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb } val version = "2.4.0" -<<<<<<< HEAD -rootProject.version = version -======= -rootProject.version = version - -subprojects { - apply(plugin = "java") - apply(plugin = "org.jetbrains.kotlin.jvm") - apply(plugin = "io.papermc.paperweight.userdev") - - repositories { - mavenCentral() - maven("https://jitpack.io") - maven("https://repo.papermc.io/repository/maven-public/") - maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") - } - dependencies { -// compileOnly("org.jetbrains.kotlin:kotlin-stdlib:1.7.10") - compileOnly("me.clip:placeholderapi:2.11.1") - } - - java { - withJavadocJar() - withSourcesJar() - } - - tasks.assemble { - dependsOn("reobfJar") - } - -} ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb +rootProject.version = version \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index a3df16f..7fc6f1f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1 @@ kotlin.code.style=official - -paper_version = 1.20.4-R0.1-SNAPSHOT \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a28464d..0d18421 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,9 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -<<<<<<< HEAD distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip -======= -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/plugin/.gradle/caches/paperweight/taskCache/reobfJar.log b/plugin/.gradle/caches/paperweight/taskCache/reobfJar.log deleted file mode 100644 index db2f312..0000000 --- a/plugin/.gradle/caches/paperweight/taskCache/reobfJar.log +++ /dev/null @@ -1,2 +0,0 @@ -Command: C:\Users\Mangr\.gradle\jdks\adoptium-21-x64-hotspot-windows\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.0-dev-all.jar D:\PC\Projects\KtBukkitGui\plugin\build\libs\plugin-unspecified.jar C:\Users\Mangr\.gradle\caches\paperweight-userdev\383bcea64446e2cc830258ba4061f82beae144700277ae2c736ef37b9c989d6c\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\383bcea64446e2cc830258ba4061f82beae144700277ae2c736ef37b9c989d6c\module\io.papermc.paper\dev-bundle\1.20.4-R0.1-SNAPSHOT\paperweight\setupCache\applyMojangMappedPaperclipPatch.jar --threads=1 -Finished after 1731.16 ms. diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 49e74ce..6b27de4 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -3,33 +3,15 @@ plugins { alias(libs.plugins.shadow) apply true alias(libs.plugins.grgit) apply true `maven-publish` -<<<<<<< HEAD -======= - id("org.ajoberstar.grgit") version "4.1.0" -} - -val paper_version: String by rootProject - -repositories { - mavenCentral() - maven("https://maven.pvphub.me/releases") - maven("https://repo.dmulloy2.net/repository/public/") ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb } dependencies { - shadow(implementation(project(":api", "reobf"))!!) + shadow(implementation(project(":api"))!!) shadow(implementation("co.pvphub:ProtocolLibDsl:-SNAPSHOT")!!) -<<<<<<< HEAD compileOnly(libs.protocolLib) compileOnly(libs.kotlin.stdlib) compileOnly(libs.paper.api) compileOnly(libs.placeholder.api) -======= - compileOnly("com.comphenix.protocol:ProtocolLib:4.7.0") - - paperweight.paperDevBundle(paper_version) ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb } tasks.test { @@ -38,17 +20,12 @@ tasks.test { sourceSets["main"].resources.srcDir("src/resources/") -<<<<<<< HEAD kotlin { jvmToolchain(JavaVersion.VERSION_17.ordinal) } java { toolchain.languageVersion.set(JavaLanguageVersion.of(17)) -======= -tasks.withType { - kotlinOptions.jvmTarget = "21" ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb } fun getCheckedOutGitCommitHash(): String = grgit.head().abbreviatedId @@ -71,15 +48,7 @@ tasks { archiveBaseName.set("ktgui-plugin") archiveClassifier.set("") archiveVersion.set(rootProject.version.toString()) -<<<<<<< HEAD exclude { it.name.startsWith("kotlin") } -======= - - minimize { - exclude("kotlin/**") - } - ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb mergeServiceFiles() } } \ No newline at end of file diff --git a/plugin/src/main/java/com/mattmx/ktgui/examples/JavaScheduling.java b/plugin/src/main/java/com/mattmx/ktgui/examples/JavaScheduling.java deleted file mode 100644 index 48cbdfb..0000000 --- a/plugin/src/main/java/com/mattmx/ktgui/examples/JavaScheduling.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.mattmx.ktgui.examples; - -import com.mattmx.ktgui.scheduling.builder.Task; - -public class JavaScheduling { - public void test() { - var repeating = Task.async() - .repeating((task) -> { - System.out.println("Ran this task " + task.getIterations() + " times."); - }).delay(2) - .period(2) - .repeat(20) - .run(); - - var later = Task.sync() - .later((task) -> { - System.out.println("1s later"); - }) - .delay(20) - .run(); - } -} diff --git a/plugin/src/main/java/com/mattmx/ktgui/examples/JavaUpdateCommandExample.java b/plugin/src/main/java/com/mattmx/ktgui/examples/JavaUpdateCommandExample.java index b6f78c2..87032c0 100644 --- a/plugin/src/main/java/com/mattmx/ktgui/examples/JavaUpdateCommandExample.java +++ b/plugin/src/main/java/com/mattmx/ktgui/examples/JavaUpdateCommandExample.java @@ -1,19 +1,11 @@ package com.mattmx.ktgui.examples; import com.mattmx.ktgui.commands.SimpleCommandBuilder; -import com.mattmx.ktgui.commands.declarative.ChainCommandBuilder; import com.mattmx.ktgui.commands.declarative.DeclarativeCommandBuilder; -import com.mattmx.ktgui.commands.declarative.arg.Argument; import com.mattmx.ktgui.commands.declarative.arg.ArgumentContext; -import com.mattmx.ktgui.commands.declarative.arg.consumer.GreedyArgumentConsumer; -import com.mattmx.ktgui.commands.declarative.arg.impl.OnlinePlayerArgument; -import com.mattmx.ktgui.commands.declarative.arg.impl.StringArgument; import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; -import static com.mattmx.ktgui.commands.declarative.DeclarativeCommandBuilderKt.command; -import static com.mattmx.ktgui.utils.ColorKt.component; - public class JavaUpdateCommandExample { private void test() { new SimpleCommandBuilder("mattmx") @@ -31,30 +23,15 @@ private void test() { ) .register(false); - DeclarativeCommandBuilder.fromString("/hello ") - .runs(Player.class, (context) -> { + DeclarativeCommandBuilder.fromString(Player.class, "/hello ") + .runs((context) -> { ArgumentContext arg = context.getArgumentContext("arg"); if (arg == null) { System.out.println("arg was null"); } - assert arg != null; System.out.println(arg.getOrNull()); }); - - Argument player = new OnlinePlayerArgument("player", "player"); - Argument msg = new StringArgument("msg", "string", new GreedyArgumentConsumer()) - .min(1); - - new ChainCommandBuilder("msg") - .argument(player) - .argument(msg) - .build() - .runs(Player.class, (context) -> { - String msgValue = msg.getValue(context); - String str = String.format("[%s -> Me]: %s", context.getSender().name(), msgValue); - player.getValue(context).sendMessage(component(str)); - }).register(this); } } diff --git a/plugin/src/main/kotlin/com/mattmx/ktgui/KotlinGui.kt b/plugin/src/main/kotlin/com/mattmx/ktgui/KotlinGui.kt index ba8351d..2e916fa 100644 --- a/plugin/src/main/kotlin/com/mattmx/ktgui/KotlinGui.kt +++ b/plugin/src/main/kotlin/com/mattmx/ktgui/KotlinGui.kt @@ -1,29 +1,17 @@ package com.mattmx.ktgui -import com.mattmx.ktgui.commands.declarative.arg.impl.* import com.mattmx.ktgui.commands.declarative.arg.suggestsTopLevel -import com.mattmx.ktgui.commands.declarative.arg.withArgs +import com.mattmx.ktgui.commands.declarative.argument import com.mattmx.ktgui.commands.declarative.div import com.mattmx.ktgui.commands.declarative.invoke 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.GuiDesigner import com.mattmx.ktgui.examples.* -import com.mattmx.ktgui.papi.placeholder -import com.mattmx.ktgui.papi.placeholderExpansion import com.mattmx.ktgui.scheduling.sync -import com.mattmx.ktgui.sound.playSound -import com.mattmx.ktgui.sound.sound -import com.mattmx.ktgui.sound.soundBuilder import com.mattmx.ktgui.utils.not import com.mattmx.ktgui.utils.pretty import org.bukkit.Bukkit -<<<<<<< HEAD -======= -import org.bukkit.Sound ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb import org.bukkit.command.CommandSender import org.bukkit.entity.Player import org.bukkit.event.inventory.InventoryType @@ -68,16 +56,6 @@ class KotlinGui : JavaPlugin() { "config-gui" to { GuiConfigExample() }) GuiHookExample.registerListener(this) - placeholderExpansion { - - val player by playerArgument() - - placeholder("ping" / player) { player().ping } - placeholder("ping") { requestedBy?.ping } - placeholder("iscool" / player) { if (player().name == author) "this player's sick" else "nah not rly" } - - } id "ktgui" author "MattMX" - sync { val cachedDesigners = hashMapOf() rawCommand("ktgui") { @@ -130,7 +108,7 @@ class KotlinGui : JavaPlugin() { } }.register(false) - "designer" { + "designer" { buildAutomaticPermissions("ktgui.command") withDefaultUsageSubCommand(defaultUsageOptions) @@ -142,8 +120,8 @@ class KotlinGui : JavaPlugin() { typeOrRowArg invalid { reply(typeOrRowArgMessage) } id missing { reply(!"&cMissing argument 'id'. Need an identifier for the designer UI.") } - val create = ("create" / typeOrRowArg / id) { - runs { + val create = subcommand("create" / typeOrRowArg / id) { + runs { val type = runCatching { InventoryType.valueOf(typeOrRowArg().uppercase()) }.getOrNull() @@ -164,11 +142,10 @@ class KotlinGui : JavaPlugin() { } } - ("open" / id) { + subcommand("open" / id) { id suggests { cachedDesigners.keys.toList() } -<<<<<<< HEAD runs { val designer = cachedDesigners[id()] ?: return@runs reply( !"&cInvalid id, create one using &7/&fdesigner ${ @@ -177,28 +154,15 @@ class KotlinGui : JavaPlugin() { ) }" ) -======= - runs { - val designer = cachedDesigners[id()] - ?: return@runs reply( - !"&cInvalid id, create one using &7/&fdesigner ${ - create.getUsage( - defaultUsageOptions, - false - ) - }" - ) ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb designer.open(sender) } } val newTitle by argument("string") - ("set-title" / id / newTitle) { + subcommand("set-title" / id / newTitle) { id suggests { cachedDesigners.keys.toList() } -<<<<<<< HEAD runs { val designer = cachedDesigners[id()] ?: return@runs reply( !"&cInvalid id, create one using &7/&fdesigner ${ @@ -207,28 +171,16 @@ class KotlinGui : JavaPlugin() { ) }" ) -======= - runs { - val designer = cachedDesigners[id()] - ?: return@runs reply( - !"&cInvalid id, create one using &7/&fdesigner ${ - create.getUsage( - defaultUsageOptions, - false - ) - }" - ) ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb designer.exportTitle = newTitle() reply(!"&aSet title of ${id()} to ${newTitle()}") } } - subcommand("export" / id) { + subcommand("export" / id) { id suggests { cachedDesigners.keys.toList() } - runs { + runs { val designer = cachedDesigners.getOrPut(id()) { GuiDesigner(id()) } val file = designer.save(this@KotlinGui) reply(!"&aSaved to /plugins/KtGUI/designer/${file.name}") @@ -236,7 +188,6 @@ class KotlinGui : JavaPlugin() { } } register this@KotlinGui -<<<<<<< HEAD val someArg by argument("string", true) someArg { missing { reply(!"&cMissing argument 'someArg'!") } @@ -254,159 +205,6 @@ class KotlinGui : JavaPlugin() { withDefaultUsageSubCommand(defaultUsageOptions) runs { reply(!"&cfoo&f!") -======= - "ktgui-cmd-examples" { - buildAutomaticPermissions("ktgui.examples.command") - - ("sound") { - runs { - val sound = soundBuilder { - sound(Sound.ENTITY_ENDERMAN_DEATH) - wait(1) - sound(Sound.BLOCK_NOTE_BLOCK_BANJO) pitch 2f - } relative true - - sender.playSound(sound) - } - } - - val coords by relativeCoords() - - coords invalid { reply(!"&cInvalid coords provided") } - - ("tp" / coords) { - runs { - reply(!"&aTeleporting to ${coords().toVector()}") - sender.teleport(coords()) - } - } - - val invType by enumArgument() - - invType stringMethod { name.lowercase() } - invType invalid { reply(!"&cThat is not a valid inventory type.") } - - ("inventory" / invType) { - runs { - GuiScreen(!"", type = invType()).open(sender) - } - } - - val a by doubleArgument() - val b by doubleArgument() - ("+" / a / b) { - runs { - reply(!"&a${a()} + ${b()} = ${a() + b()}") - } - - invalid { reply(!"&cProvide two double values to add.") } - } - - val player by playerArgument() - player invalid { reply(!"&cInvalid player '$provided'") } - ("find" / player) { - runs { - val target = player() - reply( - !"&aFound ${target.name} @ ${ - target.location.clone().toVector() - } in world '${target.location.world.name}'." - ) - } - } - - val msg by greedyStringArgument() - msg min 1 - msg invalid { reply(!"&cMust provide a valid msg (at least 1 char)") } - ("msg" / player / msg) { - runs { - reply(!"&f[Me -> ${player().name}]: ${msg()}") - reply(!"&f[${sender.name} -> Me]: ${msg()}") - } - } - - val cooldownPeriod by longArgument() - cooldownPeriod optional true - // fixme: args optional don't work - ("cooldown" / cooldownPeriod) { - - cooldown(Duration.ofSeconds(3)) - - runs { - withArgs(cooldownPeriod) { - ActionCoolDown.unregister(coolDown.get()) - - val newDuration = Duration.ofMillis(cooldownPeriod()) - cooldown(newDuration) - - reply(!"&aSet new cooldown duration to ${newDuration.pretty()}.") - } or { - reply(!"&6Command ran successfully! &fProvide millis arg to set new cooldown period.") - } - } - } - - "obj" { - val objects = hashMapOf>() - - val objectId by stringArgument() - objectId range (3..16) matches "[a-z0-9_]{3,16}".toRegex() - objectId invalid { reply(!"Invalid object ID $provided") } - - ("create" / objectId) { - runs { - objects.putIfAbsent(objectId(), hashMapOf()) - reply(!"&aCreated object ${objectId()}") - } - } - - val existingObjectId by simpleArgument>() - existingObjectId getValue { objects[this] } - existingObjectId suggests { objects.keys.toList() } - existingObjectId invalid objectId.invalidCallback.first() - - val path by stringArgument() - path matches "([a-z0-9_]\\.?)+".toRegex() - val value by stringArgument() - ("set" / existingObjectId / path / value) { - runs { - existingObjectId().putIfAbsent(path(), value()) - reply(!"&aSet ${existingObjectId.context.stringValue()}:${path()} = '${value()}'") - } - } - - val pathOptional = path.clone() - pathOptional.optional() - ("get" / existingObjectId / pathOptional) { - runs { - - if (pathOptional.context.isEmpty()) { - reply(!"&aValues in object ${existingObjectId.context.stringValue()}") - for ((k, e) in existingObjectId().entries) { - reply(!"&f${k}&7 = &b'${e}'") - } - } else { - val value = existingObjectId()[pathOptional()] - if (value != null) { - reply(!"&cThere is no defined value for ${existingObjectId.context.stringValue()}:${pathOptional()}") - } else { - reply(!"&a${existingObjectId.context.stringValue()}:${pathOptional()} = '${value}'") - } - } - } - } - - ("del" / existingObjectId) { - runs { - objects.remove(existingObjectId.context.stringValue()) - reply(!"&cDeleted object ${existingObjectId.context.stringValue()}.") - } - } - } - - runs { - reply(!getUsage(defaultUsageOptions)) ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb } } register this@KotlinGui } @@ -423,13 +221,13 @@ class KotlinGui : JavaPlugin() { lateinit var log: Logger val defaultUsageOptions = CommandUsageOptions { - namePrefix = "&7/&f" + namePrefix = "&7/" arguments { prefix = "&7<&f" - typeChar = "&7:&6" + typeChar = "&7:&e" - required = "&c!" + required = "&4!" optional = "&7?" suffix = "&7>" @@ -437,7 +235,7 @@ class KotlinGui : JavaPlugin() { subCommands { prefix = "&f" - divider = "&7|&f" + divider = "&7|" } } } diff --git a/plugin/src/main/kotlin/com/mattmx/ktgui/examples/GuiHookExample.kt b/plugin/src/main/kotlin/com/mattmx/ktgui/examples/GuiHookExample.kt index 626b774..c6c4ae5 100644 --- a/plugin/src/main/kotlin/com/mattmx/ktgui/examples/GuiHookExample.kt +++ b/plugin/src/main/kotlin/com/mattmx/ktgui/examples/GuiHookExample.kt @@ -4,7 +4,6 @@ import com.mattmx.ktgui.KotlinGui import com.mattmx.ktgui.components.screen.GuiScreen import com.mattmx.ktgui.components.signal.signal import com.mattmx.ktgui.dsl.button -import com.mattmx.ktgui.dsl.effect import com.mattmx.ktgui.dsl.event import com.mattmx.ktgui.dsl.gui import com.mattmx.ktgui.event.PreGuiBuildEvent @@ -49,24 +48,22 @@ class GuiHookExample : Example { if ((gui as GuiScreen).id != "kgui.example.gui-hook") return@event var signalExampleVar by (gui as GuiScreen).signal(0) - (gui as GuiScreen).effect { - button(Material.PURPLE_DYE) { - named(!"&d&lA button") - lore { - add(!"&fThis button was added after the gui was built.") - add(!"&fWe can even add our own signals here and whatnot: $signalExampleVar") - add(!"&a&l[CLICK]") + gui.button(Material.PURPLE_DYE) { + named(!"&d&lA button") + lore { + add(!"&fThis button was added after the gui was built.") + add(!"&fWe can even add our own signals here and whatnot: $signalExampleVar") + add(!"&a&l[CLICK]") + } + click { + ClickType.LEFT { + signalExampleVar++ } - click { - ClickType.LEFT { - signalExampleVar++ - } - ClickType.RIGHT { - signalExampleVar-- - } + ClickType.RIGHT { + signalExampleVar-- } - } slot 15 - } + } + } slot 15 } } } diff --git a/plugin/src/main/resources/plugin.yml b/plugin/src/main/resources/plugin.yml index c5897d3..88bbd4f 100644 --- a/plugin/src/main/resources/plugin.yml +++ b/plugin/src/main/resources/plugin.yml @@ -4,12 +4,7 @@ main: com.mattmx.ktgui.KotlinGui api-version: 1.17 prefix: KtGUI authors: [ MattMX ] -website: https://github.com/Matt-MX/KtPaperGui description: Declarative GUI Library for Paper. - -depend: - - MCKotlin-Paper - softdepend: - PlaceholderAPI libraries: diff --git a/settings.gradle.kts b/settings.gradle.kts index d9a60c8..c976877 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -27,7 +27,6 @@ dependencyResolutionManagement { include("api") include("plugin") -<<<<<<< HEAD //gradleEnterprise { // if (System.getenv("CI") != null) { // buildScan { @@ -36,27 +35,4 @@ include("plugin") // termsOfServiceAgree = "yes" // } // } -//} -======= -pluginManagement { - repositories { - mavenCentral() - gradlePluginPortal() - maven("https://repo.papermc.io/repository/maven-public/") - } -} - -plugins { - id("com.gradle.enterprise") version("3.15") -} - -gradleEnterprise { - if (System.getenv("CI") != null) { - buildScan { - publishAlways() - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } - } -} ->>>>>>> fc760191aa5090e9dac6c3014739a12dc7fc5dfb +//} \ No newline at end of file