kageru
f871d2a381
This means you can have multiple commands with the same or overlappings triggers, and the bot will execute the first the user has access to.
83 lines
3.3 KiB
Kotlin
83 lines
3.3 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.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.permissionDenied.isNotBlank()) {
|
|
message.channel.sendMessage(Config.localization.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)
|
|
},
|
|
CONTAINS {
|
|
override fun matches(message: String, command: Command) = message.contains(command.trigger)
|
|
},
|
|
REGEX {
|
|
override fun matches(message: String, command: Command) = command.regex!!.matches(message)
|
|
};
|
|
|
|
abstract fun matches(message: String, command: Command): Boolean
|
|
}
|