125 lines
4.6 KiB
Kotlin
125 lines
4.6 KiB
Kotlin
package nl.voidcorp.discord.command
|
|
|
|
import net.dv8tion.jda.api.Permission
|
|
import net.dv8tion.jda.api.entities.ChannelType
|
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
|
|
import java.util.*
|
|
|
|
|
|
abstract class Command(
|
|
val name: String,
|
|
val helpMesage: String = "",
|
|
val usage: String = "",
|
|
val aliases: List<String> = emptyList(),
|
|
val location: CommandSource = CommandSource.BOTH,
|
|
val permissions: Set<Permission> = emptySet()
|
|
) {
|
|
|
|
fun onCommand(event: MessageReceivedEvent, prefix: String): CommandResult {
|
|
val starts =
|
|
event.message.contentRaw.drop(prefix.length).trim()
|
|
.startsWith(name) or aliases.any {
|
|
event.message.contentRaw.drop(prefix.length).trim().startsWith(
|
|
it
|
|
)
|
|
}
|
|
return if (!starts) CommandResult.NOPE else when (location) {
|
|
CommandSource.PRIVATE -> if (event.channelType == ChannelType.PRIVATE) guildStuff(
|
|
event,
|
|
event.message.contentRaw.drop(prefix.length).trim()
|
|
) else CommandResult.NOPE
|
|
CommandSource.GUILD -> if (event.channelType == ChannelType.TEXT) privateStuff(
|
|
event,
|
|
event.message.contentRaw.drop(prefix.length).trim()
|
|
) else CommandResult.NOPE
|
|
CommandSource.BOTH ->
|
|
if (event.channelType == ChannelType.PRIVATE) guildStuff(
|
|
event,
|
|
event.message.contentRaw.drop(prefix.length).trim()
|
|
)
|
|
else privateStuff(event, event.message.contentRaw.drop(prefix.length).trim())
|
|
}
|
|
}
|
|
|
|
private fun guildStuff(event: MessageReceivedEvent, str: String): CommandResult {
|
|
val intersect = permissions.intersect(event.member?.permissions as Iterable<Permission>)
|
|
return if ((intersect.isNotEmpty() or permissions.isEmpty())) {
|
|
handle(CommandMessage(event, translateCommandline(str)))
|
|
} else CommandResult.PERMISSIONS
|
|
}
|
|
|
|
private fun privateStuff(event: MessageReceivedEvent, str: String): CommandResult {
|
|
return handle(CommandMessage(event, translateCommandline(str)))
|
|
}
|
|
|
|
abstract fun handle(event: CommandMessage): CommandResult
|
|
|
|
|
|
companion object {
|
|
var settings = CommandSettings()
|
|
|
|
|
|
/**
|
|
* [code borrowed from ant.jar]
|
|
* Crack a command line.
|
|
* @param toProcess the command line to process.
|
|
* @return the command line broken into strings.
|
|
* An empty or null toProcess parameter results in a zero sized array.
|
|
*/
|
|
private fun translateCommandline(toProcess: String): List<String> {
|
|
if (toProcess.isEmpty()) {
|
|
//no command? no string
|
|
return emptyList()
|
|
}
|
|
// parse with a simple finite state machine
|
|
|
|
val normal = 0
|
|
val inQuote = 1
|
|
val inDoubleQuote = 2
|
|
var state = normal
|
|
val tok = StringTokenizer(toProcess, "\"\' ", true)
|
|
val result = mutableListOf<String>()
|
|
val current = StringBuilder()
|
|
var lastTokenHasBeenQuoted = false
|
|
|
|
while (tok.hasMoreTokens()) {
|
|
val nextTok = tok.nextToken()
|
|
when (state) {
|
|
inQuote -> if ("\'" == nextTok) {
|
|
lastTokenHasBeenQuoted = true
|
|
state = normal
|
|
} else {
|
|
current.append(nextTok)
|
|
}
|
|
inDoubleQuote -> if ("\"" == nextTok) {
|
|
lastTokenHasBeenQuoted = true
|
|
state = normal
|
|
} else {
|
|
current.append(nextTok)
|
|
}
|
|
else -> {
|
|
if ("\'" == nextTok) {
|
|
state = inQuote
|
|
} else if ("\"" == nextTok) {
|
|
state = inDoubleQuote
|
|
} else if (" " == nextTok) {
|
|
if (lastTokenHasBeenQuoted || current.isNotEmpty()) {
|
|
result.add(current.toString())
|
|
current.setLength(0)
|
|
}
|
|
} else {
|
|
current.append(nextTok)
|
|
}
|
|
lastTokenHasBeenQuoted = false
|
|
}
|
|
}
|
|
}
|
|
if (lastTokenHasBeenQuoted || current.isNotEmpty()) {
|
|
result.add(current.toString())
|
|
}
|
|
return result
|
|
}
|
|
|
|
|
|
}
|
|
} |