refactor: Adjust how command is invoked
This commit is contained in:
parent
04472f8bfa
commit
a62d86563a
6 changed files with 57 additions and 35 deletions
|
@ -6,7 +6,7 @@ import io.github.null2264.tsukumogami.core.module.api.botModules
|
|||
import kotlinx.datetime.Clock
|
||||
|
||||
val generalModule = botModules("General") {
|
||||
commands("ping", description = "Ping the bot!") { ctx ->
|
||||
commands("ping", alias = setOf("p"), description = "Ping the bot!") { ctx ->
|
||||
val startTime = Clock.System.now()
|
||||
ctx.typing()
|
||||
val endTime = Clock.System.now()
|
||||
|
|
|
@ -34,18 +34,28 @@ open class Bot internal constructor(): IGroup {
|
|||
_prefixes.add(prefix)
|
||||
}
|
||||
|
||||
fun addCommand(command: Command) {
|
||||
if (allCommands.containsKey(command.name)) {
|
||||
private fun addCommand(name: String, command: Command) {
|
||||
if (allCommands.containsKey(name)) {
|
||||
throw IllegalStateException("Duplicate command: '${command.name}'")
|
||||
}
|
||||
allCommands[command.name] = command
|
||||
}
|
||||
|
||||
fun removeCommand(command: Command) {
|
||||
if (!allCommands.containsKey(command.name)) {
|
||||
throw IllegalStateException("Command not found: '${command.name}'")
|
||||
fun addCommand(command: Command) {
|
||||
addCommand(command.name, command)
|
||||
command.alias.forEach { addCommand(it, command) }
|
||||
}
|
||||
|
||||
private fun removeCommand(name: String) {
|
||||
if (!allCommands.containsKey(name)) {
|
||||
throw IllegalStateException("Command not found: '${name}'")
|
||||
}
|
||||
allCommands.remove(command.name)
|
||||
allCommands.remove(name)
|
||||
}
|
||||
|
||||
fun removeCommand(command: Command) {
|
||||
removeCommand(command.name)
|
||||
command.alias.forEach { removeCommand(it) }
|
||||
}
|
||||
|
||||
open suspend fun start() {
|
||||
|
@ -67,9 +77,10 @@ open class Bot internal constructor(): IGroup {
|
|||
fun getCommand(name: String?) = allCommands[name]
|
||||
|
||||
private fun getContext(message: Message): Context {
|
||||
val candidate = message.content.parsePrefixCommandAndArguments()
|
||||
val context = Context(this, message, candidate?.first, candidate?.second?.toMutableList())
|
||||
context.command = getCommand(context.pullCandidateOrNull())
|
||||
val parsed = message.content.parsePrefixAndCommand()
|
||||
val context = Context(this, message, parsed?.first)
|
||||
context.command = getCommand(parsed?.second)
|
||||
if (context.command != null) context.invokedWith = parsed?.second
|
||||
return context
|
||||
}
|
||||
|
||||
|
@ -99,17 +110,18 @@ open class Bot internal constructor(): IGroup {
|
|||
Logger.i { "Online! ${client.getSelf().username}" }
|
||||
}
|
||||
|
||||
private fun String.parsePrefixCommandAndArguments(): Pair<String, List<String>>? {
|
||||
private fun String.parsePrefixAndCommand(): Pair<String, String>? {
|
||||
if (this.isBlank()) return null
|
||||
|
||||
var ret: Pair<String, List<String>>? = null
|
||||
var ret: Pair<String, String>? = null
|
||||
|
||||
prefixes.forEach {
|
||||
if (this.substring(0, it.length) == it) {
|
||||
val prefix = this.substring(0, it.length)
|
||||
val cleanPrompt = this.substring(it.length)
|
||||
ret = Pair(prefix, cleanPrompt.parseCommandAndArguments())
|
||||
return@forEach
|
||||
run {
|
||||
prefixes.forEach { candidate ->
|
||||
val prefix = this.substring(0, candidate.length)
|
||||
if (prefix != candidate) { return@forEach }
|
||||
val command = this.drop(candidate.length).substringBefore(' ')
|
||||
ret = prefix to command
|
||||
return@run
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,34 +8,30 @@ import io.github.null2264.tsukumogami.core.commands.Command
|
|||
|
||||
class Context(
|
||||
val bot: Bot,
|
||||
private val message: Message,
|
||||
val message: Message,
|
||||
/**
|
||||
* The prefix that used to invoke the command
|
||||
*/
|
||||
val prefix: String?,
|
||||
/**
|
||||
* Potential command name and/or arguments
|
||||
*/
|
||||
val candidate: MutableList<String>?,
|
||||
) {
|
||||
|
||||
/**
|
||||
* The user that invoked the command
|
||||
*
|
||||
* Alias to [Message.author]
|
||||
*/
|
||||
val author get() = message.author
|
||||
|
||||
/**
|
||||
* The text that invoked the command
|
||||
*/
|
||||
var invokedWith: String? = null
|
||||
|
||||
/**
|
||||
* The command that currently being invoked
|
||||
*/
|
||||
var command: Command? = null
|
||||
|
||||
fun getCandidateOrNull() = candidate?.getOrNull(0)
|
||||
fun pullCandidateOrNull() = candidate?.removeFirstOrNull()
|
||||
fun pullCandidateIf(predicate: () -> Boolean): String? {
|
||||
if (predicate()) return candidate?.removeFirstOrNull()
|
||||
return null
|
||||
}
|
||||
|
||||
suspend fun send(content: String) = message.channel.createMessage(content)
|
||||
|
||||
suspend fun reply(content: String, mentionsAuthor: Boolean = false) = message.channel.createMessage {
|
||||
|
@ -48,4 +44,15 @@ class Context(
|
|||
}
|
||||
|
||||
suspend fun typing() = message.channel.type()
|
||||
|
||||
fun parseArguments(): MutableList<String>? =
|
||||
if (prefix != null && invokedWith != null) {
|
||||
message.content
|
||||
.substringAfter("$prefix$invokedWith")
|
||||
.trim()
|
||||
.split(' ')
|
||||
.toMutableList()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ abstract class Arguments {
|
|||
}
|
||||
|
||||
suspend fun parse(context: Context) {
|
||||
val currentValues = context.candidate?.toMutableList()
|
||||
val currentValues = context.parseArguments()
|
||||
|
||||
run {
|
||||
args.forEach { arg ->
|
||||
|
|
|
@ -19,9 +19,13 @@ class Group(
|
|||
override val allCommands: MutableMap<String, Command> = mutableMapOf()
|
||||
|
||||
override suspend fun invoke(context: Context) {
|
||||
val command = allCommands[context.getCandidateOrNull()]
|
||||
context.pullCandidateIf { command != null } ?: return
|
||||
context.command = command!!
|
||||
val subcommandName = context.message.content
|
||||
.substringAfter("${context.prefix}${context.invokedWith}")
|
||||
.trim()
|
||||
.substringBefore(' ')
|
||||
val command = allCommands[subcommandName] ?: return
|
||||
context.invokedWith += " $subcommandName"
|
||||
context.command = command
|
||||
command.invoke(context)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ interface IGroup {
|
|||
|
||||
private fun addCommand(command: Command) {
|
||||
allCommands[command.name] = command
|
||||
command.alias.forEach { allCommands[it] = command }
|
||||
}
|
||||
|
||||
fun commands(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue