From e5faaebd381400906116ad74aca29d36d198dfdb Mon Sep 17 00:00:00 2001 From: Jakob K Date: Tue, 24 Aug 2021 02:30:59 +0200 Subject: [PATCH] Wrap the command context --- .../kspigot/commands/BrigardierWrapper.kt | 36 +++---------- .../axay/kspigot/commands/CommandContext.kt | 54 +++++++++++++++++++ 2 files changed, 60 insertions(+), 30 deletions(-) create mode 100644 src/main/kotlin/net/axay/kspigot/commands/CommandContext.kt diff --git a/src/main/kotlin/net/axay/kspigot/commands/BrigardierWrapper.kt b/src/main/kotlin/net/axay/kspigot/commands/BrigardierWrapper.kt index 413b1aa5..f43f6f74 100644 --- a/src/main/kotlin/net/axay/kspigot/commands/BrigardierWrapper.kt +++ b/src/main/kotlin/net/axay/kspigot/commands/BrigardierWrapper.kt @@ -4,8 +4,6 @@ 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 com.mojang.brigadier.exceptions.SimpleCommandExceptionType import com.mojang.brigadier.tree.LiteralCommandNode import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -13,9 +11,6 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.async import kotlinx.coroutines.future.asCompletableFuture import net.minecraft.commands.CommandListenerWrapper -import net.minecraft.network.chat.ChatMessage -import org.bukkit.World -import org.bukkit.entity.Player /** * Create a new command. @@ -37,11 +32,11 @@ inline fun command( /** * Add custom execution logic for this command. */ -inline fun ArgumentBuilder.simpleExecutes( - crossinline executor: (CommandContext) -> Unit, +inline fun ArgumentBuilder.simpleExecutes( + crossinline executor: CommandContext.() -> Unit, ) { executes wrapped@{ - executor.invoke(it) + executor.invoke(CommandContext(it)) return@wrapped 1 } } @@ -74,12 +69,12 @@ private val argumentCoroutineScope = CoroutineScope(SupervisorJob() + Dispatcher /** * Add custom suspending suggestion logic for an argument. */ -fun RequiredArgumentBuilder.simpleSuggests( - suggestionBuilder: suspend (CommandContext) -> Iterable?, +fun RequiredArgumentBuilder.simpleSuggests( + suggestionBuilder: suspend CommandContext.() -> Iterable?, ) { suggests { context, builder -> argumentCoroutineScope.async { - suggestionBuilder.invoke(context)?.forEach { + suggestionBuilder.invoke(CommandContext(context))?.forEach { if (it is Int) builder.suggest(it) else @@ -89,22 +84,3 @@ fun RequiredArgumentBuilder.simpleSuggests( }.asCompletableFuture() } } - -/** - * Get the value of this argument. - */ -inline fun CommandContext.getArgument(name: String): T = - getArgument(name, T::class.java) - -private val REQUIRES_PLAYER_EXCEPTION = SimpleCommandExceptionType(ChatMessage("permissions.requires.player")) - -/** - * Returns the player who executed the command, or fails the command - * if it wasn't executed by a player. - */ -val CommandListenerWrapper.player get() = this.bukkitSender as? Player ?: throw REQUIRES_PLAYER_EXCEPTION.create() - -/** - * Returns the Bukkit world instance. - */ -val CommandListenerWrapper.bukkitWorld get() = world.world as World diff --git a/src/main/kotlin/net/axay/kspigot/commands/CommandContext.kt b/src/main/kotlin/net/axay/kspigot/commands/CommandContext.kt new file mode 100644 index 00000000..d8a0da70 --- /dev/null +++ b/src/main/kotlin/net/axay/kspigot/commands/CommandContext.kt @@ -0,0 +1,54 @@ +package net.axay.kspigot.commands + +import com.mojang.brigadier.context.CommandContext +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType +import net.minecraft.commands.CommandListenerWrapper +import net.minecraft.network.chat.ChatMessage +import org.bukkit.Location +import org.bukkit.Server +import org.bukkit.World +import org.bukkit.entity.Player + +class CommandContext(val nmsContext: CommandContext) { + companion object { + private val REQUIRES_PLAYER_EXCEPTION = SimpleCommandExceptionType(ChatMessage("permissions.requires.player")) + } + + /** + * Get the value of the given argument. + */ + inline fun getArgument(name: String): T = + nmsContext.getArgument(name, T::class.java) + + /** + * The source / sender which executed this command. + */ + val sender get() = nmsContext.source.bukkitSender + + /** + * Validates that this command was executes by a player (sends an error message to the sender if this is not the case) + * and returns the [Player]. + */ + val player get() = nmsContext.source.bukkitSender as? Player ?: throw REQUIRES_PLAYER_EXCEPTION.create() + + /** + * The world where the source of this command currently is in. + * + * Please note: this could be null and therefore throw an exception if called, but + * these cases are rare (e.g. command called by a datapack function), therefore + * this property is not nullable for convenience + */ + val world get() = nmsContext.source.world.world as World + + /** + * The position of the source of this command. + */ + val position get() = with(nmsContext.source.position) { + Location(nmsContext.source.world.world as? World?, x, y, z) + } + + /** + * The current server instance. + */ + val server get() = nmsContext.source.server.server as Server +}