Righto, like 7 updates in one commit
Moved categories around a bit Moved help command Added custom command client Began per guild settings stuff Added :fr00d: emoji on code blocks Incremented version
This commit is contained in:
parent
ff29659882
commit
784aa3617d
|
@ -7,7 +7,7 @@ import net.dv8tion.jda.core.hooks.ListenerAdapter
|
||||||
|
|
||||||
object Events : ListenerAdapter() {
|
object Events : ListenerAdapter() {
|
||||||
override fun onMessageReceived(event: MessageReceivedEvent) {
|
override fun onMessageReceived(event: MessageReceivedEvent) {
|
||||||
if (event.message.contentStripped.toLowerCase().contains("fraud")) {
|
if (event.message.contentStripped.toLowerCase().contains("fraud") or event.message.contentRaw.contains(Regex("`(\\w+|\\s+|\\W)+`"))) {
|
||||||
val e = event.message.guild.getEmotesByName("fr00d", true).firstOrNull()
|
val e = event.message.guild.getEmotesByName("fr00d", true).firstOrNull()
|
||||||
if (e != null)
|
if (e != null)
|
||||||
event.message.addReaction(e).queue()
|
event.message.addReaction(e).queue()
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package nl.voidcorp.dbot
|
package nl.voidcorp.dbot
|
||||||
|
|
||||||
import com.jagrosh.jdautilities.command.CommandClientBuilder
|
|
||||||
import com.jagrosh.jdautilities.command.CommandListener
|
|
||||||
import com.sedmelluq.discord.lavaplayer.jdaudp.NativeAudioSendFactory
|
import com.sedmelluq.discord.lavaplayer.jdaudp.NativeAudioSendFactory
|
||||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager
|
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager
|
||||||
import com.sedmelluq.discord.lavaplayer.source.soundcloud.SoundCloudAudioSourceManager
|
import com.sedmelluq.discord.lavaplayer.source.soundcloud.SoundCloudAudioSourceManager
|
||||||
|
@ -13,21 +11,17 @@ import io.javalin.json.ToJsonMapper
|
||||||
import net.dv8tion.jda.core.EmbedBuilder
|
import net.dv8tion.jda.core.EmbedBuilder
|
||||||
import net.dv8tion.jda.core.JDA
|
import net.dv8tion.jda.core.JDA
|
||||||
import net.dv8tion.jda.core.JDABuilder
|
import net.dv8tion.jda.core.JDABuilder
|
||||||
import net.dv8tion.jda.core.entities.Game
|
|
||||||
import net.dv8tion.jda.core.entities.MessageEmbed
|
|
||||||
import net.dv8tion.jda.core.events.message.MessageReceivedEvent
|
|
||||||
import net.dv8tion.jda.webhook.WebhookClient
|
import net.dv8tion.jda.webhook.WebhookClient
|
||||||
import net.dv8tion.jda.webhook.WebhookClientBuilder
|
import net.dv8tion.jda.webhook.WebhookClientBuilder
|
||||||
import nl.voidcorp.dbot.commands.*
|
import nl.voidcorp.dbot.commands.*
|
||||||
|
import nl.voidcorp.dbot.music.initMusic
|
||||||
import nl.voidcorp.dbot.storage.GitlabWebhook
|
import nl.voidcorp.dbot.storage.GitlabWebhook
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileReader
|
import java.io.FileReader
|
||||||
import java.time.LocalDateTime
|
|
||||||
|
|
||||||
val playerManager = DefaultAudioPlayerManager()
|
val playerManager = DefaultAudioPlayerManager()
|
||||||
|
|
||||||
val cb = CommandClientBuilder()
|
|
||||||
|
|
||||||
val log = LoggerFactory.getLogger("UnityBot")
|
val log = LoggerFactory.getLogger("UnityBot")
|
||||||
|
|
||||||
|
@ -90,72 +84,27 @@ fun main(args: Array<String>) {
|
||||||
ctx.status(200).result("OK")
|
ctx.status(200).result("OK")
|
||||||
}
|
}
|
||||||
|
|
||||||
cb.setOwnerId("168743656738521088")
|
|
||||||
cb.setPrefix("!")
|
|
||||||
cb.setAlternativePrefix("+")
|
|
||||||
commands.addAll(helloCommand, pingCommand)
|
|
||||||
cb.setGame(Game.watching("fraud and \uD83C\uDFB5 (v1.3)"))
|
|
||||||
|
|
||||||
val replies = listOf("Hello %%", "Why hello there %%!", "Hello there %%", "General %%. You are a bold one", "A wild %% appeared!")
|
|
||||||
cb.setHelpConsumer { event ->
|
|
||||||
val greeting = replies.random().replace("%%", event.member.effectiveName)
|
|
||||||
val eb = EmbedBuilder()
|
|
||||||
when {
|
|
||||||
event.args.isEmpty() -> {
|
|
||||||
eb.setTitle(greeting)
|
|
||||||
.appendDescription("My name is ${event.selfMember.effectiveName}, and I am definitely the best Discord bot around!\n\nUse `!help command` for a chance that I have more info about a command!")
|
|
||||||
.setColor(event.selfMember.color).setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl).setTimestamp(LocalDateTime.now())
|
|
||||||
val m = commands.catMap()
|
|
||||||
for (e in m.entries) {
|
|
||||||
|
|
||||||
val f = MessageEmbed.Field(e.key, e.value.joinToString(separator = "\n", postfix = "\n") { "`!${it.name}`" }, true)
|
commands.addAll(helloCommand, pingCommand, helpCommand)
|
||||||
eb.addField(f)
|
|
||||||
}
|
|
||||||
eb.setThumbnail(event.selfUser.effectiveAvatarUrl)
|
|
||||||
}
|
|
||||||
commands.any { it.name == event.args } -> {
|
|
||||||
val cmd = commands.first { it.name == event.args }
|
|
||||||
eb.setTitle("**!${cmd.name}**")
|
|
||||||
.appendDescription(cmd.help)
|
|
||||||
.setColor(event.selfMember.color).setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl).setTimestamp(LocalDateTime.now())
|
|
||||||
if (cmd.aliases.isNotEmpty()) eb.addField("Aliases", cmd.aliases.joinToString { "`$it`" }, false)
|
|
||||||
eb.addField("Usage", "`!${cmd.howTo.emptyOr(cmd.name)}`", false)
|
|
||||||
|
|
||||||
}
|
|
||||||
event.args == "help" -> {
|
|
||||||
eb.setTitle(greeting)
|
|
||||||
.appendDescription("Haha, very funny ${event.member.effectiveName}")
|
|
||||||
.setColor(event.selfMember.color).setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl).setTimestamp(LocalDateTime.now())
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
eb.setTitle(greeting)
|
|
||||||
.appendDescription("I honestly have no idea what the command `${event.args}` does...")
|
|
||||||
.setColor(event.selfMember.color).setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl).setTimestamp(LocalDateTime.now())
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
event.reply(eb.build())
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
initMusic()
|
initMusic()
|
||||||
initFun()
|
initFun()
|
||||||
cb.setListener(object : CommandListener {
|
|
||||||
override fun onNonCommandMessage(event: MessageReceivedEvent) {
|
|
||||||
val msg = event.message.contentRaw
|
|
||||||
if (msg.startsWith('!') or msg.startsWith('+')) {
|
|
||||||
val eb = EmbedBuilder().setTitle("Something went wrong...")
|
|
||||||
.addField("Unknown command: `${msg.substring(1)}`", "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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
cb.addCommands(*commands.toTypedArray())
|
val custom = UnityCommandClient("!")
|
||||||
val client = cb.build()
|
custom.addCommands(commands)
|
||||||
bot = JDABuilder(args[0]).addEventListener(client).addEventListener(nl.voidcorp.dbot.Events).setAudioSendFactory(NativeAudioSendFactory()).build()
|
custom.version = "1.4"
|
||||||
|
|
||||||
|
|
||||||
|
bot = JDABuilder(args[0]).addEventListener(custom).addEventListener(nl.voidcorp.dbot.Events).setAudioSendFactory(NativeAudioSendFactory()).build()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var bot: JDA
|
lateinit var bot: JDA
|
||||||
|
|
109
src/main/kotlin/nl/voidcorp/dbot/commands/Categories.kt
Normal file
109
src/main/kotlin/nl/voidcorp/dbot/commands/Categories.kt
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
package nl.voidcorp.dbot.commands
|
||||||
|
|
||||||
|
import com.jagrosh.jdautilities.command.Command
|
||||||
|
import com.jagrosh.jdautilities.command.CommandEvent
|
||||||
|
import net.dv8tion.jda.core.entities.ChannelType
|
||||||
|
import net.dv8tion.jda.core.entities.TextChannel
|
||||||
|
|
||||||
|
open class UnityCategory(name: String,
|
||||||
|
val channels: List<String> = listOf("bot"), val roles: List<String> = listOf(),
|
||||||
|
val errorMessage: (TextChannel) -> String = { "This command can only be used in ${it.asMention}." },
|
||||||
|
val check: (CommandEvent) -> Boolean = { true }) : Command.Category(name) {
|
||||||
|
override fun test(ce: CommandEvent): Boolean {
|
||||||
|
/*if (ce.member.hasPermission(Permission.ADMINISTRATOR)) return true*/
|
||||||
|
if (ce.member.roles.firstOrNull { it.name.equals("admin", true) } != null) return true
|
||||||
|
if (channels.all { ce.guild.getTextChannelsByName(it, true).firstOrNull() == null }) return true
|
||||||
|
if (channels.isEmpty()) return true
|
||||||
|
|
||||||
|
lateinit var ch: TextChannel
|
||||||
|
for (channel in channels.map { ce.guild.getTextChannelsByName(it, true).firstOrNull() }) {
|
||||||
|
if (channel != null) {
|
||||||
|
ch = channel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return if (ce.channelType == ChannelType.PRIVATE) {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
if (ce.textChannel != ch) {
|
||||||
|
ce.reply(errorMessage(ch))
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
if (roles.isNotEmpty()) {
|
||||||
|
val rnames = ce.member.roles.map { it.name }
|
||||||
|
if (roles.intersect(rnames).isEmpty()) {
|
||||||
|
ce.reply("You need one of these roles to execute this command: ${roles.joinToString { "`$it`" }}")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
check(ce)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
val test = ce.textChannel.name.contains("bot")
|
||||||
|
if (!test) {
|
||||||
|
ce.reply("Non music commands can only be used in the ${ce.guild.getTextChannelsByName("bot", true).first().asMention} channel")
|
||||||
|
}
|
||||||
|
|
||||||
|
return test and check(ce)*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object GeneralCategory : UnityCategory("general")
|
||||||
|
|
||||||
|
/*val MusicCategory = Command.Category("Music Commands") { ce ->
|
||||||
|
if (ce.member.roles.firstOrNull { it.name.equals("admin", true) } != null) return@Category true
|
||||||
|
|
||||||
|
val botExists = ce.guild.getTextChannelsByName("bot", true).firstOrNull() != null
|
||||||
|
val musicExists = ce.guild.getTextChannelsByName("music", true).firstOrNull() != null
|
||||||
|
val musicBotExists = ce.guild.getTextChannelsByName("music-bot", true).firstOrNull() != null
|
||||||
|
when {
|
||||||
|
musicBotExists -> {
|
||||||
|
val res = ce.textChannel.name == "music-bot"
|
||||||
|
|
||||||
|
if (!res) ce.reply("Music commands are only supported in the ${ce.guild.getTextChannelsByName("music-bot", true).first().asMention} channel!")
|
||||||
|
res
|
||||||
|
}
|
||||||
|
musicExists -> {
|
||||||
|
val res = ce.textChannel.name == "music"
|
||||||
|
if (!res) ce.reply("Music commands are only supported in the ${ce.guild.getTextChannelsByName("music", true).first().asMention} channel!")
|
||||||
|
res
|
||||||
|
}
|
||||||
|
botExists -> {
|
||||||
|
val res = ce.textChannel.name == "bot"
|
||||||
|
if (!res) ce.reply("Music commands are only supported in the ${ce.guild.getTextChannelsByName("bot", true).first().asMention} channel!")
|
||||||
|
res
|
||||||
|
}
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
object MusicCategory : UnityCategory("Music Commands", listOf("bot", "music", "music-bot"), errorMessage = { "Music commands can only be used in ${it.asMention}!" })
|
||||||
|
object MusicCategoryPrivate : UnityCategory("Music Commands", listOf("bot", "music", "music-bot"), listOf("admin"), { "Music commands can only be used in ${it.asMention}!" })
|
||||||
|
|
||||||
|
/*
|
||||||
|
val GeneralCategory = Command.Category("General commands") { ce ->
|
||||||
|
if (ce.member.roles.firstOrNull { it.name.equals("admin", true) } != null) return@Category true
|
||||||
|
if (ce.guild.getTextChannelsByName("bot", true).firstOrNull() == null) return@Category true
|
||||||
|
val test = ce.textChannel.name.contains("bot")
|
||||||
|
if (!test) {
|
||||||
|
ce.reply("Non music commands can only be used in the ${ce.guild.getTextChannelsByName("bot", true).first().asMention} channel")
|
||||||
|
}
|
||||||
|
|
||||||
|
test
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
/*val FunCategory = Command.Category("Fun Commands") { ce ->
|
||||||
|
if (ce.member.roles.firstOrNull { it.name.equals("admin", true) } != null) return@Category true
|
||||||
|
|
||||||
|
if (ce.guild.getTextChannelsByName("bot", true).firstOrNull() == null) return@Category true
|
||||||
|
val test = ce.textChannel.name.contains("bot")
|
||||||
|
if (!test) {
|
||||||
|
ce.reply("Non music commands can only be used in the ${ce.guild.getTextChannelsByName("bot", true).first().asMention} channel")
|
||||||
|
}
|
||||||
|
|
||||||
|
test
|
||||||
|
}*/
|
||||||
|
|
||||||
|
object FunCategory : UnityCategory("Fun commands")
|
|
@ -1,6 +1,13 @@
|
||||||
package nl.voidcorp.dbot.commands
|
package nl.voidcorp.dbot.commands
|
||||||
|
|
||||||
|
import net.dv8tion.jda.core.EmbedBuilder
|
||||||
import net.dv8tion.jda.core.MessageBuilder
|
import net.dv8tion.jda.core.MessageBuilder
|
||||||
|
import net.dv8tion.jda.core.entities.MessageEmbed
|
||||||
|
import nl.voidcorp.dbot.catMap
|
||||||
|
import nl.voidcorp.dbot.commands
|
||||||
|
import nl.voidcorp.dbot.emptyOr
|
||||||
|
import nl.voidcorp.dbot.random
|
||||||
|
import java.time.LocalDateTime
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,4 +22,51 @@ val pingCommand = UnityCommand("ping", help = "Check the bot's ping", aliases =
|
||||||
m.editMessage("Ping: " + ping + "ms | Websocket: " + event.jda.ping + "ms").queue()
|
m.editMessage("Ping: " + ping + "ms | Websocket: " + event.jda.ping + "ms").queue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val replies = listOf("Hello %%", "Why hello there %%!", "Hello there %%", "General %%. You are a bold one", "A wild %% appeared!")
|
||||||
|
|
||||||
|
val helpCommand = UnityCommand("help", "Guess what?"/*, category = UnityCategory("Yeet", channels = listOf())*/) { event ->
|
||||||
|
val greeting = replies.random().replace("%%", event.member.effectiveName)
|
||||||
|
val eb = EmbedBuilder()
|
||||||
|
when {
|
||||||
|
event.args.isEmpty() -> {
|
||||||
|
eb.setTitle(greeting)
|
||||||
|
.appendDescription("My name is ${event.selfMember.effectiveName}, and I am definitely the best Discord bot around!\n\nUse `!help command` for a chance that I have more info about a command!")
|
||||||
|
.setColor(event.selfMember.color).setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl).setTimestamp(LocalDateTime.now())
|
||||||
|
val m = commands.catMap()
|
||||||
|
for (e in m.entries) {
|
||||||
|
val f = MessageEmbed.Field(e.key, e.value.asSequence().filter { it.name != "help" }.joinToString(separator = "\n", postfix = "\n") { "`!${it.name}`" }, true)
|
||||||
|
eb.addField(f)
|
||||||
|
}
|
||||||
|
eb.setThumbnail(event.selfUser.effectiveAvatarUrl)
|
||||||
|
}
|
||||||
|
event.args == "help" -> {
|
||||||
|
eb.setTitle("Ha Ha")
|
||||||
|
.appendDescription("Ha ha, very funny ${event.member.effectiveName}")
|
||||||
|
.setColor(event.selfMember.color).setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl).setTimestamp(LocalDateTime.now())
|
||||||
|
}
|
||||||
|
commands.any { it.name == event.args } -> {
|
||||||
|
val cmd = commands.first { it.name == event.args }
|
||||||
|
eb.setTitle("**!${cmd.name}**")
|
||||||
|
.appendDescription(cmd.help)
|
||||||
|
.setColor(event.selfMember.color).setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl).setTimestamp(LocalDateTime.now())
|
||||||
|
if (cmd.aliases.isNotEmpty()) eb.addField("Aliases", cmd.aliases.joinToString { "`$it`" }, true)
|
||||||
|
eb.addField("Usage", "`!${cmd.howTo.emptyOr(cmd.name)}`", true)
|
||||||
|
val cat = cmd.category
|
||||||
|
if (cat is UnityCategory) {
|
||||||
|
if (cat.roles.isNotEmpty())
|
||||||
|
eb.addField("Roles", cat.roles.joinToString { "`$it`" }, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
eb.setTitle(greeting)
|
||||||
|
.appendDescription("I honestly have no idea what the command `${event.args}` does...")
|
||||||
|
.setColor(event.selfMember.color).setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl).setTimestamp(LocalDateTime.now())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
event.reply(eb.build())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package nl.voidcorp.dbot.commands
|
package nl.voidcorp.dbot.commands
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
import com.github.salomonbrys.kotson.fromJson
|
||||||
import com.jagrosh.jdautilities.command.Command
|
|
||||||
import net.dv8tion.jda.core.EmbedBuilder
|
import net.dv8tion.jda.core.EmbedBuilder
|
||||||
import nl.voidcorp.dbot.addAll
|
import nl.voidcorp.dbot.addAll
|
||||||
import nl.voidcorp.dbot.commands
|
import nl.voidcorp.dbot.commands
|
||||||
|
@ -10,17 +9,8 @@ import nl.voidcorp.dbot.random
|
||||||
import nl.voidcorp.dbot.storage.XKCD
|
import nl.voidcorp.dbot.storage.XKCD
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
val funCategory = Command.Category("Fun Commands") {
|
|
||||||
if (it.guild.getTextChannelsByName("bot", true).firstOrNull() == null) return@Category true
|
|
||||||
val test = it.textChannel.name.contains("bot")
|
|
||||||
if (!test) {
|
|
||||||
it.reply("Non music commands can only be used in the ${it.guild.getTextChannelsByName("bot", true).first().asMention} channel")
|
|
||||||
}
|
|
||||||
|
|
||||||
test
|
val xkcd = UnityCommand("xkcd", help = "Fetch an xkcd comic, either a random one, or a specific one if specified", category = FunCategory, arguments = "the comic number (optional)") { event ->
|
||||||
}
|
|
||||||
|
|
||||||
val xkcd = UnityCommand("xkcd", help = "Fetch an xkcd comic, either a random one, or a specific one if specified", category = funCategory, arguments = "the comic number (optional)") { event ->
|
|
||||||
val burl = "https://xkcd.com/"
|
val burl = "https://xkcd.com/"
|
||||||
val eurl = "/info.0.json"
|
val eurl = "/info.0.json"
|
||||||
val eb = EmbedBuilder().setTimestamp(LocalDateTime.now()).setFooter("Requested by ${event.member.effectiveName}", event.member.user.effectiveAvatarUrl)
|
val eb = EmbedBuilder().setTimestamp(LocalDateTime.now()).setFooter("Requested by ${event.member.effectiveName}", event.member.user.effectiveAvatarUrl)
|
||||||
|
@ -49,7 +39,7 @@ val xkcd = UnityCommand("xkcd", help = "Fetch an xkcd comic, either a random one
|
||||||
event.reply(eb.build())
|
event.reply(eb.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
val cat = UnityCommand("cat", help = "Get a random cat image!", category = funCategory) { event ->
|
val cat = UnityCommand("cat", help = "Get a random cat image!", category = FunCategory) { event ->
|
||||||
val url = "https://aws.random.cat/meow"
|
val url = "https://aws.random.cat/meow"
|
||||||
val eb = EmbedBuilder().setTimestamp(LocalDateTime.now()).setFooter("Requested by ${event.member.effectiveName}", event.member.user.effectiveAvatarUrl)
|
val eb = EmbedBuilder().setTimestamp(LocalDateTime.now()).setFooter("Requested by ${event.member.effectiveName}", event.member.user.effectiveAvatarUrl)
|
||||||
.setColor(event.selfMember.color)
|
.setColor(event.selfMember.color)
|
||||||
|
@ -59,7 +49,7 @@ val cat = UnityCommand("cat", help = "Get a random cat image!", category = funCa
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val dog = UnityCommand("dog", help = "Get a random dog image!", category = funCategory) { event ->
|
val dog = UnityCommand("dog", help = "Get a random dog image!", category = FunCategory) { event ->
|
||||||
val url = "https://random.dog/woof.json"
|
val url = "https://random.dog/woof.json"
|
||||||
val eb = EmbedBuilder().setTimestamp(LocalDateTime.now()).setFooter("Requested by ${event.member.effectiveName}", event.member.user.effectiveAvatarUrl)
|
val eb = EmbedBuilder().setTimestamp(LocalDateTime.now()).setFooter("Requested by ${event.member.effectiveName}", event.member.user.effectiveAvatarUrl)
|
||||||
.setColor(event.selfMember.color)
|
.setColor(event.selfMember.color)
|
||||||
|
|
|
@ -3,47 +3,12 @@ package nl.voidcorp.dbot.commands
|
||||||
import com.jagrosh.jdautilities.command.Command
|
import com.jagrosh.jdautilities.command.Command
|
||||||
import com.jagrosh.jdautilities.command.CommandEvent
|
import com.jagrosh.jdautilities.command.CommandEvent
|
||||||
import nl.voidcorp.dbot.music.TrackScheduler
|
import nl.voidcorp.dbot.music.TrackScheduler
|
||||||
|
import nl.voidcorp.dbot.music.guildMusicMap
|
||||||
import nl.voidcorp.dbot.playerManager
|
import nl.voidcorp.dbot.playerManager
|
||||||
|
|
||||||
val musicCategory = Command.Category("Music Commands") {
|
|
||||||
val botExists = it.guild.getTextChannelsByName("bot", true).firstOrNull() != null
|
|
||||||
val musicExists = it.guild.getTextChannelsByName("music", true).firstOrNull() != null
|
|
||||||
val musicBotExists = it.guild.getTextChannelsByName("music-bot", true).firstOrNull() != null
|
|
||||||
when {
|
|
||||||
musicBotExists -> {
|
|
||||||
val res = it.textChannel.name == "music-bot"
|
|
||||||
|
|
||||||
if (!res) it.reply("Music commands are only supported in the ${it.guild.getTextChannelsByName("music-bot", true).first().asMention} channel!")
|
|
||||||
res
|
|
||||||
}
|
|
||||||
musicExists -> {
|
|
||||||
val res = it.textChannel.name == "music"
|
|
||||||
if (!res) it.reply("Music commands are only supported in the ${it.guild.getTextChannelsByName("music", true).first().asMention} channel!")
|
|
||||||
res
|
|
||||||
}
|
|
||||||
botExists -> {
|
|
||||||
val res = it.textChannel.name == "bot"
|
|
||||||
if (!res) it.reply("Music commands are only supported in the ${it.guild.getTextChannelsByName("bot", true).first().asMention} channel!")
|
|
||||||
res
|
|
||||||
}
|
|
||||||
else -> true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
val generalCategory = Command.Category("General commands") {
|
|
||||||
if (it.guild.getTextChannelsByName("bot", true).firstOrNull() == null) return@Category true
|
|
||||||
val test = it.textChannel.name.contains("bot")
|
|
||||||
if (!test) {
|
|
||||||
it.reply("Non music commands can only be used in the ${it.guild.getTextChannelsByName("bot", true).first().asMention} channel")
|
|
||||||
}
|
|
||||||
|
|
||||||
test
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
open class UnityCommand(name: String, help: String = "",
|
open class UnityCommand(name: String, help: String = "",
|
||||||
category: Category = generalCategory,
|
category: UnityCategory = GeneralCategory,
|
||||||
arguments: String = "", vararg aliases: String = arrayOf(), val howTo: String = "",
|
arguments: String = "", vararg aliases: String = arrayOf(), val howTo: String = "",
|
||||||
val exec: (event: CommandEvent) -> Unit) : Command() {
|
val exec: (event: CommandEvent) -> Unit) : Command() {
|
||||||
init {
|
init {
|
||||||
|
@ -54,11 +19,12 @@ open class UnityCommand(name: String, help: String = "",
|
||||||
super.aliases = aliases
|
super.aliases = aliases
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun execute(event: CommandEvent) = exec(event)
|
override fun execute(event: CommandEvent) = exec(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
class UnityMusicCommand(name: String, help: String = "",
|
class UnityMusicCommand(name: String, help: String = "",
|
||||||
category: Category = musicCategory,
|
category: UnityCategory = MusicCategory,
|
||||||
arguments: String = "", vararg aliases: String = arrayOf(name.first().toString()),
|
arguments: String = "", vararg aliases: String = arrayOf(name.first().toString()),
|
||||||
howTo: String = "",
|
howTo: String = "",
|
||||||
val mExec: (event: CommandEvent, scheduler: TrackScheduler) -> Unit) : UnityCommand(name, help, category, arguments, *aliases, howTo = howTo, exec = {}) {
|
val mExec: (event: CommandEvent, scheduler: TrackScheduler) -> Unit) : UnityCommand(name, help, category, arguments, *aliases, howTo = howTo, exec = {}) {
|
||||||
|
|
289
src/main/kotlin/nl/voidcorp/dbot/commands/UnityCommandClient.kt
Normal file
289
src/main/kotlin/nl/voidcorp/dbot/commands/UnityCommandClient.kt
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
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?) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package nl.voidcorp.dbot.commands
|
package nl.voidcorp.dbot.music
|
||||||
|
|
||||||
import com.jagrosh.jdautilities.command.CommandEvent
|
import com.jagrosh.jdautilities.command.CommandEvent
|
||||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler
|
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler
|
||||||
|
@ -11,8 +11,11 @@ import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame
|
||||||
import net.dv8tion.jda.core.audio.AudioSendHandler
|
import net.dv8tion.jda.core.audio.AudioSendHandler
|
||||||
import nl.voidcorp.dbot.addAll
|
import nl.voidcorp.dbot.addAll
|
||||||
import nl.voidcorp.dbot.commands
|
import nl.voidcorp.dbot.commands
|
||||||
|
import nl.voidcorp.dbot.commands.UnityCommand
|
||||||
|
import nl.voidcorp.dbot.commands.UnityMusicCommand
|
||||||
|
import nl.voidcorp.dbot.commands.MusicCategory
|
||||||
|
import nl.voidcorp.dbot.commands.MusicCategoryPrivate
|
||||||
import nl.voidcorp.dbot.log
|
import nl.voidcorp.dbot.log
|
||||||
import nl.voidcorp.dbot.music.TrackScheduler
|
|
||||||
import nl.voidcorp.dbot.playerManager
|
import nl.voidcorp.dbot.playerManager
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,7 +120,7 @@ fun initMusic() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
val playCommand = UnityMusicCommand("play", "Force this song to be the next!", aliases = *arrayOf("p"), howTo = "play <url>") { event, scheduler ->
|
val playCommand = UnityMusicCommand("play", "Force this song to be the next!", aliases = *arrayOf("p"), howTo = "play <url>", category = MusicCategoryPrivate) { event, scheduler ->
|
||||||
if (event.args.isEmpty()) {
|
if (event.args.isEmpty()) {
|
||||||
event.reply("Please supply a song name or URL!")
|
event.reply("Please supply a song name or URL!")
|
||||||
return@UnityMusicCommand
|
return@UnityMusicCommand
|
||||||
|
@ -147,7 +150,7 @@ fun initMusic() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val skipCommand = UnityCommand("skip", help = "Skip the current song", aliases = *arrayOf("s"), category = musicCategory) { event ->
|
val skipCommand = UnityCommand("skip", help = "Skip the current song", aliases = *arrayOf("s"), category = MusicCategory) { event ->
|
||||||
val scheduler = guildMusicMap[event.guild.idLong]
|
val scheduler = guildMusicMap[event.guild.idLong]
|
||||||
if (scheduler == null) {
|
if (scheduler == null) {
|
||||||
event.reply("There is no music playing?")
|
event.reply("There is no music playing?")
|
|
@ -10,8 +10,6 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrack
|
||||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason
|
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason
|
||||||
import net.dv8tion.jda.core.EmbedBuilder
|
import net.dv8tion.jda.core.EmbedBuilder
|
||||||
import net.dv8tion.jda.core.entities.*
|
import net.dv8tion.jda.core.entities.*
|
||||||
import nl.voidcorp.dbot.commands.AudioPlayerSendHandler
|
|
||||||
import nl.voidcorp.dbot.commands.guildMusicMap
|
|
||||||
import nl.voidcorp.dbot.log
|
import nl.voidcorp.dbot.log
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package nl.voidcorp.dbot.storage
|
||||||
|
|
||||||
|
import com.jagrosh.jdautilities.command.GuildSettingsProvider
|
||||||
|
|
||||||
|
data class GuildSettings(val prefixes: MutableList<String> = mutableListOf("!")) : GuildSettingsProvider {
|
||||||
|
override fun getPrefixes(): MutableCollection<String> {
|
||||||
|
return prefixes
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue