Add brigardier support
This commit is contained in:
@@ -0,0 +1,23 @@
|
|||||||
|
package net.axay.kspigot.commands
|
||||||
|
|
||||||
|
import com.mojang.brigadier.CommandDispatcher
|
||||||
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder
|
||||||
|
import net.axay.kspigot.extensions.server
|
||||||
|
import net.minecraft.commands.CommandListenerWrapper
|
||||||
|
import org.bukkit.craftbukkit.v1_17_R1.CraftServer
|
||||||
|
|
||||||
|
object BrigardierSupport {
|
||||||
|
@PublishedApi
|
||||||
|
internal val commands = ArrayList<LiteralArgumentBuilder<CommandListenerWrapper>>()
|
||||||
|
|
||||||
|
fun registerAll() {
|
||||||
|
val commandManager = (server as CraftServer).server.commandDispatcher
|
||||||
|
|
||||||
|
val dispatcherField = net.minecraft.commands.CommandDispatcher::class.java.getDeclaredField("g")
|
||||||
|
dispatcherField.isAccessible = true
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val dispatcher = dispatcherField.get(commandManager) as CommandDispatcher<CommandListenerWrapper>
|
||||||
|
|
||||||
|
commands.forEach { dispatcher.register(it) }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,93 @@
|
|||||||
|
package net.axay.kspigot.commands
|
||||||
|
|
||||||
|
import com.mojang.brigadier.arguments.ArgumentType
|
||||||
|
import com.mojang.brigadier.builder.ArgumentBuilder
|
||||||
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder
|
||||||
|
import com.mojang.brigadier.builder.RequiredArgumentBuilder
|
||||||
|
import com.mojang.brigadier.context.CommandContext
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.future.asCompletableFuture
|
||||||
|
import net.minecraft.commands.CommandListenerWrapper
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command.
|
||||||
|
*
|
||||||
|
* @param name the name of the root command
|
||||||
|
* @param register if true, the command will automatically be registered
|
||||||
|
*/
|
||||||
|
inline fun command(
|
||||||
|
name: String,
|
||||||
|
register: Boolean = true,
|
||||||
|
builder: LiteralArgumentBuilder<CommandListenerWrapper>.() -> Unit
|
||||||
|
): LiteralArgumentBuilder<CommandListenerWrapper> =
|
||||||
|
LiteralArgumentBuilder.literal<CommandListenerWrapper>(name).apply(builder).apply {
|
||||||
|
if (register)
|
||||||
|
BrigardierSupport.commands += this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add custom execution logic for this command.
|
||||||
|
*/
|
||||||
|
inline fun <S> ArgumentBuilder<S, *>.simpleExecutes(
|
||||||
|
crossinline executor: (CommandContext<S>) -> Unit
|
||||||
|
) {
|
||||||
|
executes wrapped@{
|
||||||
|
executor.invoke(it)
|
||||||
|
return@wrapped 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new literal to this command.
|
||||||
|
*
|
||||||
|
* @param name the name of the literal
|
||||||
|
*/
|
||||||
|
inline fun ArgumentBuilder<CommandListenerWrapper, *>.literal(
|
||||||
|
name: String,
|
||||||
|
builder: LiteralArgumentBuilder<CommandListenerWrapper>.() -> Unit
|
||||||
|
) {
|
||||||
|
then(command(name, false, builder))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an argument.
|
||||||
|
*
|
||||||
|
* @param name the name of the argument
|
||||||
|
* @param type the type of the argument - e.g. IntegerArgumentType.integer() or StringArgumentType.string()
|
||||||
|
*/
|
||||||
|
inline fun <T> ArgumentBuilder<CommandListenerWrapper, *>.argument(
|
||||||
|
name: String,
|
||||||
|
type: ArgumentType<T>,
|
||||||
|
builder: RequiredArgumentBuilder<CommandListenerWrapper, T>.() -> Unit
|
||||||
|
) {
|
||||||
|
then(RequiredArgumentBuilder.argument<CommandListenerWrapper, T>(name, type).apply(builder))
|
||||||
|
}
|
||||||
|
|
||||||
|
private val argumentCoroutineScope = CoroutineScope(Dispatchers.IO)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add custom suspending suggestion logic for an argument.
|
||||||
|
*/
|
||||||
|
fun <S> RequiredArgumentBuilder<S, *>.simpleSuggests(
|
||||||
|
suggestionBuilder: suspend (CommandContext<S>) -> Iterable<Any?>?
|
||||||
|
) {
|
||||||
|
suggests { context, builder ->
|
||||||
|
argumentCoroutineScope.async {
|
||||||
|
suggestionBuilder.invoke(context)?.forEach {
|
||||||
|
if (it is Int)
|
||||||
|
builder.suggest(it)
|
||||||
|
else
|
||||||
|
builder.suggest(it.toString())
|
||||||
|
}
|
||||||
|
builder.build()
|
||||||
|
}.asCompletableFuture()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of this argument.
|
||||||
|
*/
|
||||||
|
inline fun <reified T> CommandContext<CommandListenerWrapper>.getArgument(name: String): T =
|
||||||
|
getArgument(name, T::class.java)
|
Reference in New Issue
Block a user