From 7753f11e605a739747d1df6daedc2562fee3b42a Mon Sep 17 00:00:00 2001 From: limited_dev Date: Sun, 23 Apr 2023 23:53:11 +0200 Subject: [PATCH 1/2] chore: changed Ext to Extension, added Potatoes Signed-off-by: limited_dev --- src/main/kotlin/de/limited_dev/botendo/Bot.kt | 25 +++++++---- ...owPlayingExt.kt => NowPlayingExtension.kt} | 2 +- .../music/{PlayExt.kt => PlayExtension.kt} | 3 +- .../music/{QueueExt.kt => QueueExtension.kt} | 2 +- .../music/{SkipExt.kt => SkipExtension.kt} | 2 +- .../music/{StopExt.kt => StopExtension.kt} | 2 +- .../music/components/MusicManager.kt | 6 +-- .../util/{InfoExt.kt => InfoExtension.kt} | 2 +- .../extensions/util/PotatoExtension.kt | 41 +++++++++++++++++++ 9 files changed, 68 insertions(+), 17 deletions(-) rename src/main/kotlin/de/limited_dev/botendo/extensions/music/{NowPlayingExt.kt => NowPlayingExtension.kt} (98%) rename src/main/kotlin/de/limited_dev/botendo/extensions/music/{PlayExt.kt => PlayExtension.kt} (99%) rename src/main/kotlin/de/limited_dev/botendo/extensions/music/{QueueExt.kt => QueueExtension.kt} (98%) rename src/main/kotlin/de/limited_dev/botendo/extensions/music/{SkipExt.kt => SkipExtension.kt} (99%) rename src/main/kotlin/de/limited_dev/botendo/extensions/music/{StopExt.kt => StopExtension.kt} (99%) rename src/main/kotlin/de/limited_dev/botendo/extensions/util/{InfoExt.kt => InfoExtension.kt} (97%) create mode 100644 src/main/kotlin/de/limited_dev/botendo/extensions/util/PotatoExtension.kt diff --git a/src/main/kotlin/de/limited_dev/botendo/Bot.kt b/src/main/kotlin/de/limited_dev/botendo/Bot.kt index c179ad8..96b4ce0 100644 --- a/src/main/kotlin/de/limited_dev/botendo/Bot.kt +++ b/src/main/kotlin/de/limited_dev/botendo/Bot.kt @@ -21,16 +21,19 @@ package de.limited_dev.botendo import com.kotlindiscord.kord.extensions.ExtensibleBot import de.limited_dev.botendo.extensions.music.* -import de.limited_dev.botendo.extensions.util.InfoExt +import de.limited_dev.botendo.extensions.util.InfoExtension +import de.limited_dev.botendo.extensions.util.PotatoExtension import de.limited_dev.botendo.util.CredentialManager import de.limited_dev.botendo.util.Logger +import dev.kord.core.event.interaction.ButtonInteractionCreateEvent +import dev.kord.core.on import dev.schlaubi.lavakord.LavaKord import dev.schlaubi.lavakord.kord.lavakord object Bot { //The kord object gets set at app launch - lateinit var lava: LavaKord private lateinit var bot: ExtensibleBot + lateinit var lava: LavaKord suspend fun start() { Logger.out("Starting Bot...") @@ -51,12 +54,13 @@ object Bot { } extensions { - add(::InfoExt) - add(::PlayExt) - add(::StopExt) - add(::SkipExt) - add(::NowPlayingExt) - add(::QueueExt) + add(::InfoExtension) + add(::PlayExtension) + add(::StopExtension) + add(::SkipExtension) + add(::NowPlayingExtension) + add(::QueueExtension) + add(::PotatoExtension) } } @@ -66,6 +70,11 @@ object Bot { //Add the LavaLink node from config lava.addNode(CredentialManager.linkip, CredentialManager.linkpw) + //Register Button presses + bot.kordRef.on { + + } + //Start the bot bot.start() } diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExtension.kt similarity index 98% rename from src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExt.kt rename to src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExtension.kt index d9cb197..c44cacb 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExt.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExtension.kt @@ -28,7 +28,7 @@ import de.limited_dev.botendo.util.UrlUtil import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.kord.getLink -class NowPlayingExt : Extension() { +class NowPlayingExtension : Extension() { override val name = "nowplaying" override suspend fun setup() { publicSlashCommand { diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExtension.kt similarity index 99% rename from src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExt.kt rename to src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExtension.kt index fb2060d..851ff60 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExt.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExtension.kt @@ -30,7 +30,8 @@ import de.limited_dev.botendo.util.MessageUtil import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.kord.getLink -class PlayExt : Extension() { + +class PlayExtension : Extension() { override val name = "play" diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExtension.kt similarity index 98% rename from src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExt.kt rename to src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExtension.kt index 9448c0e..606db73 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExt.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExtension.kt @@ -27,7 +27,7 @@ import de.limited_dev.botendo.util.MessageUtil import de.limited_dev.botendo.util.TimeUtil import dev.schlaubi.lavakord.audio.Link -class QueueExt : Extension() { +class QueueExtension : Extension() { override val name = "queue" override suspend fun setup() { publicSlashCommand { diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExtension.kt similarity index 99% rename from src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExt.kt rename to src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExtension.kt index 1fbbdc9..ddcf6ab 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExt.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExtension.kt @@ -28,7 +28,7 @@ import de.limited_dev.botendo.util.TimeUtil import de.limited_dev.botendo.util.UrlUtil import dev.schlaubi.lavakord.audio.Link -class SkipExt : Extension() { +class SkipExtension : Extension() { override val name = "skip" override suspend fun setup() { publicSlashCommand { diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExtension.kt similarity index 99% rename from src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExt.kt rename to src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExtension.kt index 6c12501..ecfc52d 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExt.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExtension.kt @@ -28,7 +28,7 @@ import de.limited_dev.botendo.util.MessageUtil import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.kord.getLink -class StopExt : Extension() { +class StopExtension : Extension() { override val name = "stop" override suspend fun setup() { publicSlashCommand { diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt index bf7b133..5e2a8b6 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt @@ -22,7 +22,7 @@ package de.limited_dev.botendo.extensions.music.components import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext import com.kotlindiscord.kord.extensions.components.forms.ModalForm import com.kotlindiscord.kord.extensions.types.respond -import de.limited_dev.botendo.extensions.music.PlayExt +import de.limited_dev.botendo.extensions.music.PlayExtension import de.limited_dev.botendo.util.MessageUtil import de.limited_dev.botendo.util.TimeUtil import de.limited_dev.botendo.util.UrlUtil @@ -44,7 +44,7 @@ object MusicManager { suspend fun addToQueue( - ctx: PublicSlashCommandContext, + ctx: PublicSlashCommandContext, link: Link, search: String ) { @@ -52,7 +52,7 @@ object MusicManager { } suspend fun addToQueue( - ctx: PublicSlashCommandContext, + ctx: PublicSlashCommandContext, link: Link, search: String, silent: Boolean diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExtension.kt similarity index 97% rename from src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExt.kt rename to src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExtension.kt index 00909b9..47feb40 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExt.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExtension.kt @@ -24,7 +24,7 @@ import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import de.limited_dev.botendo.build.BuildConstants import de.limited_dev.botendo.util.MessageUtil -class InfoExt : Extension() { +class InfoExtension : Extension() { override val name = "info" override suspend fun setup() { publicSlashCommand { diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/util/PotatoExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/util/PotatoExtension.kt new file mode 100644 index 0000000..dcfd92b --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/util/PotatoExtension.kt @@ -0,0 +1,41 @@ +/* + * Botendo + * Copyright (C) 2023 limited_dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.limited_dev.botendo.extensions.util + +import com.kotlindiscord.kord.extensions.extensions.Extension +import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import de.limited_dev.botendo.util.MessageUtil + +class PotatoExtension : Extension() { + override val name = "potato" + override suspend fun setup() { + publicSlashCommand { + name = "potato" + description = "Potato" + this.action { + MessageUtil.sendEmbedForPublicSlashCommandWithImage( + this, "Potato", + "Potato", + "https://static.tumblr.com/c06d8e0928395746a63b9c5d3cb1ce66/sl9iajp/gxFmqk38z/tumblr_static_potato-equality.jpg" + ) + } + } + } +} From 465101f68a49343e96dc0c1067bf2507a797ed22 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 26 Apr 2023 17:48:53 +0200 Subject: [PATCH 2/2] feat: added button controls for controlling music, added presence, added color codes to bot output, added some comments into the code fix: fixed issues with skipping a song, when there is no next sond in the queue chore: renamed Dockerfile, updated README.md Signed-off-by: limited_dev --- dockerfile => Dockerfile | 0 README.md | 7 +- build.gradle.kts | 3 +- src/main/kotlin/de/limited_dev/botendo/Bot.kt | 32 +++- .../de/limited_dev/botendo/buttons/Button.kt | 35 +++++ .../botendo/buttons/ButtonManager.kt | 26 ++++ .../botendo/buttons/music/PauseButton.kt | 105 +++++++++++++ .../botendo/buttons/music/QueueButton.kt | 96 ++++++++++++ .../botendo/buttons/music/RepeatButton.kt | 104 +++++++++++++ .../botendo/buttons/music/SkipButton.kt | 147 ++++++++++++++++++ .../botendo/buttons/music/StopButton.kt | 98 ++++++++++++ .../extensions/music/NowPlayingExtension.kt | 46 ++++-- .../botendo/extensions/music/PlayExtension.kt | 4 + .../extensions/music/QueueExtension.kt | 20 ++- .../botendo/extensions/music/SkipExtension.kt | 48 ++++-- .../botendo/extensions/music/StopExtension.kt | 5 + .../music/components/GuildTrackScheduler.kt | 4 + .../music/components/MusicManager.kt | 35 +++++ .../botendo/extensions/util/InfoExtension.kt | 5 +- .../extensions/util/PotatoExtension.kt | 3 +- .../de/limited_dev/botendo/util/ButtonUtil.kt | 46 ++++++ .../limited_dev/botendo/util/MessageUtil.kt | 20 ++- .../de/limited_dev/botendo/util/TimeUtil.kt | 5 +- .../de/limited_dev/botendo/util/UrlUtil.kt | 1 + 24 files changed, 856 insertions(+), 39 deletions(-) rename dockerfile => Dockerfile (100%) create mode 100644 src/main/kotlin/de/limited_dev/botendo/buttons/Button.kt create mode 100644 src/main/kotlin/de/limited_dev/botendo/buttons/ButtonManager.kt create mode 100644 src/main/kotlin/de/limited_dev/botendo/buttons/music/PauseButton.kt create mode 100644 src/main/kotlin/de/limited_dev/botendo/buttons/music/QueueButton.kt create mode 100644 src/main/kotlin/de/limited_dev/botendo/buttons/music/RepeatButton.kt create mode 100644 src/main/kotlin/de/limited_dev/botendo/buttons/music/SkipButton.kt create mode 100644 src/main/kotlin/de/limited_dev/botendo/buttons/music/StopButton.kt create mode 100644 src/main/kotlin/de/limited_dev/botendo/util/ButtonUtil.kt diff --git a/dockerfile b/Dockerfile similarity index 100% rename from dockerfile rename to Dockerfile diff --git a/README.md b/README.md index 33739da..8455c81 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ A Discord music bot, written in Kotlin using the kord library. ## Special Thanks to -- HopeBaron for taking the time to help me fix this pos. +- HopeBaron for helping me a whole lot ## Commands @@ -27,6 +27,11 @@ A Discord music bot, written in Kotlin using the kord library. ## How to self-host (using the Docker container) +1. Pull the container +2. Map /data/ to a folder on disk +3. Run the Bot once +4. Follow step 4 - 7 of "How to self-host (using the JAR)" + ## How to self-host (using the JAR) 1. Download the latest release from the Package Registry ("Packages and registries" > "Package Registry") diff --git a/build.gradle.kts b/build.gradle.kts index 5e69edf..2413c18 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,7 +33,7 @@ val ownerID = 372703841151614976L group = "de.limited_dev.botendo" version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_SHORT_SHA")}-prod" } ?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" } - ?: "6.1.1" + ?: "6.2.0" val kordver = "1.5.6" val lavaver = "3.8.0" @@ -44,7 +44,6 @@ project.base.archivesName.set(mavenArtifact) repositories { mavenCentral() - maven("https://m2.dv8tion.net/releases") maven { name = "Gitlab" val projectId = System.getenv("CI_PROJECT_ID") diff --git a/src/main/kotlin/de/limited_dev/botendo/Bot.kt b/src/main/kotlin/de/limited_dev/botendo/Bot.kt index 96b4ce0..296088e 100644 --- a/src/main/kotlin/de/limited_dev/botendo/Bot.kt +++ b/src/main/kotlin/de/limited_dev/botendo/Bot.kt @@ -20,11 +20,15 @@ package de.limited_dev.botendo import com.kotlindiscord.kord.extensions.ExtensibleBot +import de.limited_dev.botendo.buttons.ButtonManager import de.limited_dev.botendo.extensions.music.* import de.limited_dev.botendo.extensions.util.InfoExtension import de.limited_dev.botendo.extensions.util.PotatoExtension import de.limited_dev.botendo.util.CredentialManager import de.limited_dev.botendo.util.Logger +import de.limited_dev.botendo.util.MessageUtil +import dev.kord.common.Color +import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.event.interaction.ButtonInteractionCreateEvent import dev.kord.core.on import dev.schlaubi.lavakord.LavaKord @@ -62,6 +66,10 @@ object Bot { add(::QueueExtension) add(::PotatoExtension) } + + this.presence { + this.streaming("music", "https://twitch.tv/limited_dev") + } } //Add LavaLink @@ -72,7 +80,29 @@ object Bot { //Register Button presses bot.kordRef.on { - + val inter = this.interaction + val response = inter.deferPublicResponse() + val u = inter.user + val g = this.interaction.getOriginalInteractionResponse().getGuild() + var flag = false + for (b in ButtonManager.buttons) { + if (b.id != inter.componentId || flag) + continue + b.onInteraction(response, g, u) + flag = true + } + if (!flag) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "Error", + "Could not find button with id \"${inter.componentId}\".\nPlease report this.", + u.asUser().username + "#" + u.asUser().discriminator + ) + ) + } + } } //Start the bot diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/Button.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/Button.kt new file mode 100644 index 0000000..0511e2e --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/buttons/Button.kt @@ -0,0 +1,35 @@ +/* + * Botendo + * Copyright (C) 2023 limited_dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.limited_dev.botendo.buttons + +import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior +import dev.kord.core.entity.Guild +import dev.kord.core.entity.User + +open class Button(val id: String) { + + open suspend fun onInteraction( + response: DeferredPublicMessageInteractionResponseBehavior, + guild: Guild, + user: User + ) { + + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/ButtonManager.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/ButtonManager.kt new file mode 100644 index 0000000..614858d --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/buttons/ButtonManager.kt @@ -0,0 +1,26 @@ +/* + * Botendo + * Copyright (C) 2023 limited_dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.limited_dev.botendo.buttons + +import de.limited_dev.botendo.buttons.music.* + +object ButtonManager { + val buttons = listOf(RepeatButton(), PauseButton(), SkipButton(), QueueButton(), StopButton()) +} diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/music/PauseButton.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/music/PauseButton.kt new file mode 100644 index 0000000..f23ed45 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/buttons/music/PauseButton.kt @@ -0,0 +1,105 @@ +/* + * Botendo + * Copyright (C) 2023 limited_dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.limited_dev.botendo.buttons.music + +import de.limited_dev.botendo.Bot +import de.limited_dev.botendo.buttons.Button +import de.limited_dev.botendo.extensions.music.components.MusicManager +import de.limited_dev.botendo.util.ButtonUtil +import de.limited_dev.botendo.util.MessageUtil +import dev.kord.common.Color +import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior +import dev.kord.core.behavior.interaction.response.respond +import dev.kord.core.entity.Guild +import dev.kord.core.entity.User +import dev.kord.rest.builder.message.modify.actionRow +import dev.schlaubi.lavakord.audio.Link + +class PauseButton : Button("btn.music.pause") { + override suspend fun onInteraction( + response: DeferredPublicMessageInteractionResponseBehavior, + guild: Guild, + user: User + ) { + val guildId = guild.id + val link = Bot.lava.getLink(guildId.toString()) + val player = link.player + val voiceState = user.asMember(guildId).getVoiceStateOrNull() + if (voiceState == null) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "You are not connected to a VC", + "Please connect to a VC", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } + + val channelId = voiceState.channelId + if (link.state == Link.State.NOT_CONNECTED) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "Not connected", + "I'm not in a VC and therefore, I am not playing anything.", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "You are not in my VC", + "We are not in the same VC and therefore, you cannot control the music", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } + + player.pause(!player.paused) + + val gts = MusicManager.getGuildTrackScheduler(guild, player) + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0x52E01A), + if (player.paused) "I paused" else "I'm continuing", + if (player.paused) "I paused the song" else "I'm continuing to play the song.", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + + + this.actionRow { + this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components) + } + } + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/music/QueueButton.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/music/QueueButton.kt new file mode 100644 index 0000000..6a7615c --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/buttons/music/QueueButton.kt @@ -0,0 +1,96 @@ +/* + * Botendo + * Copyright (C) 2023 limited_dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.limited_dev.botendo.buttons.music + +import de.limited_dev.botendo.Bot +import de.limited_dev.botendo.buttons.Button +import de.limited_dev.botendo.extensions.music.components.MusicManager +import de.limited_dev.botendo.util.ButtonUtil +import de.limited_dev.botendo.util.MessageUtil +import de.limited_dev.botendo.util.TimeUtil +import dev.kord.common.Color +import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior +import dev.kord.core.behavior.interaction.response.respond +import dev.kord.core.entity.Guild +import dev.kord.core.entity.User +import dev.kord.rest.builder.message.modify.actionRow +import dev.schlaubi.lavakord.audio.Link + +class QueueButton : Button("btn.music.queue") { + override suspend fun onInteraction( + response: DeferredPublicMessageInteractionResponseBehavior, + guild: Guild, + user: User + ) { + val guildId = guild.id + val link = Bot.lava.getLink(guildId.toString()) + val player = link.player + if (link.state == Link.State.NOT_CONNECTED) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "Not connected", + "I'm not in a VC and therefore, I am not playing anything.", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } + + val track = player.playingTrack + if (track == null) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "Not playing", + "I'm not playing anything currently", user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } + val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player) + val q = gts.getQueue() + var desc = + """${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length.inWholeMilliseconds)} (${track.author})**""" + "\n" + for ((i, tr) in q.withIndex()) { + if (i >= 14) + continue + desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n" + } + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0x52E01A), + "Queue", + desc, + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + + this.actionRow { + this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components) + } + } + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/music/RepeatButton.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/music/RepeatButton.kt new file mode 100644 index 0000000..d354134 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/buttons/music/RepeatButton.kt @@ -0,0 +1,104 @@ +/* + * Botendo + * Copyright (C) 2023 limited_dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.limited_dev.botendo.buttons.music + +import de.limited_dev.botendo.Bot +import de.limited_dev.botendo.buttons.Button +import de.limited_dev.botendo.extensions.music.components.MusicManager +import de.limited_dev.botendo.util.ButtonUtil +import de.limited_dev.botendo.util.MessageUtil +import dev.kord.common.Color +import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior +import dev.kord.core.behavior.interaction.response.respond +import dev.kord.core.entity.Guild +import dev.kord.core.entity.User +import dev.kord.rest.builder.message.modify.actionRow +import dev.schlaubi.lavakord.audio.Link + +class RepeatButton : Button("btn.music.repeat") { + override suspend fun onInteraction( + response: DeferredPublicMessageInteractionResponseBehavior, + guild: Guild, + user: User + ) { + val guildId = guild.id + val link = Bot.lava.getLink(guildId.toString()) + val player = link.player + val voiceState = user.asMember(guildId).getVoiceStateOrNull() + if (voiceState == null) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "You are not connected to a VC", + "Please connect to a VC", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } + + val channelId = voiceState.channelId + if (link.state == Link.State.NOT_CONNECTED) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "Not connected", + "I'm not in a VC and therefore, I am not playing anything.", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "You are not in my VC", + "We are not in the same VC and therefore, you cannot control the music", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } + + val gts = MusicManager.getGuildTrackScheduler(guild, player) + gts.repeating = !gts.repeating + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0x52E01A), + if (gts.repeating) "Now Repeating" else "Now Continuing", + if (gts.repeating) "The current track will now loop" else "The next track will play when this song finishes", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + + + this.actionRow { + this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components) + } + } + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/music/SkipButton.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/music/SkipButton.kt new file mode 100644 index 0000000..38c1992 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/buttons/music/SkipButton.kt @@ -0,0 +1,147 @@ +/* + * Botendo + * Copyright (C) 2023 limited_dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.limited_dev.botendo.buttons.music + +import de.limited_dev.botendo.Bot +import de.limited_dev.botendo.buttons.Button +import de.limited_dev.botendo.extensions.music.components.MusicManager +import de.limited_dev.botendo.util.ButtonUtil +import de.limited_dev.botendo.util.MessageUtil +import de.limited_dev.botendo.util.TimeUtil +import de.limited_dev.botendo.util.UrlUtil +import dev.kord.common.Color +import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior +import dev.kord.core.behavior.interaction.response.respond +import dev.kord.core.entity.Guild +import dev.kord.core.entity.User +import dev.kord.rest.builder.message.modify.actionRow +import dev.schlaubi.lavakord.audio.Link + +class SkipButton : Button("btn.music.skip") { + override suspend fun onInteraction( + response: DeferredPublicMessageInteractionResponseBehavior, + guild: Guild, + user: User + ) { + val guildId = guild.id + val link = Bot.lava.getLink(guildId.toString()) + val player = link.player + val voiceState = user.asMember(guildId).getVoiceStateOrNull() + if (voiceState == null) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "You are not connected to a VC", + "Please connect to a VC", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } + + val channelId = voiceState.channelId + if (link.state == Link.State.NOT_CONNECTED) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "Not connected", + "I'm not in a VC and therefore, I am not playing anything.", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "You are not in my VC", + "We are not in the same VC and therefore, you cannot control the music", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } + var track = player.playingTrack + if (track == null) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "Not playing", + "I'm not playing anything currently", user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } + val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player) + if (!gts.isEmpty()) { + track = gts.getHead().toTrack() + gts.playNext() + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbedWithImage( + Color(0x52E01A), + "Skipped song; now playing", + "**${track.title}**\n*Now Playing*\nby ${track.author} :: ${ + TimeUtil.getTimeFormatedRaw( + track.length.inWholeMilliseconds + ) + }\n" + + ">>>${track.uri}", + "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + + this.actionRow { + this.components.addAll( + ButtonUtil.getMusicControllerButtons( + player.paused, + gts.repeating + ).components + ) + } + } + return + } + player.stopTrack() + + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0x52E01A), + "Skipped song; now playing", + "Nothing", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + this.actionRow { + this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components) + } + } + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/music/StopButton.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/music/StopButton.kt new file mode 100644 index 0000000..fabc991 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/buttons/music/StopButton.kt @@ -0,0 +1,98 @@ +/* + * Botendo + * Copyright (C) 2023 limited_dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.limited_dev.botendo.buttons.music + +import de.limited_dev.botendo.Bot +import de.limited_dev.botendo.buttons.Button +import de.limited_dev.botendo.extensions.music.components.MusicManager +import de.limited_dev.botendo.util.MessageUtil +import dev.kord.common.Color +import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior +import dev.kord.core.behavior.interaction.response.respond +import dev.kord.core.entity.Guild +import dev.kord.core.entity.User +import dev.schlaubi.lavakord.audio.Link + +class StopButton : Button("btn.music.stop") { + override suspend fun onInteraction( + response: DeferredPublicMessageInteractionResponseBehavior, + guild: Guild, + user: User + ) { + val guildId = guild.id + val link = Bot.lava.getLink(guildId.toString()) + val player = link.player + val voiceState = user.asMember(guildId).getVoiceStateOrNull() + if (voiceState == null) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "You are not connected to a VC", + "Please connect to a VC", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } + + val channelId = voiceState.channelId + if (link.state == Link.State.NOT_CONNECTED) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "Not connected", + "I'm not in a VC and therefore, I am not playing anything.", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0xE0311A), + "You are not in my VC", + "We are not in the same VC and therefore, you cannot control the music", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + return + } + + player.stopTrack() + link.destroy() + MusicManager.getGuildTrackScheduler(guild.asGuild(), player).clear() + response.respond { + this.embeds = mutableListOf( + MessageUtil.getEmbed( + Color(0x52E01A), + "I stopped and left", + "just like your girlfriend", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + } + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExtension.kt index c44cacb..cb0f1d5 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExtension.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExtension.kt @@ -21,10 +21,15 @@ package de.limited_dev.botendo.extensions.music import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import com.kotlindiscord.kord.extensions.types.respond import de.limited_dev.botendo.Bot +import de.limited_dev.botendo.extensions.music.components.MusicManager +import de.limited_dev.botendo.util.ButtonUtil import de.limited_dev.botendo.util.MessageUtil import de.limited_dev.botendo.util.TimeUtil import de.limited_dev.botendo.util.UrlUtil +import dev.kord.common.Color +import dev.kord.rest.builder.message.create.actionRow import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.kord.getLink @@ -41,6 +46,7 @@ class NowPlayingExtension : Extension() { if (link.state == Link.State.NOT_CONNECTED) { MessageUtil.sendEmbedForPublicSlashCommand( this, + Color(0xE0A81A), "Not connected", "I'm not in a VC and therefore, I am not playing anything." ) @@ -50,26 +56,38 @@ class NowPlayingExtension : Extension() { if (track == null) { MessageUtil.sendEmbedForPublicSlashCommand( this, + Color(0xE0A81A), "Not Playing", "I'm not playing anything currently" ) return@action } - MessageUtil.sendEmbedForPublicSlashCommandWithImage( - this, - "Currently playing", - "**${track.title}**\n*Now Playing*\nby ${track.author} :${ - TimeUtil.getTimeFormatedRaw( - track.position.inWholeMilliseconds + val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player) + + this.respond { + this.embeds.add( + MessageUtil.getEmbedWithImage( + Color(0x52E01A), + "Currently playing", + "**${track.title}**\n*Now Playing*\nby ${track.author} :${ + TimeUtil.getTimeFormatedRaw( + track.position.inWholeMilliseconds + ) + }: ${ + TimeUtil.getTimeFormatedRaw( + track.length.inWholeMilliseconds + ) + }\n" + + ">>>${track.uri}", + "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg", + user.asUser().username + "#" + user.asUser().discriminator ) - }: ${ - TimeUtil.getTimeFormatedRaw( - track.length.inWholeMilliseconds - ) - }\n" + - ">>>${track.uri}", - "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg" - ) + ) + + this.actionRow { + ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating) + } + } } } } diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExtension.kt index 851ff60..137c16e 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExtension.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExtension.kt @@ -27,6 +27,7 @@ import com.kotlindiscord.kord.extensions.types.respond import de.limited_dev.botendo.Bot import de.limited_dev.botendo.extensions.music.components.MusicManager import de.limited_dev.botendo.util.MessageUtil +import dev.kord.common.Color import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.kord.getLink @@ -48,6 +49,7 @@ class PlayExtension : Extension() { this.respond { embeds.add( MessageUtil.getEmbed( + Color(0xE0311A), "You are not connected to a VC", "Please connect to a VC", u.asUser().username + "#" + u.asUser().discriminator @@ -65,6 +67,7 @@ class PlayExtension : Extension() { this.respond { embeds.add( MessageUtil.getEmbed( + Color(0xE0311A), "You are not in my VC", "We are not in the same VC and therefore, you cannot play any music", u.asUser().username + "#" + u.asUser().discriminator @@ -83,6 +86,7 @@ class PlayExtension : Extension() { this.respond { embeds.add( MessageUtil.getEmbed( + Color(0xE0A81A), "Searching...", "We are looking for $query", u.asUser().username + "#" + u.asUser().discriminator diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExtension.kt index 606db73..69bb99f 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExtension.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExtension.kt @@ -21,10 +21,14 @@ package de.limited_dev.botendo.extensions.music import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import com.kotlindiscord.kord.extensions.types.respond import de.limited_dev.botendo.Bot import de.limited_dev.botendo.extensions.music.components.MusicManager +import de.limited_dev.botendo.util.ButtonUtil import de.limited_dev.botendo.util.MessageUtil import de.limited_dev.botendo.util.TimeUtil +import dev.kord.common.Color +import dev.kord.rest.builder.message.create.actionRow import dev.schlaubi.lavakord.audio.Link class QueueExtension : Extension() { @@ -40,6 +44,7 @@ class QueueExtension : Extension() { if (link.state == Link.State.NOT_CONNECTED) { MessageUtil.sendEmbedForPublicSlashCommand( this, + Color(0xE0311A), "Not connected", "I'm not in a VC and therefore, I am not playing anything." ) @@ -49,6 +54,7 @@ class QueueExtension : Extension() { if (track == null) { MessageUtil.sendEmbedForPublicSlashCommand( this, + Color(0xE0A81A), "Queue empty", "I'm not playing anything currently" ) @@ -63,8 +69,20 @@ class QueueExtension : Extension() { continue desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n" } - MessageUtil.sendEmbedForPublicSlashCommand(this, "Queue", desc) + this.respond { + this.embeds.add( + MessageUtil.getEmbed( + Color(0x52E01A), + "Queue", + desc, + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + this.actionRow { + ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating) + } + } } } } diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExtension.kt index ddcf6ab..039f4e9 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExtension.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExtension.kt @@ -21,11 +21,15 @@ package de.limited_dev.botendo.extensions.music import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import com.kotlindiscord.kord.extensions.types.respond import de.limited_dev.botendo.Bot import de.limited_dev.botendo.extensions.music.components.MusicManager +import de.limited_dev.botendo.util.ButtonUtil import de.limited_dev.botendo.util.MessageUtil import de.limited_dev.botendo.util.TimeUtil import de.limited_dev.botendo.util.UrlUtil +import dev.kord.common.Color +import dev.kord.rest.builder.message.create.actionRow import dev.schlaubi.lavakord.audio.Link class SkipExtension : Extension() { @@ -43,6 +47,7 @@ class SkipExtension : Extension() { if (voiceState == null) { MessageUtil.sendEmbedForPublicSlashCommand( this, + Color(0xE0311A), "You are not connected to a VC", "Please connect to a VC" ) @@ -53,6 +58,7 @@ class SkipExtension : Extension() { if (link.state == Link.State.NOT_CONNECTED) { MessageUtil.sendEmbedForPublicSlashCommand( this, + Color(0xE0311A), "Not connected", "I'm not in a VC and therefore, I am not playing anything." ) @@ -60,6 +66,7 @@ class SkipExtension : Extension() { } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { MessageUtil.sendEmbedForPublicSlashCommand( this, + Color(0xE0311A), "You are not in my VC", "We are not in the same VC and therefore, you cannot control the music" ) @@ -69,26 +76,41 @@ class SkipExtension : Extension() { if (track == null) { MessageUtil.sendEmbedForPublicSlashCommand( this, + Color(0xE0311A), "Not playing", "I'm not playing anything currently" ) return@action } val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player) - track = gts.getHead().toTrack() - gts.playNext() - MessageUtil.sendEmbedForPublicSlashCommandWithImage( - this, - "Skipped song; now playing", - "**${track.title}**\n*Now Playing*\nby ${track.author} :: ${ - TimeUtil.getTimeFormatedRaw( - track.length.inWholeMilliseconds - ) - }\n" + - ">>>${track.uri}", - "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg" + if (!gts.isEmpty()) { + track = gts.getHead().toTrack() + gts.playNext() + } else { + player.stopTrack() + } - ) + + this.respond { + this.embeds.add( + MessageUtil.getEmbedWithImage( + Color(0x52E01A), + "Skipped song; now playing", + "**${track.title}**\n*Now Playing*\nby ${track.author} :: ${ + TimeUtil.getTimeFormatedRaw( + track.length.inWholeMilliseconds + ) + }\n" + + ">>>${track.uri}", + "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) + + this.actionRow { + ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating) + } + } } } } diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExtension.kt index ecfc52d..7c361ba 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExtension.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExtension.kt @@ -25,6 +25,7 @@ import com.kotlindiscord.kord.extensions.types.respond import de.limited_dev.botendo.Bot import de.limited_dev.botendo.extensions.music.components.MusicManager import de.limited_dev.botendo.util.MessageUtil +import dev.kord.common.Color import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.kord.getLink @@ -44,6 +45,7 @@ class StopExtension : Extension() { this.respond { this.embeds.add( MessageUtil.getEmbed( + Color(0xE0311A), "You are not connected to a VC", "Please connect to my VC", u.asUser().username + "#" + u.asUser().discriminator ) @@ -56,6 +58,7 @@ class StopExtension : Extension() { this.respond { this.embeds.add( MessageUtil.getEmbed( + Color(0xE0311A), "Not connected", "I'm not in a VC and therefore, I am not playing anything.", u.asUser().username + "#" + u.asUser().discriminator @@ -67,6 +70,7 @@ class StopExtension : Extension() { this.respond { this.embeds.add( MessageUtil.getEmbed( + Color(0xE0311A), "You are not in my VC", "We are not in the same VC", u.asUser().username + "#" + u.asUser().discriminator ) @@ -80,6 +84,7 @@ class StopExtension : Extension() { this.respond { this.embeds.add( MessageUtil.getEmbed( + Color(0x52E01A), "I stopped and left", "just like your girlfriend", u.asUser().username + "#" + u.asUser().discriminator diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/GuildTrackScheduler.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/GuildTrackScheduler.kt index 0cd329f..420eae7 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/GuildTrackScheduler.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/GuildTrackScheduler.kt @@ -109,5 +109,9 @@ class GuildTrackScheduler(val pl: Player) { fun getHead(): TrackResponse.PartialTrack { return queue.first() } + + fun isEmpty(): Boolean { + return queue.isEmpty() + } } diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt index 5e2a8b6..f81b07e 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt @@ -23,11 +23,14 @@ import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashC import com.kotlindiscord.kord.extensions.components.forms.ModalForm import com.kotlindiscord.kord.extensions.types.respond import de.limited_dev.botendo.extensions.music.PlayExtension +import de.limited_dev.botendo.util.ButtonUtil import de.limited_dev.botendo.util.MessageUtil import de.limited_dev.botendo.util.TimeUtil import de.limited_dev.botendo.util.UrlUtil +import dev.kord.common.Color import dev.kord.common.entity.Snowflake import dev.kord.core.entity.Guild +import dev.kord.rest.builder.message.create.actionRow import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.player.Player import dev.schlaubi.lavakord.rest.TrackResponse @@ -71,6 +74,7 @@ object MusicManager { ctx.respond { this.embeds.add( MessageUtil.getEmbedWithImage( + Color(0x52E01A), "Queuing track from link", "**${item.track.info.title}**\n*Queue*\nby ${item.track.info.author} :: ${ TimeUtil.getTimeFormatedRaw( @@ -81,6 +85,15 @@ object MusicManager { "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg" ) ) + + this.actionRow { + this.components.addAll( + ButtonUtil.getMusicControllerButtons( + player.paused, + gts.repeating + ).components + ) + } } } @@ -93,6 +106,7 @@ object MusicManager { ctx.respond { this.embeds.add( MessageUtil.getEmbedWithImage( + Color(0x52E01A), "Queuing playlist from link", "**${item.tracks.first().info.title}**\n*${item.playlistInfo.name}*\nby ${item.tracks.first().info.author} :: ${ TimeUtil.getTimeFormatedRaw( @@ -103,6 +117,15 @@ object MusicManager { "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg" ) ) + + this.actionRow { + this.components.addAll( + ButtonUtil.getMusicControllerButtons( + player.paused, + gts.repeating + ).components + ) + } } } @@ -112,6 +135,7 @@ object MusicManager { ctx.respond { this.embeds.add( MessageUtil.getEmbedWithImage( + Color(0x52E01A), "Queuing track from query", "**${item.tracks.first().info.title}**\n*Queue*\nby ${item.tracks.first().info.author} :: ${ TimeUtil.getTimeFormatedRaw( @@ -122,6 +146,15 @@ object MusicManager { "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.tracks.first().info.uri) + "/maxresdefault.jpg" ) ) + + this.actionRow { + this.components.addAll( + ButtonUtil.getMusicControllerButtons( + player.paused, + gts.repeating + ).components + ) + } } } @@ -130,6 +163,7 @@ object MusicManager { ctx.respond { this.embeds.add( MessageUtil.getEmbed( + Color(0xE0311A), "Not found", "There were no matches.", u.username + "#" + u.discriminator @@ -143,6 +177,7 @@ object MusicManager { ctx.respond { this.embeds.add( MessageUtil.getEmbed( + Color(0xE0311A), "Load failed", "There was an error while loading.", u.username + "#" + u.discriminator ) diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExtension.kt index 47feb40..347533a 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExtension.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExtension.kt @@ -23,6 +23,7 @@ import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import de.limited_dev.botendo.build.BuildConstants import de.limited_dev.botendo.util.MessageUtil +import dev.kord.common.Color class InfoExtension : Extension() { override val name = "info" @@ -32,9 +33,9 @@ class InfoExtension : Extension() { description = "Show infos about the bot" this.action { MessageUtil.sendEmbedForPublicSlashCommand( - this, "Botendo", + this, Color(0x52E01A), "Botendo", "Botendo ***v." + BuildConstants.version + "***\n" + - "kord-extensions ***v." + BuildConstants.kordVersion + "***\n" + + "Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" + "lavalink.kt ***v." + BuildConstants.lavaVersion + "***\n" + "Coroutines ***v." + BuildConstants.coroutinesVersion + "***" ) diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/util/PotatoExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/util/PotatoExtension.kt index dcfd92b..2f46c5b 100644 --- a/src/main/kotlin/de/limited_dev/botendo/extensions/util/PotatoExtension.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/util/PotatoExtension.kt @@ -22,6 +22,7 @@ package de.limited_dev.botendo.extensions.util import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import de.limited_dev.botendo.util.MessageUtil +import dev.kord.common.Color class PotatoExtension : Extension() { override val name = "potato" @@ -31,7 +32,7 @@ class PotatoExtension : Extension() { description = "Potato" this.action { MessageUtil.sendEmbedForPublicSlashCommandWithImage( - this, "Potato", + this, Color(0xE0311A), "Potato", "Potato", "https://static.tumblr.com/c06d8e0928395746a63b9c5d3cb1ce66/sl9iajp/gxFmqk38z/tumblr_static_potato-equality.jpg" ) diff --git a/src/main/kotlin/de/limited_dev/botendo/util/ButtonUtil.kt b/src/main/kotlin/de/limited_dev/botendo/util/ButtonUtil.kt new file mode 100644 index 0000000..e92434d --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/util/ButtonUtil.kt @@ -0,0 +1,46 @@ +/* + * Botendo + * Copyright (C) 2023 limited_dev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.limited_dev.botendo.util + +import dev.kord.common.entity.ButtonStyle +import dev.kord.rest.builder.component.ActionRowBuilder + +object ButtonUtil { + fun getMusicControllerButtons(isPaused: Boolean, isRepeating: Boolean): ActionRowBuilder { + val ar = ActionRowBuilder() + ar.interactionButton(ButtonStyle.Secondary, "btn.music.repeat") { + this.label = if (isRepeating) "Stop Repeating" else "Repeat" + } + ar.interactionButton(ButtonStyle.Success, "btn.music.pause") { + this.label = if (isPaused) "Continue" else "Pause" + } + ar.interactionButton(ButtonStyle.Primary, "btn.music.skip") { + this.label = "Skip" + } + ar.interactionButton(ButtonStyle.Secondary, "btn.music.queue") { + this.label = "Queue" + } + ar.interactionButton(ButtonStyle.Danger, "btn.music.stop") { + this.label = "Stop" + } + return ar + } + +} diff --git a/src/main/kotlin/de/limited_dev/botendo/util/MessageUtil.kt b/src/main/kotlin/de/limited_dev/botendo/util/MessageUtil.kt index cc8aeef..5085188 100644 --- a/src/main/kotlin/de/limited_dev/botendo/util/MessageUtil.kt +++ b/src/main/kotlin/de/limited_dev/botendo/util/MessageUtil.kt @@ -23,6 +23,7 @@ import com.kotlindiscord.kord.extensions.commands.Arguments import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext import com.kotlindiscord.kord.extensions.components.forms.ModalForm import com.kotlindiscord.kord.extensions.types.respond +import dev.kord.common.Color import dev.kord.rest.builder.message.EmbedBuilder import java.time.LocalDateTime import java.time.format.DateTimeFormatter @@ -30,14 +31,17 @@ import java.time.format.DateTimeFormatter object MessageUtil { private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss") + ///Send an embedded message as a reply suspend fun sendEmbedForPublicSlashCommand( ctx: PublicSlashCommandContext, + color: Color, title: String, description: String ) { ctx.respond { embeds.add( getEmbed( + color, title, description, ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator @@ -46,8 +50,10 @@ object MessageUtil { } } + ///Send an embedded message with an image as a reply suspend fun sendEmbedForPublicSlashCommandWithImage( ctx: PublicSlashCommandContext, + color: Color, title: String, description: String, thumbnailUrl: String @@ -55,6 +61,7 @@ object MessageUtil { ctx.respond { embeds.add( getEmbedWithImage( + color, title, description, ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator, @@ -64,23 +71,32 @@ object MessageUtil { } } - fun getEmbed(title: String, description: String, source: String): EmbedBuilder { + ///Get an embedded msg with title, description and a src + fun getEmbed( + color: Color, + title: String, + description: String, + source: String + ): EmbedBuilder { val now: LocalDateTime = LocalDateTime.now() val ebb = EmbedBuilder() ebb.title = title ebb.description = description ebb.footer = EmbedBuilder.Footer() ebb.footer!!.text = ">" + dtf.format(now) + " - $source" + ebb.color = color return ebb } + ///Get an embedded msg with image, title, description and a src fun getEmbedWithImage( + color: Color, title: String, description: String, source: String, thumbnailUrl: String ): EmbedBuilder { - val ebb = getEmbed(title, description, source) + val ebb = getEmbed(color, title, description, source) ebb.thumbnail = EmbedBuilder.Thumbnail() ebb.thumbnail!!.url = thumbnailUrl return ebb diff --git a/src/main/kotlin/de/limited_dev/botendo/util/TimeUtil.kt b/src/main/kotlin/de/limited_dev/botendo/util/TimeUtil.kt index 7365f16..d2a9676 100644 --- a/src/main/kotlin/de/limited_dev/botendo/util/TimeUtil.kt +++ b/src/main/kotlin/de/limited_dev/botendo/util/TimeUtil.kt @@ -22,7 +22,8 @@ package de.limited_dev.botendo.util import java.util.concurrent.TimeUnit object TimeUtil { - fun getTimeFormatedShortend(time: Long): String? { + ///Convert Miliseconds to xdays xhours xmins xsecs + fun getTimeFormatedShortend(time: Long): String { var time = time val days = TimeUnit.MILLISECONDS .toDays(time) @@ -54,7 +55,7 @@ object TimeUtil { return s } - fun getTimeFormatedRaw(time: Long): String? { + fun getTimeFormatedRaw(time: Long): String { var time = time val days = TimeUnit.MILLISECONDS .toDays(time) diff --git a/src/main/kotlin/de/limited_dev/botendo/util/UrlUtil.kt b/src/main/kotlin/de/limited_dev/botendo/util/UrlUtil.kt index 14e95a6..ed67935 100644 --- a/src/main/kotlin/de/limited_dev/botendo/util/UrlUtil.kt +++ b/src/main/kotlin/de/limited_dev/botendo/util/UrlUtil.kt @@ -20,6 +20,7 @@ package de.limited_dev.botendo.util object UrlUtil { + ///Strip the video ID from a YouTube link fun getYtThumbnailUrl(uri: String): String { return uri.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1] }