From 1e794438673103775bacf5be83f667a355373dd1 Mon Sep 17 00:00:00 2001 From: p5nbTgip0r Date: Mon, 16 Oct 2023 16:10:50 -0700 Subject: [PATCH 1/5] feat: add coroutine support for application commands --- .../discord/commands/ApplicationCommand.kt | 6 +-- .../diabetes/ConversionApplicationCommand.kt | 2 +- .../diabetes/EstimationApplicationCommand.kt | 2 +- .../commands/misc/AwyissApplicationCommand.kt | 2 +- .../NightscoutApplicationCommand.kt | 4 +- .../NightscoutGraphApplicationCommand.kt | 46 ++++++++----------- .../listeners/ApplicationCommandListener.kt | 19 ++++++-- 7 files changed, 42 insertions(+), 39 deletions(-) diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/ApplicationCommand.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/ApplicationCommand.kt index b91179f5..29bfabb1 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/ApplicationCommand.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/ApplicationCommand.kt @@ -10,11 +10,11 @@ import net.dv8tion.jda.api.interactions.components.buttons.Button interface ApplicationCommand { val commandName: String - fun execute(event: SlashCommandInteractionEvent) + suspend fun execute(event: SlashCommandInteractionEvent) - fun execute(event: ButtonInteractionEvent): Boolean = false + suspend fun execute(event: ButtonInteractionEvent): Boolean = false - fun execute(event: ModalInteractionEvent): Boolean = false + suspend fun execute(event: ModalInteractionEvent): Boolean = false fun config(): CommandData diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/diabetes/ConversionApplicationCommand.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/diabetes/ConversionApplicationCommand.kt index 2d963762..d86e8dc5 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/diabetes/ConversionApplicationCommand.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/diabetes/ConversionApplicationCommand.kt @@ -25,7 +25,7 @@ class ConversionApplicationCommand : ApplicationCommand { ) } - override fun execute(event: SlashCommandInteractionEvent) { + override suspend fun execute(event: SlashCommandInteractionEvent) { val glucoseNumber = event.getOption(commandArgGlucose)!!.asString val glucoseUnit = event.getOption(commandArgUnit)?.asString diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/diabetes/EstimationApplicationCommand.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/diabetes/EstimationApplicationCommand.kt index 28acd708..f59f0ca3 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/diabetes/EstimationApplicationCommand.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/diabetes/EstimationApplicationCommand.kt @@ -33,7 +33,7 @@ class EstimationApplicationCommand : ApplicationCommand { ) } - override fun execute(event: SlashCommandInteractionEvent) { + override suspend fun execute(event: SlashCommandInteractionEvent) { when (event.subcommandName) { commandModeAverage -> estimateAverage(event) commandModeA1c -> estimateA1c(event) diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/misc/AwyissApplicationCommand.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/misc/AwyissApplicationCommand.kt index 63b26bd0..cbc84403 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/misc/AwyissApplicationCommand.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/misc/AwyissApplicationCommand.kt @@ -23,7 +23,7 @@ class AwyissApplicationCommand : ApplicationCommand { .addOption(OptionType.BOOLEAN, commandArgSfw, "Safe for work", false) } - override fun execute(event: SlashCommandInteractionEvent) { + override suspend fun execute(event: SlashCommandInteractionEvent) { val stringValue = event.getOption(commandArgValue)!!.asString val sfwValue = event.getOption(commandArgSfw)?.asBoolean ?: true diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/nightscout/NightscoutApplicationCommand.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/nightscout/NightscoutApplicationCommand.kt index 0d37030d..0e7b922b 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/nightscout/NightscoutApplicationCommand.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/nightscout/NightscoutApplicationCommand.kt @@ -45,7 +45,7 @@ class NightscoutApplicationCommand : ApplicationCommand { private val commandButtonDeleteConfirm = "nsdeleteyes".generateId() private val commandButtonDeleteCancel = "nsdeleteno".generateId() - override fun execute(event: SlashCommandInteractionEvent) { + override suspend fun execute(event: SlashCommandInteractionEvent) { when (event.subcommandGroup) { groupNameSet -> when (event.subcommandName) { commandModeToken -> setToken(event) @@ -70,7 +70,7 @@ class NightscoutApplicationCommand : ApplicationCommand { } } - override fun execute(event: ButtonInteractionEvent): Boolean { + override suspend fun execute(event: ButtonInteractionEvent): Boolean { when (event.componentId) { commandButtonDeleteConfirm -> deleteData(event) commandButtonDeleteCancel -> cancelDeleteData(event) diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/nightscout/NightscoutGraphApplicationCommand.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/nightscout/NightscoutGraphApplicationCommand.kt index 3bc30d5c..c4cb5a75 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/nightscout/NightscoutGraphApplicationCommand.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/nightscout/NightscoutGraphApplicationCommand.kt @@ -13,9 +13,7 @@ import com.dongtronic.nightscout.data.NightscoutDTO import com.dongtronic.nightscout.exceptions.NoNightscoutDataException import com.fasterxml.jackson.core.JsonProcessingException import dev.minn.jda.ktx.coroutines.await -import kotlinx.coroutines.launch import kotlinx.coroutines.reactor.awaitSingle -import kotlinx.coroutines.runBlocking import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent import net.dv8tion.jda.api.interactions.commands.OptionType import net.dv8tion.jda.api.interactions.commands.build.CommandData @@ -37,7 +35,7 @@ class NightscoutGraphApplicationCommand : ApplicationCommand { private val logger = logger() private val cooldowns = mutableMapOf() - override fun execute(event: SlashCommandInteractionEvent) { + override suspend fun execute(event: SlashCommandInteractionEvent) { val cooldownSeconds = getCooldown(event.user.id) if (cooldownSeconds != null) { val plural = if (abs(cooldownSeconds) != 1L) "s" else "" @@ -56,31 +54,27 @@ class NightscoutGraphApplicationCommand : ApplicationCommand { return } - runBlocking { - launch { - try { - val enabled = !event.isFromGuild || - GraphDisableDAO.instance.getGraphEnabled(event.guild!!.id).awaitSingle() + try { + val enabled = !event.isFromGuild || + GraphDisableDAO.instance.getGraphEnabled(event.guild!!.id).awaitSingle() - if (!enabled) { - event.reply("Nightscout graphs are disabled in this guild").setEphemeral(true).queue() - return@launch - } + if (!enabled) { + event.reply("Nightscout graphs are disabled in this guild").setEphemeral(true).queue() + return + } - event.deferReply(false).queue() - - val chart = getDataSet(event.user.id, hours).awaitSingle() - val imageBytes = chart.getBitmapBytes(BitmapFormat.PNG) - event.hook.editOriginalAttachments(FileUpload.fromData(imageBytes, "graph.png")).submit().await() - applyCooldown(event.user.id) - } catch (e: Exception) { - logger.error("Error generating NS graph for ${event.user}") - if (e is NightscoutFetchException) { - event.hook.editOriginal(NightscoutCommand.handleGrabError(e.originalException, event.user, e.userDTO)).queue() - } else { - event.hook.editOriginal(NightscoutCommand.handleError(e)).queue() - } - } + event.deferReply(false).queue() + + val chart = getDataSet(event.user.id, hours).awaitSingle() + val imageBytes = chart.getBitmapBytes(BitmapFormat.PNG) + event.hook.editOriginalAttachments(FileUpload.fromData(imageBytes, "graph.png")).submit().await() + applyCooldown(event.user.id) + } catch (e: Exception) { + logger.error("Error generating NS graph for ${event.user}") + if (e is NightscoutFetchException) { + event.hook.editOriginal(NightscoutCommand.handleGrabError(e.originalException, event.user, e.userDTO)).queue() + } else { + event.hook.editOriginal(NightscoutCommand.handleError(e)).queue() } } } diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/listeners/ApplicationCommandListener.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/listeners/ApplicationCommandListener.kt index 3533bb24..9f2580c3 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/listeners/ApplicationCommandListener.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/listeners/ApplicationCommandListener.kt @@ -2,12 +2,13 @@ package com.dongtronic.diabot.platforms.discord.listeners import com.dongtronic.diabot.platforms.discord.commands.ApplicationCommand import com.dongtronic.diabot.util.logger +import dev.minn.jda.ktx.events.CoroutineEventListener +import net.dv8tion.jda.api.events.GenericEvent import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent -import net.dv8tion.jda.api.hooks.ListenerAdapter -class ApplicationCommandListener(vararg val commands: ApplicationCommand) : ListenerAdapter() { +class ApplicationCommandListener(vararg val commands: ApplicationCommand) : CoroutineEventListener { private val logger = logger() private val commandMap: Map @@ -23,7 +24,15 @@ class ApplicationCommandListener(vararg val commands: ApplicationCommand) : List } } - override fun onSlashCommandInteraction(event: SlashCommandInteractionEvent) { + override suspend fun onEvent(event: GenericEvent) { + when (event) { + is SlashCommandInteractionEvent -> onSlashCommandInteraction(event) + is ButtonInteractionEvent -> onButtonInteraction(event) + is ModalInteractionEvent -> onModalInteraction(event) + } + } + + suspend fun onSlashCommandInteraction(event: SlashCommandInteractionEvent) { val commandClass = commandMap[event.name] if (commandClass != null) { @@ -34,7 +43,7 @@ class ApplicationCommandListener(vararg val commands: ApplicationCommand) : List } } - override fun onButtonInteraction(event: ButtonInteractionEvent) { + suspend fun onButtonInteraction(event: ButtonInteractionEvent) { val name = event.componentId.split(':').firstOrNull() val commandClass = commandMap[name] @@ -44,7 +53,7 @@ class ApplicationCommandListener(vararg val commands: ApplicationCommand) : List } } - override fun onModalInteraction(event: ModalInteractionEvent) { + suspend fun onModalInteraction(event: ModalInteractionEvent) { val name = event.modalId.split(':').firstOrNull() val commandClass = commandMap[name] From 6c3149f130b8d59dee2694d7f450de6e18d3f494 Mon Sep 17 00:00:00 2001 From: p5nbTgip0r Date: Mon, 16 Oct 2023 16:13:18 -0700 Subject: [PATCH 2/5] feat: add coroutine base for prefix/text commands --- .../discord/commands/DiscordCommand.kt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/DiscordCommand.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/DiscordCommand.kt index 0a59e217..09e41253 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/DiscordCommand.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/DiscordCommand.kt @@ -1,6 +1,10 @@ package com.dongtronic.diabot.platforms.discord.commands import com.jagrosh.jdautilities.command.Command +import com.jagrosh.jdautilities.command.CommandEvent +import dev.minn.jda.ktx.events.CoroutineEventManager +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking abstract class DiscordCommand(category: Category, parent: Command?) : Command() { var examples = arrayOfNulls(0) @@ -13,6 +17,25 @@ abstract class DiscordCommand(category: Category, parent: Command?) : Command() this.parent = parent } + override fun execute(event: CommandEvent) { + // The `.injectKTX()` line in the main class changes the event manager to a CoroutineEventManager + val manager = event.jda.eventManager as? CoroutineEventManager + if (manager == null) { + // fallback to blocking if the event manager isn't a CoroutineEventManager for some reason + runBlocking { + launch { + executeSuspend(event) + } + } + } else { + manager.launch { + executeSuspend(event) + } + } + } + + open suspend fun executeSuspend(event: CommandEvent) {} + override fun toString(): String { return if (this.parent != null) { "${this.parent} $name" From ab39c7f18f7c4ce9d3cdbe36df49bcdf280295ec Mon Sep 17 00:00:00 2001 From: p5nbTgip0r Date: Mon, 16 Oct 2023 16:24:14 -0700 Subject: [PATCH 3/5] refactor: make `CommandEvent` non-null in sample command code --- .../diabot/platforms/discord/commands/SampleSubCommand.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/SampleSubCommand.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/SampleSubCommand.kt index c12b70ea..7110d6f5 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/SampleSubCommand.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/SampleSubCommand.kt @@ -38,7 +38,7 @@ class SampleSubCommand(category: Category, parent: Command?) : DiscordCommand(ca this.aliases = arrayOf("l") } - override fun execute(event: CommandEvent?) { + override fun execute(event: CommandEvent) { // do a thing } } @@ -53,7 +53,7 @@ class SampleSubCommand(category: Category, parent: Command?) : DiscordCommand(ca this.aliases = arrayOf("a") } - override fun execute(event: CommandEvent?) { + override fun execute(event: CommandEvent) { // do another thing } } @@ -68,7 +68,7 @@ class SampleSubCommand(category: Category, parent: Command?) : DiscordCommand(ca this.aliases = arrayOf("remove", "d", "r") } - override fun execute(event: CommandEvent?) { + override fun execute(event: CommandEvent) { // do the third thing } } From ade60429a698feb8294d8e324a3b6a19d1ea2f00 Mon Sep 17 00:00:00 2001 From: p5nbTgip0r Date: Sat, 28 Oct 2023 00:38:44 -0700 Subject: [PATCH 4/5] refactor: migrate existing text command coroutines to `executeSuspend` function --- .../discord/commands/quote/QuoteAddCommand.kt | 78 ++++++------- .../commands/quote/QuoteSearchCommand.kt | 106 +++++++++--------- 2 files changed, 86 insertions(+), 98 deletions(-) diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteAddCommand.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteAddCommand.kt index 406bb622..8465a297 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteAddCommand.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteAddCommand.kt @@ -6,9 +6,7 @@ import com.dongtronic.diabot.platforms.discord.commands.DiscordCommand import com.dongtronic.diabot.util.logger import com.jagrosh.jdautilities.command.CommandEvent import dev.minn.jda.ktx.coroutines.await -import kotlinx.coroutines.launch import kotlinx.coroutines.reactor.awaitSingle -import kotlinx.coroutines.runBlocking import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder import net.dv8tion.jda.api.utils.messages.MessageCreateData @@ -25,54 +23,50 @@ class QuoteAddCommand(category: Category, parent: QuoteCommand) : DiscordCommand this.examples = arrayOf(this.parent!!.name + " add \"this is a quote added manually\" - gar") } - override fun execute(event: CommandEvent) { - runBlocking { - launch { - if (!QuoteDAO.awaitCheckRestrictions(event.guildChannel, warnDisabledGuild = true)) return@launch + override suspend fun executeSuspend(event: CommandEvent) { + if (!QuoteDAO.awaitCheckRestrictions(event.guildChannel, warnDisabledGuild = true)) return - val match = quoteRegex.find(event.message.contentRaw) - if (match == null) { - event.replyError("Could not parse quote. Please make sure you are using the correct format for this command") - return@launch - } - - val message = match.groups["message"]!!.value.trim() - var author = match.groups["author"]!!.value.trim() - var authorId = 0L - - val mention = mentionsRegex.matchEntire(author) - if (mention != null) { - val uid = mention.groups["uid"]!!.value.trim().toLongOrNull() + val match = quoteRegex.find(event.message.contentRaw) + if (match == null) { + event.replyError("Could not parse quote. Please make sure you are using the correct format for this command") + return + } - if (uid != null) { - try { - val user = event.jda.retrieveUserById(uid).await() - author = user.name - authorId = uid - } catch (ignored: Throwable) { - } - } - } + val message = match.groups["message"]!!.value.trim() + var author = match.groups["author"]!!.value.trim() + var authorId = 0L - val quoteDto = QuoteDTO( - guildId = event.guild.id, - channelId = event.channel.id, - author = author, - authorId = authorId.toString(), - quoterId = event.author.id, - message = message, - messageId = event.message.id - ) + val mention = mentionsRegex.matchEntire(author) + if (mention != null) { + val uid = mention.groups["uid"]!!.value.trim().toLongOrNull() + if (uid != null) { try { - val quote = QuoteDAO.getInstance().addQuote(quoteDto).awaitSingle() - event.reply(createAddedMessage(event.member.asMention, quote.quoteId!!)) - } catch (e: Throwable) { - event.replyError("Could not add quote: ${e.message}") - logger.warn("Unexpected error: " + e::class.simpleName + " - " + e.message) + val user = event.jda.retrieveUserById(uid).await() + author = user.name + authorId = uid + } catch (ignored: Throwable) { } } } + + val quoteDto = QuoteDTO( + guildId = event.guild.id, + channelId = event.channel.id, + author = author, + authorId = authorId.toString(), + quoterId = event.author.id, + message = message, + messageId = event.message.id + ) + + try { + val quote = QuoteDAO.getInstance().addQuote(quoteDto).awaitSingle() + event.reply(createAddedMessage(event.member.asMention, quote.quoteId!!)) + } catch (e: Throwable) { + event.replyError("Could not add quote: ${e.message}") + logger.warn("Unexpected error: " + e::class.simpleName + " - " + e.message) + } } companion object { diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteSearchCommand.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteSearchCommand.kt index 3712bc79..c5d225fe 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteSearchCommand.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteSearchCommand.kt @@ -4,9 +4,7 @@ import com.dongtronic.diabot.data.mongodb.QuoteDAO import com.dongtronic.diabot.data.mongodb.QuoteDTO import com.dongtronic.diabot.platforms.discord.commands.DiscordCommand import com.jagrosh.jdautilities.command.CommandEvent -import kotlinx.coroutines.launch import kotlinx.coroutines.reactor.awaitSingle -import kotlinx.coroutines.runBlocking import net.dv8tion.jda.api.EmbedBuilder import org.bson.conversions.Bson import org.litote.kmongo.and @@ -28,68 +26,64 @@ class QuoteSearchCommand(category: Category, parent: QuoteCommand) : DiscordComm this.maxNumberOfQuotes = System.getenv().getOrDefault("QUOTE_MAX_SEARCH_DISPLAY", "10").toInt() } - override fun execute(event: CommandEvent) { - runBlocking { - launch { - if (!QuoteDAO.awaitCheckRestrictions(event.guildChannel, warnDisabledGuild = true)) return@launch + override suspend fun executeSuspend(event: CommandEvent) { + if (!QuoteDAO.awaitCheckRestrictions(event.guildChannel, warnDisabledGuild = true)) return - var args = event.args.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() }.toList() + var args = event.args.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() }.toList() - // Do we want one random quote from our search? - val random = args.getOrNull(0) == "r" - if (random) { - args = args.slice(1 until args.size) - } + // Do we want one random quote from our search? + val random = args.getOrNull(0) == "r" + if (random) { + args = args.slice(1 until args.size) + } - if (args.isEmpty()) { - replyTooFewArgs(event) - return@launch - } + if (args.isEmpty()) { + replyTooFewArgs(event) + return + } - // Build a list of regex filters based on the provided keywords - val filters: MutableList = mutableListOf() - for (arg in args) { - val keyword = Regex.escape(arg) - filters += QuoteDTO::message regex "(?i)$keyword" - } + // Build a list of regex filters based on the provided keywords + val filters: MutableList = mutableListOf() + for (arg in args) { + val keyword = Regex.escape(arg) + filters += QuoteDTO::message regex "(?i)$keyword" + } - if (random) { - // Get a single, random quote - val quote = QuoteDAO.getInstance().getRandomQuote(event.guild.id, and(filters)).awaitSingle() - event.reply(createQuoteEmbed(quote)) - return@launch - } + if (random) { + // Get a single, random quote + val quote = QuoteDAO.getInstance().getRandomQuote(event.guild.id, and(filters)).awaitSingle() + event.reply(createQuoteEmbed(quote)) + return + } - @Suppress("SwallowedException") - try { - val quotes = QuoteDAO.getInstance().getQuotes(event.guild.id, and(filters)) - - // Create an embed with up to 10 quotes as fields - val builder = EmbedBuilder() - val msg = event.message.contentRaw - builder.setAuthor("Diabot Quote Search") - builder.setDescription("Command: \"$msg\"") - - val quotesIter = quotes.toIterable().iterator() - var count = 0 - while (quotesIter.hasNext()) { - val quote = quotesIter.next() - if (count < maxNumberOfQuotes) { - // Ignore any quotes past the first 10 - addQuoteToEmbed(builder, quote) - } - count += 1 - } - - if (count > maxNumberOfQuotes) { - builder.addField("Too many!", "$count quotes found, omitting the rest", false) - } - - event.reply(builder.build()) - } catch (e: java.util.NoSuchElementException) { - event.replyError("Could not find any quote") + @Suppress("SwallowedException") + try { + val quotes = QuoteDAO.getInstance().getQuotes(event.guild.id, and(filters)) + + // Create an embed with up to 10 quotes as fields + val builder = EmbedBuilder() + val msg = event.message.contentRaw + builder.setAuthor("Diabot Quote Search") + builder.setDescription("Command: \"$msg\"") + + val quotesIter = quotes.toIterable().iterator() + var count = 0 + while (quotesIter.hasNext()) { + val quote = quotesIter.next() + if (count < maxNumberOfQuotes) { + // Ignore any quotes past the first 10 + addQuoteToEmbed(builder, quote) } + count += 1 } + + if (count > maxNumberOfQuotes) { + builder.addField("Too many!", "$count quotes found, omitting the rest", false) + } + + event.reply(builder.build()) + } catch (e: java.util.NoSuchElementException) { + event.replyError("Could not find any quote") } } From 7164f521c9c22263b5efa2d11553472f60329f26 Mon Sep 17 00:00:00 2001 From: p5nbTgip0r Date: Sat, 28 Oct 2023 00:39:20 -0700 Subject: [PATCH 5/5] fix(quote): quote search not working when quote limit is reached --- .../platforms/discord/commands/quote/QuoteSearchCommand.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteSearchCommand.kt b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteSearchCommand.kt index c5d225fe..5e09ccde 100644 --- a/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteSearchCommand.kt +++ b/bot/src/main/java/com/dongtronic/diabot/platforms/discord/commands/quote/QuoteSearchCommand.kt @@ -27,7 +27,7 @@ class QuoteSearchCommand(category: Category, parent: QuoteCommand) : DiscordComm } override suspend fun executeSuspend(event: CommandEvent) { - if (!QuoteDAO.awaitCheckRestrictions(event.guildChannel, warnDisabledGuild = true)) return + if (!QuoteDAO.awaitCheckRestrictions(event.guildChannel, warnDisabledGuild = true, checkQuoteLimit = false)) return var args = event.args.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() }.toList()