diff --git a/surf-api-velocity/surf-api-velocity-api/build.gradle.kts b/surf-api-velocity/surf-api-velocity-api/build.gradle.kts index 6d0156fd..6fa06f88 100644 --- a/surf-api-velocity/surf-api-velocity-api/build.gradle.kts +++ b/surf-api-velocity/surf-api-velocity-api/build.gradle.kts @@ -13,4 +13,10 @@ dependencies { api(libs.commandapi.velocity.kotlin) } +kotlin { + compilerOptions { + optIn.add("dev.slne.surf.surfapi.core.api.util.InternalSurfApi") + } +} + description = "surf-api-velocity-api" diff --git a/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/InternalCommandBridge.kt b/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/InternalCommandBridge.kt new file mode 100644 index 00000000..edde0001 --- /dev/null +++ b/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/InternalCommandBridge.kt @@ -0,0 +1,20 @@ +package dev.slne.surf.surfapi.velocity.api.command.args + +import com.velocitypowered.api.proxy.Player +import dev.slne.surf.surfapi.core.api.util.InternalSurfApi +import dev.slne.surf.surfapi.core.api.util.requiredService +import kotlinx.coroutines.Deferred +import java.util.* + +@InternalSurfApi +interface InternalCommandBridge { + fun getPlayer(name: String): Player? + fun getPlayer(uuid: UUID): Player? + fun getPlayers(): Collection + + suspend fun requestPlayerUuid(name: String): UUID? + + fun async(block: suspend () -> T): Deferred + + companion object : InternalCommandBridge by requiredService() +} \ No newline at end of file diff --git a/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/OfflinePlaynameToUuid.kt b/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/OfflinePlaynameToUuid.kt new file mode 100644 index 00000000..0ee9a4ec --- /dev/null +++ b/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/OfflinePlaynameToUuid.kt @@ -0,0 +1,53 @@ +package dev.slne.surf.surfapi.velocity.api.command.args + +import com.mojang.brigadier.arguments.StringArgumentType +import com.mojang.brigadier.context.CommandContext +import dev.jorel.commandapi.CommandAPICommand +import dev.jorel.commandapi.arguments.Argument +import dev.jorel.commandapi.arguments.ArgumentSuggestions +import dev.jorel.commandapi.arguments.CommandAPIArgumentType +import dev.jorel.commandapi.executors.CommandArguments +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.Deferred +import java.util.* + +class OfflinePlaynameToUuid(nodeName: String) : + Argument>(nodeName, StringArgumentType.word()) { + + init { + replaceSuggestions(ArgumentSuggestions.stringCollection { + InternalCommandBridge.getPlayers().map { it.username } + }) + } + + override fun getPrimitiveType(): Class> { + @Suppress("UNCHECKED_CAST") + return Deferred::class.java as Class> + } + + override fun getArgumentType(): CommandAPIArgumentType? { + return CommandAPIArgumentType.PRIMITIVE_STRING + } + + override fun parseArgument( + cmdCtx: CommandContext, + key: String, + previousArgs: CommandArguments, + ): Deferred { + val playerName = StringArgumentType.getString(cmdCtx, key) + val onlinePlayer = InternalCommandBridge.getPlayer(playerName) + + if (onlinePlayer != null) { + return CompletableDeferred(onlinePlayer.uniqueId) + } + + return InternalCommandBridge.async { InternalCommandBridge.requestPlayerUuid(playerName) } + } +} + +inline fun CommandAPICommand.offlinePlaynameToUuid( + nodeName: String, + optional: Boolean = false, + block: Argument<*>.() -> Unit = {}, +): CommandAPICommand = + withArguments(OfflinePlaynameToUuid(nodeName).setOptional(optional).apply(block)) \ No newline at end of file diff --git a/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/PlayerArgument.kt b/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/PlayerArgument.kt new file mode 100644 index 00000000..aeca9baf --- /dev/null +++ b/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/PlayerArgument.kt @@ -0,0 +1,46 @@ +package dev.slne.surf.surfapi.velocity.api.command.args + +import com.mojang.brigadier.arguments.StringArgumentType +import com.mojang.brigadier.context.CommandContext +import com.velocitypowered.api.proxy.Player +import dev.jorel.commandapi.CommandAPICommand +import dev.jorel.commandapi.arguments.Argument +import dev.jorel.commandapi.arguments.ArgumentSuggestions +import dev.jorel.commandapi.arguments.CommandAPIArgumentType +import dev.jorel.commandapi.executors.CommandArguments + +class PlayerArgument(nodeName: String) : Argument(nodeName, StringArgumentType.word()) { + companion object { + private val NO_PLAYERS_FOUND = SimpleCommandExceptionType("No player was found") + } + + init { + replaceSuggestions(ArgumentSuggestions.stringCollection { + InternalCommandBridge.getPlayers().map { it.username } + }) + } + + override fun getPrimitiveType(): Class { + return Player::class.java + } + + override fun getArgumentType(): CommandAPIArgumentType? { + return CommandAPIArgumentType.PRIMITIVE_STRING + } + + override fun parseArgument( + cmdCtx: CommandContext, + key: String, + previousArgs: CommandArguments, + ): Player { + val playerName = StringArgumentType.getString(cmdCtx, key) + return InternalCommandBridge.getPlayer(playerName) ?: throw NO_PLAYERS_FOUND.create() + } +} + +inline fun CommandAPICommand.playerArgument( + nodeName: String, + optional: Boolean = false, + block: Argument<*>.() -> Unit = {}, +): CommandAPICommand = + withArguments(PlayerArgument(nodeName).setOptional(optional).apply(block)) \ No newline at end of file diff --git a/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/extensions.kt b/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/extensions.kt new file mode 100644 index 00000000..d82aca9c --- /dev/null +++ b/surf-api-velocity/surf-api-velocity-api/src/main/kotlin/dev/slne/surf/surfapi/velocity/api/command/args/extensions.kt @@ -0,0 +1,8 @@ +package dev.slne.surf.surfapi.velocity.api.command.args + +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType +import com.velocitypowered.api.command.VelocityBrigadierMessage +import dev.slne.surf.surfapi.core.api.messages.adventure.text + +fun SimpleCommandExceptionType(message: String) = + SimpleCommandExceptionType(VelocityBrigadierMessage.tooltip(text(message))) \ No newline at end of file