Skip to content

Commit

Permalink
fix: suggestions not entire working correctly, improve help topic & v…
Browse files Browse the repository at this point in the history
…arious other improvements
  • Loading branch information
StillLutto committed Jan 13, 2025
1 parent e3f8d12 commit a28c07b
Show file tree
Hide file tree
Showing 54 changed files with 241 additions and 422 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.undefined.stellar

import com.undefined.stellar.argument.AbstractStellarArgument
import com.undefined.stellar.argument.ArgumentHandler
import com.undefined.stellar.data.argument.CommandContext
import com.undefined.stellar.data.execution.StellarExecution
Expand All @@ -15,12 +16,12 @@ import org.jetbrains.annotations.ApiStatus
import java.util.*

@Suppress("UNCHECKED_CAST")
abstract class AbstractStellarCommand<T>(val name: String, val description: String = "", usage: String = "") : ArgumentHandler() {
abstract class AbstractStellarCommand<T>(val name: String, val description: String = "A custom Stellar command.", usage: String = "", aliases: List<String> = mutableListOf()) : ArgumentHandler() {

override val base: AbstractStellarCommand<*>
get() = this
@ApiStatus.Internal val aliases: MutableList<String> = mutableListOf()
@ApiStatus.Internal val helpTopic: SortedMap<String, String> = sortedMapOf()
@ApiStatus.Internal val aliases: MutableList<String> = aliases.toMutableList()
@ApiStatus.Internal val information: SortedMap<String, String> = sortedMapOf()
@ApiStatus.Internal open val failureMessages: MutableList<Component> = mutableListOf()
@ApiStatus.Internal open val globalFailureMessages: MutableList<Component> = mutableListOf()
@ApiStatus.Internal open val failureExecutions: MutableList<StellarExecution<*>> = mutableListOf()
Expand All @@ -32,9 +33,11 @@ abstract class AbstractStellarCommand<T>(val name: String, val description: Stri
@ApiStatus.Internal open val registerExecutions: MutableList<() -> Unit> = mutableListOf()

init {
if (description.isNotEmpty()) helpTopic["Description"] to description
if (usage.isNotEmpty()) helpTopic["Usage"] to usage
if (aliases.isNotEmpty()) helpTopic["Aliases"] = aliases.joinToString(", ")
if (this !is AbstractStellarArgument<*>) {
if (aliases.isNotEmpty()) information["Aliases"] = aliases.joinToString(", ")
if (usage.isNotEmpty()) information["Usage"] = usage
if (description.isNotEmpty()) information["Description"] = description
}
}

fun setAliases(vararg aliases: String): T {
Expand All @@ -49,22 +52,22 @@ abstract class AbstractStellarCommand<T>(val name: String, val description: Stri
}

fun setDescription(description: String): T {
helpTopic["Description"] = description
information["Description"] = description
return this as T
}

fun setUsageText(usage: String): T {
helpTopic["Usage"] = usage
information["Usage"] = usage
return this as T
}

fun setInformation(name: String, text: String): T {
helpTopic[name] = text
information[name] = text
return this as T
}

fun clearInformation(): T {
helpTopic.clear()
information.clear()
return this as T
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,7 @@ abstract class AbstractStellarArgument<T>(val parent: AbstractStellarCommand<*>,
}

fun addSuggestions(vararg suggestions: Suggestion): T = addSuggestions(suggestions.toList())

fun addSuggestionWithoutTooltip(suggestion: String): T = addSuggestions(listOf(Suggestion(suggestion, "")))

fun addSuggestionsWithoutTooltip(suggestions: List<String>): T = addSuggestions(suggestions.map { Suggestion(it, "") })

fun addSuggestions(vararg list: String): T = addSuggestions(list.map { Suggestion(it, "") })
fun addSuggestions(vararg suggestions: String): T = addSuggestions(suggestions.map { Suggestion(it, "") })

fun setSuggestions(vararg suggestions: Suggestion): T {
this.suggestions.clear()
Expand All @@ -58,13 +53,18 @@ abstract class AbstractStellarArgument<T>(val parent: AbstractStellarCommand<*>,
return addSuggestions(suggestions.map { Suggestion(it, "") })
}

inline fun <reified C : CommandSender> addAsyncSuggestion(noinline suggestion: CommandContext<C>.() -> CompletableFuture<List<Suggestion>>): T {
inline fun <reified C : CommandSender> addFutureSuggestion(noinline suggestion: CommandContext<C>.(input: String) -> CompletableFuture<List<Suggestion>>): T {
suggestions.add(StellarSuggestion(C::class, suggestion))
return this as T
}

inline fun <reified C : CommandSender> addSuggestion(noinline suggestion: CommandContext<C>.() -> List<Suggestion>): T {
suggestions.add(StellarSuggestion(C::class) { CompletableFuture.completedFuture(suggestion(this)) })
inline fun <reified C : CommandSender> addAsyncSuggestion(noinline suggestion: CommandContext<C>.(input: String) -> List<Suggestion>): T {
suggestions.add(StellarSuggestion(C::class) { CompletableFuture.supplyAsync { suggestion(this, it) } })
return this as T
}

inline fun <reified C : CommandSender> addSuggestion(noinline suggestion: CommandContext<C>.(input: String) -> List<Suggestion>): T {
suggestions.add(StellarSuggestion(C::class) { CompletableFuture.completedFuture(suggestion(this, it)) })
return this as T
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package com.undefined.stellar.argument
import com.undefined.stellar.AbstractStellarCommand
import com.undefined.stellar.argument.block.BlockDataArgument
import com.undefined.stellar.argument.block.BlockPredicateArgument
import com.undefined.stellar.argument.custom.EnumArgument
import com.undefined.stellar.argument.custom.EnumFormatting
import com.undefined.stellar.argument.custom.ListArgument
import com.undefined.stellar.argument.entity.EntityAnchorArgument
import com.undefined.stellar.argument.item.ItemPredicateArgument
Expand Down Expand Up @@ -163,15 +165,15 @@ open class ArgumentHandler {
fun addUUIDListArgument(name: String, list: CommandContext<CommandSender>.() -> List<UUID>): ListArgument<UUID> =
addArgument { ListArgument(UUIDArgument(base, name), list, parse = { it }) }

inline fun <reified T : Enum<T>> addEnumArgument(name: String): com.undefined.stellar.argument.custom.EnumArgument<T> =
addArgument { com.undefined.stellar.argument.custom.EnumArgument<T>(base, name, T::class) }
inline fun <reified T : Enum<T>> addEnumArgument(name: String, formatting: EnumFormatting = EnumFormatting.LOWERCASE): EnumArgument<T> =
addArgument { EnumArgument<T>(base, name, T::class, { Suggestion.withText(formatting.action(it!!.name)) }) }

inline fun <reified T : Enum<T>> addEnumArgument(
name: String,
noinline converter: (Enum<*>?) -> Suggestion = { Suggestion.withText(it?.name ?: "") },
noinline converter: (Enum<*>?) -> Suggestion = { Suggestion.withText(it!!.name) },
noinline parse: (Any?) -> Enum<T>?
): com.undefined.stellar.argument.custom.EnumArgument<T> = addArgument {
com.undefined.stellar.argument.custom.EnumArgument(
): EnumArgument<T> = addArgument {
EnumArgument(
base,
name,
T::class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class EnumArgument<T : Enum<T>>(
parent: AbstractStellarCommand<*>,
name: String,
val enum: KClass<out Enum<*>>,
converter: (Enum<*>?) -> Suggestion = { Suggestion.withText(it?.name ?: "") },
converter: (Enum<*>?) -> Suggestion = { Suggestion.withText(it!!.name) },
parse: (Any?) -> Enum<T>? = {
try {
valueOf(enum.java, (it as String).uppercase()) as Enum<T>
Expand All @@ -21,12 +21,16 @@ class EnumArgument<T : Enum<T>>(
}
}
) : ListArgument<Enum<*>?>(StringArgument(parent, name, StringType.WORD), enum.java.enumConstants.toList(), converter, parse) {

fun valueOf(name: String): Enum<T>? =
try {
valueOf(enum.java, name) as Enum<T>
} catch (e: IllegalArgumentException) {
null
}
}

enum class EnumFormatting(val action: (String) -> String) {
LOWERCASE({ it.lowercase() }),
UPPERCASE({ it.uppercase() }),
CAPITALIZED({ it.lowercase().replaceFirstChar { char -> char.uppercase() } }),
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ open class ListArgument<T>(
}

override val suggestions: MutableList<StellarSuggestion<*>>
get() = (super.suggestions + StellarSuggestion(CommandSender::class) { CompletableFuture.completedFuture(getSuggestionList(this)) }).toMutableList()
get() = (super.suggestions + StellarSuggestion(CommandSender::class) { input ->
CompletableFuture.completedFuture(getSuggestionList(this).filter { it.text.startsWith(input, true) })
}).toMutableList()

fun getSuggestionList(context: CommandContext<CommandSender>): List<Suggestion> = list(context).map(converter)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import kotlin.reflect.KClass
import kotlin.reflect.safeCast

@Suppress("UNCHECKED_CAST")
data class StellarSuggestion<C : CommandSender>(private val clazz: KClass<C>, private val suggestion: CommandContext<C>.() -> CompletableFuture<List<Suggestion>>) {
fun get(context: CommandContext<CommandSender>): CompletableFuture<List<Suggestion>> {
if (clazz.safeCast(context.sender) == null) return CompletableFuture.completedFuture(listOf())
return suggestion(context as CommandContext<C>)
}
data class StellarSuggestion<C : CommandSender>(private val clazz: KClass<C>, private val suggestion: CommandContext<C>.(input: String) -> CompletableFuture<List<Suggestion>>) {
fun get(context: CommandContext<CommandSender>, input: String = ""): CompletableFuture<List<Suggestion>> = // TODO remove default value
clazz.safeCast(context.sender)?.let { suggestion(context as CommandContext<C>, input) } ?: CompletableFuture.completedFuture(listOf())
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ import org.bukkit.command.CommandSender
import org.bukkit.plugin.java.JavaPlugin
import org.jetbrains.annotations.ApiStatus

class StellarCommand(name: String, permissions: List<String> = listOf(), aliases: List<String> = listOf()) : AbstractStellarCommand<StellarCommand>(name) {
class StellarCommand(name: String, permissions: List<String> = listOf(), aliases: List<String> = listOf()) : AbstractStellarCommand<StellarCommand>(name, aliases = aliases) {

constructor(name: String, vararg aliases: String) : this(name, aliases = aliases.toList())
constructor(name: String, permission: String, vararg aliases: String) : this(name, listOf(permission), aliases.toList())
constructor(name: String, permission: String, aliases: List<String>) : this(name, listOf(permission), aliases)

init {
this.permissionRequirements.addAll(permissions.map { PermissionStellarRequirement(1, it) })
this.aliases.addAll(aliases)
}

private var registered = false
Expand Down
14 changes: 13 additions & 1 deletion paper/api/src/main/kotlin/com/undefined/stellar/util/Builders.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,16 @@ fun command(name: String, description: String, builder: StellarCommand.() -> Uni
fun command(name: String, description: String, permissions: List<String>, builder: StellarCommand.() -> Unit): StellarCommand = command(name, description, permissions, listOf(), builder)
fun command(name: String, permissions: List<String>, builder: StellarCommand.() -> Unit): StellarCommand = command(name, "", permissions, listOf(), builder)
fun command(name: String, permissions: List<String>, aliases: List<String>, builder: StellarCommand.() -> Unit): StellarCommand = command(name, "", permissions, aliases, builder)
fun command(name: String, builder: StellarCommand.() -> Unit): StellarCommand = command(name, "", builder)
fun command(name: String, builder: StellarCommand.() -> Unit): StellarCommand = command(name, "", builder)

fun command(name: String, description: String, permissions: List<String>, aliases: List<String>): StellarCommand {
val command = StellarCommand(name, permissions, aliases)
command.setDescription(description)
return command
}

fun command(name: String, description: String): StellarCommand = command(name, description, listOf(), listOf())
fun command(name: String, description: String, permissions: List<String>): StellarCommand = command(name, description, permissions, listOf())
fun command(name: String, permissions: List<String>): StellarCommand = command(name, "", permissions, listOf())
fun command(name: String, permissions: List<String>, aliases: List<String>): StellarCommand = command(name, "", permissions, aliases)
fun command(name: String): StellarCommand = command(name, "")

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import net.minecraft.server.MinecraftServer
import org.bukkit.Bukkit
import java.util.concurrent.CompletableFuture

@Suppress("DEPRECATION")
object BrigadierCommandHelper {

val COMMAND_SOURCE: CommandSourceStack by lazy {
Expand All @@ -27,7 +28,7 @@ object BrigadierCommandHelper {

fun handleHelpTopic(command: AbstractStellarCommand<*>) {
Bukkit.getServer().helpMap.addTopic(
CustomCommandHelpTopic(command.name, command.description, command.helpTopic) {
CustomCommandHelpTopic(command.name, command.description, command.information) {
val context = MinecraftServer.getServer().createCommandSourceStack()
val requirements = command.requirements.all { it(this) }
val permissionRequirements = command.permissionRequirements.all {
Expand Down Expand Up @@ -62,7 +63,7 @@ object BrigadierCommandHelper {
val stellarContext = CommandContextAdapter.getStellarCommandContext(context)
val completions: CompletableFuture<List<com.undefined.stellar.data.suggestion.Suggestion>> = CompletableFuture.supplyAsync {
val suggestions: MutableList<com.undefined.stellar.data.suggestion.Suggestion> = mutableListOf()
for (suggestion in command.suggestions) suggestions.addAll(suggestion.get(stellarContext).get())
for (suggestion in command.suggestions) suggestions.addAll(suggestion.get(stellarContext, builder.remaining).get())
suggestions
}
return CommandAdapter.getMojangSuggestions(builder, completions)
Expand Down
11 changes: 4 additions & 7 deletions server/src/main/kotlin/com/undefined/stellar/Main.kt
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
package com.undefined.stellar

import com.undefined.stellar.argument.custom.EnumFormatting
import com.undefined.stellar.data.suggestion.Suggestion
import org.bukkit.Bukkit
import org.bukkit.World.Environment
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.plugin.java.JavaPlugin
import java.util.concurrent.CompletableFuture

class Main : JavaPlugin() {

override fun onEnable() {
StellarCommand("test")
.addEnumArgument<Environment>("env")
StellarCommand("test", "t")
.addEnumArgument<Environment>("env", EnumFormatting.LOWERCASE)
.addExecution<Player> {
val env = getArgument<Environment>("env")
sender.sendMessage(env.name)
}
.addStringArgument("test")
.addAsyncSuggestion<Player> {
.addFutureSuggestion<Player> {
CompletableFuture.supplyAsync {
return@supplyAsync listOf(Suggestion.withText("test"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import net.minecraft.server.v1_13_R1.CommandListenerWrapper
import net.minecraft.server.v1_13_R1.MinecraftServer
import org.bukkit.Bukkit
import org.bukkit.scheduler.BukkitRunnable
import java.util.concurrent.CompletableFuture

@Suppress("DEPRECATION")
Expand All @@ -31,7 +30,7 @@ object BrigadierCommandHelper {

fun handleHelpTopic(command: AbstractStellarCommand<*>) {
Bukkit.getServer().helpMap.addTopic(
CustomCommandHelpTopic(command.name, command.description, command.helpTopic) {
CustomCommandHelpTopic(command.name, command.description, command.information) {
val context = MinecraftServer.getServer().serverCommandListener
val requirements = command.requirements.all { it(this) }
val permissionRequirements = command.permissionRequirements.all {
Expand Down Expand Up @@ -92,9 +91,3 @@ object BrigadierCommandHelper {
}

}

fun sync(execution: () -> Unit) {
object : BukkitRunnable() {
override fun run() = execution()
}.runTask(CommandRegistrar.plugin)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import net.minecraft.server.v1_13_R2.CommandListenerWrapper
import net.minecraft.server.v1_13_R2.MinecraftServer
import org.bukkit.Bukkit
import org.bukkit.scheduler.BukkitRunnable
import java.util.concurrent.CompletableFuture

@Suppress("DEPRECATION")
Expand All @@ -31,7 +30,7 @@ object BrigadierCommandHelper {

fun handleHelpTopic(command: AbstractStellarCommand<*>) {
Bukkit.getServer().helpMap.addTopic(
CustomCommandHelpTopic(command.name, command.description, command.helpTopic) {
CustomCommandHelpTopic(command.name, command.description, command.information) {
val context = MinecraftServer.getServer().serverCommandListener
val requirements = command.requirements.all { it(this) }
val permissionRequirements = command.permissionRequirements.all {
Expand Down Expand Up @@ -92,9 +91,3 @@ object BrigadierCommandHelper {
}

}

fun sync(execution: () -> Unit) {
object : BukkitRunnable() {
override fun run() = execution()
}.runTask(CommandRegistrar.plugin)
}
Loading

0 comments on commit a28c07b

Please sign in to comment.