289 lines
8.7 KiB
Kotlin
289 lines
8.7 KiB
Kotlin
package nl.voidcorp.dbot.commands
|
|
|
|
import com.github.salomonbrys.kotson.fromJson
|
|
import com.jagrosh.jdautilities.command.*
|
|
import net.dv8tion.jda.core.EmbedBuilder
|
|
import net.dv8tion.jda.core.OnlineStatus
|
|
import net.dv8tion.jda.core.entities.ChannelType
|
|
import net.dv8tion.jda.core.entities.Game
|
|
import net.dv8tion.jda.core.entities.Guild
|
|
import net.dv8tion.jda.core.entities.Message
|
|
import net.dv8tion.jda.core.events.ReadyEvent
|
|
import net.dv8tion.jda.core.events.message.MessageReceivedEvent
|
|
import net.dv8tion.jda.core.hooks.ListenerAdapter
|
|
import nl.voidcorp.dbot.bot
|
|
import nl.voidcorp.dbot.gson
|
|
import nl.voidcorp.dbot.log
|
|
import nl.voidcorp.dbot.storage.GuildSettings
|
|
import java.io.File
|
|
import java.time.LocalDateTime
|
|
import java.time.OffsetDateTime
|
|
import java.util.*
|
|
import java.util.concurrent.ScheduledExecutorService
|
|
import java.util.concurrent.ScheduledThreadPoolExecutor
|
|
import java.util.function.Function
|
|
|
|
|
|
val gmap = mutableMapOf<Long, GuildSettings>()
|
|
|
|
object GSM : GuildSettingsManager<GuildSettings> {
|
|
private val f = File("settings.json")
|
|
|
|
override fun getSettings(it: Guild): GuildSettings {
|
|
val res = gmap[it.idLong]
|
|
return if (res != null) {
|
|
res
|
|
} else {
|
|
val gm = GuildSettings()
|
|
gmap[it.idLong] = gm
|
|
gm
|
|
}
|
|
}
|
|
|
|
override fun init() {
|
|
if (f.exists()) {
|
|
gmap.putAll(gson.fromJson(f.readText()))
|
|
}
|
|
}
|
|
|
|
override fun shutdown() {
|
|
gson.toJson(gmap, f.bufferedWriter())
|
|
}
|
|
}
|
|
|
|
data class UnityCommandClient(private val prefix: String,
|
|
private val commands: MutableList<Command> = mutableListOf()
|
|
) : CommandClient, ListenerAdapter() {
|
|
private val cooldownMap = mutableMapOf<String, OffsetDateTime>()
|
|
override fun applyCooldown(name: String, seconds: Int) {
|
|
cooldownMap[name] = OffsetDateTime.now().plusSeconds(seconds.toLong())
|
|
}
|
|
|
|
override fun <M : GuildSettingsManager<*>> getSettingsManager(): M? {
|
|
return null
|
|
}
|
|
|
|
override fun getError(): String = "❌"
|
|
|
|
override fun addAnnotatedModule(module: Any?) {
|
|
//NOP
|
|
}
|
|
|
|
override fun addAnnotatedModule(module: Any?, mapFunction: Function<Command, Int>?) {
|
|
//NOP
|
|
}
|
|
|
|
override fun getServerInvite(): String? {
|
|
return null
|
|
}
|
|
|
|
private val ses = ScheduledThreadPoolExecutor(8)
|
|
|
|
override fun getScheduleExecutor(): ScheduledExecutorService = ses
|
|
|
|
override fun cleanCooldowns() {
|
|
for ((k, v) in cooldownMap) {
|
|
if (v.isBefore(OffsetDateTime.now())) {
|
|
cooldownMap.remove(k)
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun getWarning(): String = "⚠️"
|
|
|
|
override fun addCommand(command: Command) {
|
|
commands.add(command)
|
|
}
|
|
|
|
override fun addCommand(command: Command, index: Int) {
|
|
commands.add(index, command)
|
|
}
|
|
|
|
fun <T : Command> addCommands(commands: List<T>) {
|
|
for (c in commands) {
|
|
addCommand(c)
|
|
}
|
|
}
|
|
|
|
override fun <S : Any> getSettingsFor(guild: Guild): S? = null
|
|
|
|
private fun getSettings(guild: Guild): GuildSettings = GSM.getSettings(guild)
|
|
|
|
private var cmdListener: CommandListener? = null
|
|
override fun setListener(listener: CommandListener) {
|
|
cmdListener = listener
|
|
}
|
|
|
|
private val start = OffsetDateTime.now()
|
|
override fun getStartTime(): OffsetDateTime = start
|
|
|
|
|
|
override fun getListener(): CommandListener? = cmdListener
|
|
|
|
override fun getSuccess(): String = "✔️"
|
|
|
|
private val usageMap = mutableMapOf<String, Int>()
|
|
|
|
override fun getCommandUses(command: Command): Int = usageMap[command.name] ?: 0
|
|
|
|
private operator fun <T> MutableMap<T, Int>.plus(t: T) {
|
|
val res = this[t]
|
|
if (res != null) {
|
|
this[t] = res + 1
|
|
} else {
|
|
this[t] = 1
|
|
}
|
|
}
|
|
|
|
override fun getCommandUses(name: String): Int = usageMap[name] ?: 0
|
|
|
|
|
|
override fun getCooldown(name: String): OffsetDateTime? = cooldownMap[name]
|
|
|
|
|
|
override fun getHelpWord(): String = "help"
|
|
|
|
override fun shutdown() {
|
|
ses.shutdown()
|
|
GSM.shutdown()
|
|
}
|
|
|
|
override fun removeCommand(name: String) {
|
|
commands.removeIf { it.name == name }
|
|
}
|
|
|
|
override fun usesLinkedDeletion(): Boolean = false
|
|
|
|
override fun getTextualPrefix(): String = prefix
|
|
|
|
override fun getTotalGuilds(): Int = bot.guilds.size
|
|
|
|
override fun getRemainingCooldown(name: String): Int {
|
|
val cd = cooldownMap[name]
|
|
return if (cd == null) {
|
|
0
|
|
} else {
|
|
(OffsetDateTime.now().toEpochSecond() - cd.toEpochSecond()).toInt()
|
|
}
|
|
|
|
}
|
|
|
|
override fun getCoOwnerIds(): Array<String> {
|
|
return arrayOf()
|
|
}
|
|
|
|
override fun getAltPrefix(): String? = null
|
|
|
|
|
|
override fun getPrefix(): String = prefix
|
|
|
|
override fun getCommands(): MutableList<Command> = commands
|
|
|
|
override fun getCoOwnerIdsLong(): LongArray = coOwnerIds.toList().map { it.toLong() }.toLongArray()
|
|
|
|
override fun getOwnerId(): String = "168743656738521088"
|
|
override fun getOwnerIdLong(): Long = ownerId.toLong()
|
|
|
|
private fun splitOnPrefixLength(rawContent: String, length: Int): Array<String?> {
|
|
return Arrays.copyOf(rawContent.substring(length).trim { it <= ' ' }.split("\\s+".toRegex(), 2).toTypedArray(), 2)
|
|
}
|
|
|
|
|
|
var unknownCommandHandler: (MessageReceivedEvent, String?) -> Unit = { event, command ->
|
|
val eb = EmbedBuilder().setTitle("Something went wrong...")
|
|
.addField("Unknown command: `$command`", "I don't know this command...", false)
|
|
.setColor(event.guild.selfMember.color).setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl).setTimestamp(LocalDateTime.now())
|
|
event.textChannel.sendMessage(eb.build()).queue()
|
|
}
|
|
|
|
override fun onMessageReceived(event: MessageReceivedEvent) {
|
|
if (event.author.isBot)
|
|
return
|
|
|
|
var parts: Array<String?>? = null
|
|
val rawContent = event.message.contentRaw
|
|
|
|
val settings = getSettings(event.guild)
|
|
|
|
|
|
//Check for mention
|
|
if (settings.prefixes.isEmpty()) {
|
|
if (rawContent.startsWith("<@" + event.jda.selfUser.id + ">") || rawContent.startsWith("<@!" + event.jda.selfUser.id + ">")) {
|
|
parts = splitOnPrefixLength(rawContent, rawContent.indexOf(">") + 1)
|
|
}
|
|
}
|
|
|
|
//check for default prefix if not overridden
|
|
if (rawContent.startsWith(prefix) and settings.prefixes.isEmpty())
|
|
parts = splitOnPrefixLength(rawContent, rawContent.indexOf(prefix))
|
|
|
|
// Check for guild specific prefixes
|
|
if (parts == null) {
|
|
val prefixes = settings.getPrefixes()
|
|
for (prefix in prefixes) {
|
|
if (parts == null && rawContent.toLowerCase().startsWith(prefix.toLowerCase()))
|
|
parts = splitOnPrefixLength(rawContent, prefix.length)
|
|
}
|
|
}
|
|
|
|
if (parts != null)
|
|
//starts with valid prefix
|
|
{
|
|
|
|
if ((event.channel.type == ChannelType.PRIVATE) or event.textChannel.canTalk()) {
|
|
val name = parts[0]
|
|
val args = if (parts[1] == null) "" else parts[1]
|
|
var command: Command? // this will be null if it's not a command
|
|
command = commands.firstOrNull { it.name == name }
|
|
if (command == null) {
|
|
command = commands.firstOrNull { name in it.aliases }
|
|
}
|
|
|
|
|
|
if (command != null) {
|
|
val cevent = CommandEventOverride(event, args, this)
|
|
|
|
if (cmdListener != null)
|
|
cmdListener!!.onCommand(cevent, command)
|
|
usageMap + command.name
|
|
command.run(cevent)
|
|
return // Command is done
|
|
} else {
|
|
unknownCommandHandler(event, name)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private val status = OnlineStatus.ONLINE
|
|
var version = "?.?"
|
|
|
|
private val game = Game.watching("fraud and \uD83C\uDFB5 (v$version)")
|
|
|
|
override fun onReady(event: ReadyEvent) {
|
|
|
|
if (!event.jda.selfUser.isBot) {
|
|
log.error("This bot can't run as a client!")
|
|
return
|
|
}
|
|
event.jda.presence.setPresence(status,
|
|
when {
|
|
game == null -> null
|
|
"default" == game.name -> Game.playing("Type ${prefix}help")
|
|
else -> game
|
|
})
|
|
|
|
// Start SettingsManager if necessary
|
|
GSM.init()
|
|
}
|
|
|
|
|
|
}
|
|
|
|
class CommandEventOverride(event: MessageReceivedEvent, args: String?, client: UnityCommandClient) : CommandEvent(event, args, client) {
|
|
override fun linkId(message: Message?) {
|
|
|
|
}
|
|
} |