discord-kagebot/src/main/kotlin/moe/kageru/kagebot/command/Command.kt

85 lines
3.4 KiB
Kotlin

package moe.kageru.kagebot.command
import moe.kageru.kagebot.Globals
import moe.kageru.kagebot.Log
import moe.kageru.kagebot.MessageUtil
import moe.kageru.kagebot.Util.applyIf
import moe.kageru.kagebot.config.Config
import moe.kageru.kagebot.config.LocalizationSpec
import moe.kageru.kagebot.config.RawCommand
import moe.kageru.kagebot.features.MessageFeature
import org.javacord.api.entity.message.MessageAuthor
import org.javacord.api.entity.message.embed.EmbedBuilder
import org.javacord.api.event.message.MessageCreateEvent
private const val AUTHOR_PLACEHOLDER = "@@"
class Command(cmd: RawCommand) {
val trigger: String
private val response: String?
val matchType: MatchType
private val permissions: Permissions?
private val actions: MessageActions?
val regex: Regex?
val embed: EmbedBuilder?
val feature: MessageFeature?
init {
trigger = cmd.trigger ?: throw IllegalArgumentException("Every command must have a trigger.")
response = cmd.response
matchType = cmd.matchType?.let { type ->
MatchType.values().find { it.name.equals(type, ignoreCase = true) }
?: throw IllegalArgumentException("Invalid [command.matchType]: “${cmd.matchType}")
} ?: MatchType.PREFIX
permissions = cmd.permissions?.let { Permissions(it) }
actions = cmd.actions?.let { MessageActions(it) }
regex = if (matchType == MatchType.REGEX) Regex(trigger) else null
embed = cmd.embed?.let(MessageUtil::listToEmbed)
feature = cmd.feature?.let { Config.features.findByString(it) }
}
fun isAllowed(message: MessageCreateEvent) = permissions?.isAllowed(message) ?: true
fun execute(message: MessageCreateEvent): Boolean {
if (permissions?.isAllowed(message) == false) {
if (Config.localization[LocalizationSpec.permissionDenied].isNotBlank()) {
message.channel.sendMessage(Config.localization[LocalizationSpec.permissionDenied])
}
Log.info("Denying command ${this.trigger} to user ${message.messageAuthor.discriminatedName} (ID: ${message.messageAuthor.id})")
return false
}
Log.info("Executing command ${this.trigger} triggered by user ${message.messageAuthor.discriminatedName} (ID: ${message.messageAuthor.id})")
Globals.commandCounter.incrementAndGet()
this.actions?.run(message, this)
this.response?.let {
message.channel.sendMessage(respond(message.messageAuthor, it))
}
this.embed?.let {
MessageUtil.sendEmbed(message.channel, embed)
}
this.feature?.handle(message)
return true
}
fun matches(msg: String) = this.matchType.matches(msg, this)
private fun respond(author: MessageAuthor, response: String) =
response.applyIf(response.contains(AUTHOR_PLACEHOLDER)) {
it.replace(AUTHOR_PLACEHOLDER, MessageUtil.mention(author))
}
}
enum class MatchType {
PREFIX {
override fun matches(message: String, command: Command) = message.startsWith(command.trigger, ignoreCase = true)
},
CONTAINS {
override fun matches(message: String, command: Command) = message.contains(command.trigger, ignoreCase = true)
},
REGEX {
override fun matches(message: String, command: Command) = command.regex!!.matches(message)
};
abstract fun matches(message: String, command: Command): Boolean
}