io.github.freya022.botcommands.internal.commands.application.slash.SlashCommandInfo.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of BotCommands Show documentation
Show all versions of BotCommands Show documentation
A Kotlin-first (and Java) framework that makes creating Discord bots a piece of cake, using the JDA library.
package io.github.freya022.botcommands.internal.commands.application.slash
import dev.minn.jda.ktx.messages.reply_
import io.github.freya022.botcommands.api.commands.application.slash.GlobalSlashEvent
import io.github.freya022.botcommands.api.commands.application.slash.GuildSlashEvent
import io.github.freya022.botcommands.api.commands.application.slash.builder.SlashCommandBuilder
import io.github.freya022.botcommands.api.commands.ratelimit.CancellableRateLimit
import io.github.freya022.botcommands.api.core.BContext
import io.github.freya022.botcommands.api.core.utils.simpleNestedName
import io.github.freya022.botcommands.internal.*
import io.github.freya022.botcommands.internal.commands.application.ApplicationCommandInfo
import io.github.freya022.botcommands.internal.commands.application.ApplicationGeneratedOption
import io.github.freya022.botcommands.internal.commands.application.slash.SlashUtils.getCheckedDefaultValue
import io.github.freya022.botcommands.internal.core.options.Option
import io.github.freya022.botcommands.internal.core.options.OptionType
import io.github.freya022.botcommands.internal.core.reflection.checkEventScope
import io.github.freya022.botcommands.internal.core.reflection.toMemberEventFunction
import io.github.freya022.botcommands.internal.parameters.CustomMethodOption
import io.github.freya022.botcommands.internal.utils.*
import io.github.oshai.kotlinlogging.KotlinLogging
import net.dv8tion.jda.api.events.Event
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
import net.dv8tion.jda.api.interactions.commands.CommandInteractionPayload
import kotlin.reflect.KParameter
import kotlin.reflect.full.callSuspendBy
import kotlin.reflect.jvm.jvmErasure
private val logger = KotlinLogging.logger { }
abstract class SlashCommandInfo internal constructor(
val context: BContext,
builder: SlashCommandBuilder
) : ApplicationCommandInfo(
builder
) {
val description: String
final override val eventFunction = builder.toMemberEventFunction(context)
final override val parameters: List
init {
eventFunction.checkEventScope(builder)
val rootDescription = LocalizationUtils.getCommandRootDescription(context, builder)
description = if (builder.description != SlashCommandBuilder.DEFAULT_DESCRIPTION) {
// If a description was set, then use it, but check if a root description was found too
if (rootDescription != null) {
logger.debug { "A command description was set manually, while a root description was found in a localization bundle, path: '$path'" }
}
builder.description
} else {
// If a description isn't set, then take the root description if it exists,
// otherwise take the builder's default description
rootDescription ?: builder.description
}
parameters = builder.optionAggregateBuilders.transform {
SlashCommandParameter(this@SlashCommandInfo, builder.optionAggregateBuilders, it)
}
parameters
.flatMap { it.allOptions }
.filterIsInstance()
.forEach(SlashCommandOption::buildAutocomplete)
}
internal suspend fun execute(jdaEvent: SlashCommandInteractionEvent, cancellableRateLimit: CancellableRateLimit): Boolean {
val event = when {
topLevelInstance.isGuildOnly -> GuildSlashEvent(context, jdaEvent, cancellableRateLimit)
else -> GlobalSlashEvent(context, jdaEvent, cancellableRateLimit)
}
val objects = getSlashOptions(event, parameters) ?: return false
function.callSuspendBy(objects)
return true
}
context(IExecutableInteractionInfo)
internal suspend fun getSlashOptions(
event: T,
parameters: List
): Map? where T : CommandInteractionPayload, T : Event {
val optionValues = parameters.mapOptions { option ->
if (tryInsertOption(event, this, option) == InsertOptionResult.ABORT)
return null
}
return parameters.mapFinalParameters(event, optionValues)
}
private suspend fun tryInsertOption(
event: T,
optionMap: MutableMap