diff --git a/build.gradle.kts b/build.gradle.kts index f05a0e1..1084309 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -35,7 +35,7 @@ version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_ ?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" } ?: "DevelopmentBuild" -val kordver = "0.8.3" +val kordver = "1.5.6" val lavaver = "3.8.0" val coroutinesver = "1.1.0" @@ -68,12 +68,16 @@ repositories { } } +val shadow by configurations.getting +val implementation by configurations.getting +implementation.extendsFrom(shadow) + dependencies { - implementation("dev.kord:kord-core:$kordver") - implementation("dev.schlaubi.lavakord:kord:$lavaver") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesver") - implementation("org.slf4j:slf4j-api:2.0.3") - implementation("org.slf4j:slf4j-simple:2.0.3") + shadow("com.kotlindiscord.kord.extensions:kord-extensions:$kordver") + shadow("dev.schlaubi.lavakord:kord:$lavaver") + shadow("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesver") + shadow("org.slf4j:slf4j-api:2.0.3") + shadow("org.slf4j:slf4j-simple:2.0.3") } @@ -117,13 +121,7 @@ tasks { withType { - dependencies { - include(dependency("dev.schlaubi.lavakord:kord:$lavaver")) - include(dependency("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesver")) - include(dependency("dev.kord:kord-core:$kordver")) - include(dependency("org.slf4j:slf4j-api:2.0.3")) - include(dependency("org.slf4j:slf4j-simple:2.0.3")) - } + configurations = listOf(shadow) dependsOn("generateTemplates", "processResources") } diff --git a/src/main/kotlin/de/limited_dev/botendo/Bot.kt b/src/main/kotlin/de/limited_dev/botendo/Bot.kt index 3e4863e..c179ad8 100644 --- a/src/main/kotlin/de/limited_dev/botendo/Bot.kt +++ b/src/main/kotlin/de/limited_dev/botendo/Bot.kt @@ -19,24 +19,18 @@ package de.limited_dev.botendo -import de.limited_dev.botendo.commands.slash.component.SlashCommandManager -import de.limited_dev.botendo.commands.slash.component.options.CommandOption -import de.limited_dev.botendo.commands.slash.component.options.OptionType +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.util.CredentialManager import de.limited_dev.botendo.util.Logger -import de.limited_dev.botendo.util.MessageUtil -import dev.kord.core.Kord -import dev.kord.core.event.interaction.GuildChatInputCommandInteractionCreateEvent -import dev.kord.core.on -import dev.kord.gateway.Intent -import dev.kord.gateway.PrivilegedIntent import dev.schlaubi.lavakord.LavaKord import dev.schlaubi.lavakord.kord.lavakord object Bot { //The kord object gets set at app launch - lateinit var kord: Kord lateinit var lava: LavaKord + private lateinit var bot: ExtensibleBot suspend fun start() { Logger.out("Starting Bot...") @@ -49,97 +43,30 @@ object Bot { return } - //Register slash commands to bot - SlashCommandManager.register() - //Add Bot token to kord - kord = Kord(CredentialManager.token) - - //Register Command Listener - kord.on { - val deferred = interaction.deferPublicResponse() - //val deferred = async { interaction.deferPublicResponse() } - val command = interaction.command - Logger.out("Command /${command.rootName} with ${command.options.size} Option${if (command.options.size == 1) "" else "s"}") - for (c in SlashCommandManager.commands) { - if (c.name != command.rootName) - continue - val opt = mutableMapOf() - if (c.options != null) { - for (o in c.options) { - when (o.type) { - OptionType.INT -> - if (command.integers[o.name] != null) - opt[o] = command.integers[o.name].toString() - - OptionType.STRING -> - if (command.strings[o.name] != null) - opt[o] = command.strings[o.name].toString() - - OptionType.BOOLEAN -> - if (command.booleans[o.name] != null) - opt[o] = command.booleans[o.name].toString() - } - } - } - c.onSlashCommand(interaction, deferred, opt) - return@on + //kord = Kord(CredentialManager.token) + bot = ExtensibleBot(CredentialManager.token) { + applicationCommands { + enabled = true + } + + extensions { + add(::InfoExt) + add(::PlayExt) + add(::StopExt) + add(::SkipExt) + add(::NowPlayingExt) + add(::QueueExt) } - MessageUtil.sendEmbedForInteraction( - interaction, deferred, "Command not found", "Could not find the command, which you just ran.\n" + - "This is 110%ly an error. Please report it to limited_dev#7441." - ) } - //Register Slash Commands at Discord - /* - kord.createGlobalApplicationCommands { - for (sc in SlashCommandManager.commands) { - this.input(sc.name, sc.description, builder = { - if (sc.options != null) { - for (o in sc.options) { - when (o.type) { - - OptionType.INT -> { - integer(o.name, o.description) { - this.required = o.required - } - } - - OptionType.STRING -> { - string(o.name, o.description) { - this.required = o.required - } - } - - OptionType.BOOLEAN -> { - boolean(o.name, o.description) { - this.required = o.required - } - } - } - } - } - }) - } - } */ - //Add LavaLink - lava = kord.lavakord() + lava = bot.kordRef.lavakord() //Add the LavaLink node from config lava.addNode(CredentialManager.linkip, CredentialManager.linkpw) - Logger.out("Logging in") - //Start the bot - kord.login { - // Load gateway privileges - @OptIn(PrivilegedIntent::class) - intents += Intent.GuildMembers - - @OptIn(PrivilegedIntent::class) - intents += Intent.MessageContent - } + bot.start() } } diff --git a/src/main/kotlin/de/limited_dev/botendo/Main.kt b/src/main/kotlin/de/limited_dev/botendo/Main.kt index 47d7bfd..59b9dd8 100644 --- a/src/main/kotlin/de/limited_dev/botendo/Main.kt +++ b/src/main/kotlin/de/limited_dev/botendo/Main.kt @@ -34,6 +34,6 @@ suspend fun main() { "M#########M \n" + " " ) - println("Bot ver.${BuildConstants.version}") + println("Bot v.${BuildConstants.version}, Kord Extensions v.${BuildConstants.kordVersion}, LavaKord v.${BuildConstants.lavaVersion}, Coroutines v.${BuildConstants.coroutinesVersion}") Bot.start() } diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/SlashCommand.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/SlashCommand.kt deleted file mode 100644 index a0367a1..0000000 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/SlashCommand.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.commands.slash.component - -import de.limited_dev.botendo.commands.slash.component.options.CommandOption -import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior -import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction - -abstract class SlashCommand(val name: String, val description: String, val options: List? = null) { - - open suspend fun onSlashCommand( - interaction: GuildChatInputCommandInteraction, - deferred: DeferredPublicMessageInteractionResponseBehavior, - args: Map - ) { - } - -} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/SlashCommandManager.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/SlashCommandManager.kt deleted file mode 100644 index a69f7e1..0000000 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/SlashCommandManager.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.commands.slash.component - -import de.limited_dev.botendo.commands.slash.music.* -import de.limited_dev.botendo.commands.slash.util.InfoCommand - -object SlashCommandManager { - - val commands = mutableListOf() - - fun register() { - commands.add(InfoCommand()) - commands.add(PlayCommand()) - commands.add(StopCommand()) - commands.add(NowPlayingCommand()) - commands.add(QueueCommand()) - commands.add(SkipCommand()) - } -} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/options/CommandOption.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/options/CommandOption.kt deleted file mode 100644 index abeef23..0000000 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/options/CommandOption.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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.commands.slash.component.options - -data class CommandOption(val name: String, val description: String, val required: Boolean, val type: OptionType) diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/options/OptionType.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/options/OptionType.kt deleted file mode 100644 index bce7067..0000000 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/component/options/OptionType.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.commands.slash.component.options - -enum class OptionType { - INT, - STRING, - BOOLEAN -} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/NowPlayingCommand.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/NowPlayingCommand.kt deleted file mode 100644 index 36e830e..0000000 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/NowPlayingCommand.kt +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.commands.slash.music - -import de.limited_dev.botendo.Bot -import de.limited_dev.botendo.commands.slash.component.SlashCommand -import de.limited_dev.botendo.commands.slash.component.options.CommandOption -import de.limited_dev.botendo.util.MessageUtil -import de.limited_dev.botendo.util.TimeUtil -import de.limited_dev.botendo.util.UrlUtil -import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior -import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction -import dev.schlaubi.lavakord.audio.Link - -class NowPlayingCommand : SlashCommand("nowplaying", "Show what's currently playing", null) { - override suspend fun onSlashCommand( - interaction: GuildChatInputCommandInteraction, - deferred: DeferredPublicMessageInteractionResponseBehavior, - args: Map - ) { - val guildId = interaction.guildId - val link = Bot.lava.getLink(guildId.toString()) - val player = link.player - if (link.state != Link.State.CONNECTED) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "Not connected", - "I'm not in a VC and therefore, I am not playing anything." - ) - return - } - val track = player.playingTrack - if (track == null) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "Not Playing", - "I'm not playing anything currently" - ) - return - } - MessageUtil.sendEmbedForInteractionWithImage( - interaction, - deferred, - "Currently 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" - ) - } -} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/PlayCommand.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/PlayCommand.kt deleted file mode 100644 index cc48ceb..0000000 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/PlayCommand.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.commands.slash.music - -import de.limited_dev.botendo.Bot.lava -import de.limited_dev.botendo.commands.slash.component.SlashCommand -import de.limited_dev.botendo.commands.slash.component.options.CommandOption -import de.limited_dev.botendo.commands.slash.component.options.OptionType -import de.limited_dev.botendo.commands.slash.music.component.MusicManager -import de.limited_dev.botendo.util.MessageUtil -import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior -import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction -import dev.schlaubi.lavakord.audio.Link - -class PlayCommand : SlashCommand( - "play", - "Play music", - listOf(CommandOption("linkquery", "Either a search query or a Link", true, OptionType.STRING)) -) { - override suspend fun onSlashCommand( - interaction: GuildChatInputCommandInteraction, - deferred: DeferredPublicMessageInteractionResponseBehavior, - args: Map - ) { - val guildId = interaction.guildId - val link = lava.getLink(guildId.toString()) - - val voiceState = interaction.user.getVoiceStateOrNull() - if (voiceState == null) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "You are not connected to a VC", - "Please connect to a VC" - ) - return - } - - val channelId = voiceState.channelId - - if (link.state != Link.State.CONNECTED) { - link.connectAudio(channelId!!.value) - } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "You are not in my VC", - "We are not in the same VC and therefore, you cannot play any music" - ) - return - } - - val query = args[this.options!![0]] - val search = if (query!!.startsWith("http")) { - query - } else { - "ytsearch:$query" - } - MessageUtil.sendEmbedForInteraction(interaction, deferred, "Searching...", "We are looking for $query") - MusicManager.addToQueue(interaction, deferred, link, search) - } -} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/QueueCommand.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/QueueCommand.kt deleted file mode 100644 index e5f0404..0000000 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/QueueCommand.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.commands.slash.music - -import de.limited_dev.botendo.Bot -import de.limited_dev.botendo.commands.slash.component.SlashCommand -import de.limited_dev.botendo.commands.slash.component.options.CommandOption -import de.limited_dev.botendo.commands.slash.music.component.MusicManager -import de.limited_dev.botendo.util.MessageUtil -import de.limited_dev.botendo.util.TimeUtil -import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior -import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction -import dev.schlaubi.lavakord.audio.Link - -class QueueCommand : SlashCommand("queue", "Show whats up next", null) { - override suspend fun onSlashCommand( - interaction: GuildChatInputCommandInteraction, - deferred: DeferredPublicMessageInteractionResponseBehavior, - args: Map - ) { - val guildId = interaction.guildId - val link = Bot.lava.getLink(guildId.toString()) - val player = link.player - if (link.state != Link.State.CONNECTED) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "Not connected", - "I'm not in a VC and therefore, I am not playing anything." - ) - return - } - val track = player.playingTrack - if (track == null) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "Queue empty", - "I'm not playing anything currently" - ) - return - } - val gts = MusicManager.getGuildTrackScheduler(interaction.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" - } - MessageUtil.sendEmbedForInteraction(interaction, deferred, "Queue", desc) - } -} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/SkipCommand.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/SkipCommand.kt deleted file mode 100644 index f74a2fd..0000000 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/SkipCommand.kt +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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.commands.slash.music - -import de.limited_dev.botendo.Bot -import de.limited_dev.botendo.commands.slash.component.SlashCommand -import de.limited_dev.botendo.commands.slash.component.options.CommandOption -import de.limited_dev.botendo.commands.slash.music.component.MusicManager -import de.limited_dev.botendo.util.MessageUtil -import de.limited_dev.botendo.util.TimeUtil -import de.limited_dev.botendo.util.UrlUtil -import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior -import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction -import dev.schlaubi.lavakord.audio.Link - -class SkipCommand : SlashCommand("skip", "Skip to the next song in queue", null) { - override suspend fun onSlashCommand( - interaction: GuildChatInputCommandInteraction, - deferred: DeferredPublicMessageInteractionResponseBehavior, - args: Map - ) { - val guildId = interaction.guildId - val link = Bot.lava.getLink(guildId.toString()) - val player = link.player - val voiceState = interaction.user.getVoiceStateOrNull() - if (voiceState == null) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "You are not connected to a VC", - "Please connect to a VC" - ) - return - } - - val channelId = voiceState.channelId - if (link.state != Link.State.CONNECTED) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "Not connected", - "I'm not in a VC and therefore, I am not playing anything." - ) - return - } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "You are not in my VC", - "We are not in the same VC and therefore, you cannot control the music" - ) - return - } - var track = player.playingTrack - if (track == null) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "Not playing", - "I'm not playing anything currently" - ) - return - } - val gts = MusicManager.getGuildTrackScheduler(interaction.guild.asGuild(), player) - track = gts.getHead().toTrack() - gts.playNext() - MessageUtil.sendEmbedForInteractionWithImage( - interaction, - deferred, - "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" - ) - } -} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/StopCommand.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/StopCommand.kt deleted file mode 100644 index cd46ffb..0000000 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/StopCommand.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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.commands.slash.music - -import de.limited_dev.botendo.Bot -import de.limited_dev.botendo.commands.slash.component.SlashCommand -import de.limited_dev.botendo.commands.slash.component.options.CommandOption -import de.limited_dev.botendo.commands.slash.music.component.MusicManager -import de.limited_dev.botendo.util.MessageUtil -import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior -import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction -import dev.schlaubi.lavakord.audio.Link - -class StopCommand : SlashCommand("stop", "Stop playing and start leavin'", null) { - override suspend fun onSlashCommand( - interaction: GuildChatInputCommandInteraction, - deferred: DeferredPublicMessageInteractionResponseBehavior, - args: Map - ) { - val guildId = interaction.guildId - val link = Bot.lava.getLink(guildId.toString()) - val player = link.player - - val voiceState = interaction.user.getVoiceStateOrNull() - if (voiceState == null) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "You are not connected to a VC", - "Please connect to my VC" - ) - return - } - - val channelId = voiceState.channelId - if (link.state != Link.State.CONNECTED) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "Not connected", - "I'm not in a VC and therefore, I am not playing anything." - ) - return - } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "You are not in my VC", - "We are not in the same VC" - ) - return - } - player.stopTrack() - link.destroy() - MusicManager.getGuildTrackScheduler(interaction.getGuild(), player).clear() - MessageUtil.sendEmbedForInteraction(interaction, deferred, "I stopped and left", "just like your girlfriend") - } -} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/MusicManager.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/MusicManager.kt deleted file mode 100644 index e916542..0000000 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/MusicManager.kt +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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.commands.slash.music.component - -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.entity.Snowflake -import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior -import dev.kord.core.entity.Guild -import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction -import dev.schlaubi.lavakord.audio.Link -import dev.schlaubi.lavakord.audio.player.Player -import dev.schlaubi.lavakord.rest.TrackResponse -import dev.schlaubi.lavakord.rest.loadItem - -object MusicManager { - private var musicManagerMap: MutableMap = mutableMapOf() - - fun getGuildTrackScheduler(guild: Guild, player: Player): GuildTrackScheduler { - return musicManagerMap.computeIfAbsent(guild.id) { - GuildTrackScheduler(player) - } - } - - - suspend fun addToQueue( - interaction: GuildChatInputCommandInteraction, - deferred: DeferredPublicMessageInteractionResponseBehavior, - link: Link, - search: String - ) { - addToQueue(interaction, deferred, link, search, false) - } - - suspend fun addToQueue( - interaction: GuildChatInputCommandInteraction, - deferred: DeferredPublicMessageInteractionResponseBehavior, - link: Link, - search: String, - silent: Boolean - ) { - val player = link.player - val item = link.loadItem(search) - val gts = getGuildTrackScheduler(interaction.getGuild(), player) - - gts.addEvents() - - when (item.loadType) { - TrackResponse.LoadType.TRACK_LOADED -> { - gts.queue(item.track) - if (!silent) - MessageUtil.sendEmbedForInteractionWithImage( - interaction, - deferred, - "Queuing track from link", - "**${item.track.info.title}**\n*Queue*\nby ${item.track.info.author} :: ${ - TimeUtil.getTimeFormatedRaw( - item.track.info.length - ) - }\n" + - ">>>${item.track.info.uri}", - "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg" - ) - } - - TrackResponse.LoadType.PLAYLIST_LOADED -> { - val l = item.tracks.reversed() - for (partialTrack in l) { - gts.queue(partialTrack) - } - if (!silent) - MessageUtil.sendEmbedForInteractionWithImage( - interaction, - deferred, - "Queuing playlist from link", - "**${item.tracks.first().info.title}**\n*${item.playlistInfo.name}*\nby ${item.tracks.first().info.author} :: ${ - TimeUtil.getTimeFormatedRaw( - item.tracks.first().info.length - ) - }\n" + - ">>>${item.tracks.first().info.uri}", - "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.tracks.first().info.uri) + "/maxresdefault.jpg" - ) - } - - TrackResponse.LoadType.SEARCH_RESULT -> { - gts.queue(item.tracks.first()) - if (!silent) - MessageUtil.sendEmbedForInteractionWithImage( - interaction, - deferred, - "Queuing track from query", - "**${item.tracks.first().info.title}**\n*Queue*\nby ${item.tracks.first().info.author} :: ${ - TimeUtil.getTimeFormatedRaw( - item.tracks.first().info.length - ) - }\n" + - ">>>${item.tracks.first().info.uri}", - "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.tracks.first().info.uri) + "/maxresdefault.jpg" - ) - } - - TrackResponse.LoadType.NO_MATCHES -> { - if (!silent) - MessageUtil.sendEmbedForInteraction(interaction, deferred, "Not found", "There were no matches.") - } - - TrackResponse.LoadType.LOAD_FAILED -> { - if (!silent) - MessageUtil.sendEmbedForInteraction( - interaction, - deferred, - "Load failed", - "There was an error while loading." - ) - } - } - } -} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/util/InfoCommand.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/util/InfoCommand.kt deleted file mode 100644 index 7daa0fe..0000000 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/util/InfoCommand.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.commands.slash.util - -import de.limited_dev.botendo.build.BuildConstants -import de.limited_dev.botendo.commands.slash.component.SlashCommand -import de.limited_dev.botendo.commands.slash.component.options.CommandOption -import de.limited_dev.botendo.util.MessageUtil -import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior -import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction - -class InfoCommand : SlashCommand("info", "Shows infos about the bot", null) { - override suspend fun onSlashCommand( - interaction: GuildChatInputCommandInteraction, - deferred: DeferredPublicMessageInteractionResponseBehavior, - args: Map - ) { - MessageUtil.sendEmbedForInteraction(interaction, deferred, "Botendo v5", "ver." + BuildConstants.version) - } -} diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExt.kt new file mode 100644 index 0000000..c243c27 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExt.kt @@ -0,0 +1,72 @@ +/* + * 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.music + +import com.kotlindiscord.kord.extensions.extensions.Extension +import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import de.limited_dev.botendo.Bot +import de.limited_dev.botendo.util.MessageUtil +import de.limited_dev.botendo.util.TimeUtil +import de.limited_dev.botendo.util.UrlUtil +import dev.schlaubi.lavakord.audio.Link +import dev.schlaubi.lavakord.kord.getLink + +class NowPlayingExt : Extension() { + override val name = "nowplaying" + override suspend fun setup() { + publicSlashCommand { + name = "nowplaying" + description = "Show what's currently playing" + this.action { + val guildId = this.guild!!.id + val link = Bot.lava.getLink(guildId) + val player = link.player + if (link.state != Link.State.CONNECTED) { + MessageUtil.sendEmbedForPublicSlashCommand( + this, + "Not connected", + "I'm not in a VC and therefore, I am not playing anything." + ) + return@action + } + val track = player.playingTrack + if (track == null) { + MessageUtil.sendEmbedForPublicSlashCommand( + this, + "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.length.inWholeMilliseconds + ) + }\n" + + ">>>${track.uri}", + "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg" + ) + } + } + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExt.kt new file mode 100644 index 0000000..fb2060d --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExt.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.extensions.music + +import com.kotlindiscord.kord.extensions.commands.Arguments +import com.kotlindiscord.kord.extensions.commands.converters.impl.string +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.MessageUtil +import dev.schlaubi.lavakord.audio.Link +import dev.schlaubi.lavakord.kord.getLink + +class PlayExt : Extension() { + + override val name = "play" + + override suspend fun setup() { + publicSlashCommand(::PlayArgs) { + name = "play" + description = "Play music" + this.action { + val guildId = this.guild!!.id + val link = Bot.lava.getLink(guildId) + val u = this.user + val vcsUser = u.asMember(guildId).getVoiceStateOrNull() + if (vcsUser == null) { + this.respond { + embeds.add( + MessageUtil.getEmbed( + "You are not connected to a VC", + "Please connect to a VC", + u.asUser().username + "#" + u.asUser().discriminator + ) + ) + } + return@action + } + + val channelId = vcsUser.channelId + + if (link.state != Link.State.CONNECTED) { + link.connectAudio(channelId!!.value) + } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { + this.respond { + embeds.add( + MessageUtil.getEmbed( + "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 + ) + ) + } + return@action + } + + val query = arguments.linkquery + val search = if (query.startsWith("http")) { + query + } else { + "ytsearch:$query" + } + this.respond { + embeds.add( + MessageUtil.getEmbed( + "Searching...", + "We are looking for $query", + u.asUser().username + "#" + u.asUser().discriminator + ) + ) + } + MusicManager.addToQueue(this, link, search) + + } + } + } + + inner class PlayArgs : Arguments() { + val linkquery by string { + name = "linkqery" + description = "Song link or search query" + } + } +} + diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExt.kt new file mode 100644 index 0000000..ce29e01 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExt.kt @@ -0,0 +1,71 @@ +/* + * 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.music + +import com.kotlindiscord.kord.extensions.extensions.Extension +import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import de.limited_dev.botendo.Bot +import de.limited_dev.botendo.extensions.music.components.MusicManager +import de.limited_dev.botendo.util.MessageUtil +import de.limited_dev.botendo.util.TimeUtil +import dev.schlaubi.lavakord.audio.Link + +class QueueExt : Extension() { + override val name = "queue" + override suspend fun setup() { + publicSlashCommand { + name = "queue" + description = "Show whats up next" + this.action { + val guildId = this.guild!!.id + val link = Bot.lava.getLink(guildId.toString()) + val player = link.player + if (link.state != Link.State.CONNECTED) { + MessageUtil.sendEmbedForPublicSlashCommand( + this, + "Not connected", + "I'm not in a VC and therefore, I am not playing anything." + ) + return@action + } + val track = player.playingTrack + if (track == null) { + MessageUtil.sendEmbedForPublicSlashCommand( + this, + "Queue empty", + "I'm not playing anything currently" + ) + return@action + } + val gts = MusicManager.getGuildTrackScheduler(this.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" + } + MessageUtil.sendEmbedForPublicSlashCommand(this, "Queue", desc) + + } + } + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExt.kt new file mode 100644 index 0000000..c274277 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExt.kt @@ -0,0 +1,95 @@ +/* + * 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.music + +import com.kotlindiscord.kord.extensions.extensions.Extension +import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import de.limited_dev.botendo.Bot +import de.limited_dev.botendo.extensions.music.components.MusicManager +import de.limited_dev.botendo.util.MessageUtil +import de.limited_dev.botendo.util.TimeUtil +import de.limited_dev.botendo.util.UrlUtil +import dev.schlaubi.lavakord.audio.Link + +class SkipExt : Extension() { + override val name = "skip" + override suspend fun setup() { + publicSlashCommand { + name = "skip" + description = "Skip to the next song in queue" + this.action { + val guildId = this.guild!!.id + val link = Bot.lava.getLink(guildId.toString()) + val player = link.player + val u = this.user + val voiceState = u.asMember(guildId).getVoiceStateOrNull() + if (voiceState == null) { + MessageUtil.sendEmbedForPublicSlashCommand( + this, + "You are not connected to a VC", + "Please connect to a VC" + ) + return@action + } + + val channelId = voiceState.channelId + if (link.state != Link.State.CONNECTED) { + MessageUtil.sendEmbedForPublicSlashCommand( + this, + "Not connected", + "I'm not in a VC and therefore, I am not playing anything." + ) + return@action + } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { + MessageUtil.sendEmbedForPublicSlashCommand( + this, + "You are not in my VC", + "We are not in the same VC and therefore, you cannot control the music" + ) + return@action + } + var track = player.playingTrack + if (track == null) { + MessageUtil.sendEmbedForPublicSlashCommand( + this, + "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" + + ) + } + } + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExt.kt new file mode 100644 index 0000000..8a4292c --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExt.kt @@ -0,0 +1,92 @@ +/* + * 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.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.MessageUtil +import dev.schlaubi.lavakord.audio.Link +import dev.schlaubi.lavakord.kord.getLink + +class StopExt : Extension() { + override val name = "stop" + override suspend fun setup() { + publicSlashCommand { + name = "stop" + description = "Stop playing and start leavin'" + this.action { + val guildId = this.guild!!.id + val link = Bot.lava.getLink(guildId) + val player = link.player + val u = this.user + val vcsUser = u.asMember(guildId).getVoiceStateOrNull() + if (vcsUser == null) { + this.respond { + this.embeds.add( + MessageUtil.getEmbed( + "You are not connected to a VC", + "Please connect to my VC", u.asUser().username + "#" + u.asUser().discriminator + ) + ) + } + return@action + } + val channelId = vcsUser.channelId + if (link.state != Link.State.CONNECTED) { + this.respond { + this.embeds.add( + MessageUtil.getEmbed( + "Not connected", + "I'm not in a VC and therefore, I am not playing anything.", + u.asUser().username + "#" + u.asUser().discriminator + ) + ) + } + return@action + } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { + this.respond { + this.embeds.add( + MessageUtil.getEmbed( + "You are not in my VC", + "We are not in the same VC", u.asUser().username + "#" + u.asUser().discriminator + ) + ) + } + return@action + } + player.stopTrack() + link.destroy() + MusicManager.getGuildTrackScheduler(this.getGuild()!!.asGuild(), player).clear() + this.respond { + this.embeds.add( + MessageUtil.getEmbed( + "I stopped and left", + "just like your girlfriend", + u.asUser().username + "#" + u.asUser().discriminator + ) + ) + } + } + } + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/GuildTrackScheduler.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/GuildTrackScheduler.kt similarity index 98% rename from src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/GuildTrackScheduler.kt rename to src/main/kotlin/de/limited_dev/botendo/extensions/music/components/GuildTrackScheduler.kt index c9ca8e9..0cd329f 100644 --- a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/GuildTrackScheduler.kt +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/GuildTrackScheduler.kt @@ -17,7 +17,7 @@ * */ -package de.limited_dev.botendo.commands.slash.music.component +package de.limited_dev.botendo.extensions.music.components import de.limited_dev.botendo.util.Logger import dev.schlaubi.lavakord.audio.TrackEndEvent @@ -110,3 +110,4 @@ class GuildTrackScheduler(val pl: Player) { return queue.first() } } + 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 new file mode 100644 index 0000000..bf7b133 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt @@ -0,0 +1,154 @@ +/* + * 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.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.util.MessageUtil +import de.limited_dev.botendo.util.TimeUtil +import de.limited_dev.botendo.util.UrlUtil +import dev.kord.common.entity.Snowflake +import dev.kord.core.entity.Guild +import dev.schlaubi.lavakord.audio.Link +import dev.schlaubi.lavakord.audio.player.Player +import dev.schlaubi.lavakord.rest.TrackResponse +import dev.schlaubi.lavakord.rest.loadItem + +object MusicManager { + private var musicManagerMap: MutableMap = mutableMapOf() + + fun getGuildTrackScheduler(guild: Guild, player: Player): GuildTrackScheduler { + return musicManagerMap.computeIfAbsent(guild.id) { + GuildTrackScheduler(player) + } + } + + + suspend fun addToQueue( + ctx: PublicSlashCommandContext, + link: Link, + search: String + ) { + addToQueue(ctx, link, search, false) + } + + suspend fun addToQueue( + ctx: PublicSlashCommandContext, + link: Link, + search: String, + silent: Boolean + ) { + val player = link.player + val item = link.loadItem(search) + val gts = getGuildTrackScheduler(ctx.guild!!.asGuild(), player) + val u = ctx.user.asUser() + + gts.addEvents() + + when (item.loadType) { + TrackResponse.LoadType.TRACK_LOADED -> { + gts.queue(item.track) + if (!silent) + ctx.respond { + this.embeds.add( + MessageUtil.getEmbedWithImage( + "Queuing track from link", + "**${item.track.info.title}**\n*Queue*\nby ${item.track.info.author} :: ${ + TimeUtil.getTimeFormatedRaw( + item.track.info.length + ) + }\n" + + ">>>${item.track.info.uri}", u.username + "#" + u.discriminator, + "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg" + ) + ) + } + } + + TrackResponse.LoadType.PLAYLIST_LOADED -> { + val l = item.tracks.reversed() + for (partialTrack in l) { + gts.queue(partialTrack) + } + if (!silent) + ctx.respond { + this.embeds.add( + MessageUtil.getEmbedWithImage( + "Queuing playlist from link", + "**${item.tracks.first().info.title}**\n*${item.playlistInfo.name}*\nby ${item.tracks.first().info.author} :: ${ + TimeUtil.getTimeFormatedRaw( + item.tracks.first().info.length + ) + }\n" + + ">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator, + "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg" + ) + ) + } + } + + TrackResponse.LoadType.SEARCH_RESULT -> { + gts.queue(item.tracks.first()) + if (!silent) + ctx.respond { + this.embeds.add( + MessageUtil.getEmbedWithImage( + "Queuing track from query", + "**${item.tracks.first().info.title}**\n*Queue*\nby ${item.tracks.first().info.author} :: ${ + TimeUtil.getTimeFormatedRaw( + item.tracks.first().info.length + ) + }\n" + + ">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator, + "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.tracks.first().info.uri) + "/maxresdefault.jpg" + ) + ) + } + } + + TrackResponse.LoadType.NO_MATCHES -> { + if (!silent) + ctx.respond { + this.embeds.add( + MessageUtil.getEmbed( + "Not found", + "There were no matches.", + u.username + "#" + u.discriminator + ) + ) + } + } + + TrackResponse.LoadType.LOAD_FAILED -> { + if (!silent) + ctx.respond { + this.embeds.add( + MessageUtil.getEmbed( + "Load failed", + "There was an error while loading.", u.username + "#" + u.discriminator + ) + ) + } + } + } + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExt.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExt.kt new file mode 100644 index 0000000..00909b9 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExt.kt @@ -0,0 +1,44 @@ +/* + * 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.build.BuildConstants +import de.limited_dev.botendo.util.MessageUtil + +class InfoExt : Extension() { + override val name = "info" + override suspend fun setup() { + publicSlashCommand { + name = "info" + description = "Show infos about the bot" + this.action { + MessageUtil.sendEmbedForPublicSlashCommand( + this, "Botendo", + "Botendo ***v." + BuildConstants.version + "***\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/util/MessageUtil.kt b/src/main/kotlin/de/limited_dev/botendo/util/MessageUtil.kt index 67f732f..cc8aeef 100644 --- a/src/main/kotlin/de/limited_dev/botendo/util/MessageUtil.kt +++ b/src/main/kotlin/de/limited_dev/botendo/util/MessageUtil.kt @@ -19,9 +19,10 @@ package de.limited_dev.botendo.util -import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior -import dev.kord.core.behavior.interaction.response.respond -import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction +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.rest.builder.message.EmbedBuilder import java.time.LocalDateTime import java.time.format.DateTimeFormatter @@ -29,43 +30,41 @@ import java.time.format.DateTimeFormatter object MessageUtil { private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss") - suspend fun sendEmbedForInteraction( - interaction: GuildChatInputCommandInteraction, - deferred: DeferredPublicMessageInteractionResponseBehavior, + suspend fun sendEmbedForPublicSlashCommand( + ctx: PublicSlashCommandContext, title: String, description: String ) { - deferred.respond { - embeds = mutableListOf( + ctx.respond { + embeds.add( getEmbed( title, description, - interaction.user.username + "#" + interaction.user.discriminator + ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator ) ) } } - suspend fun sendEmbedForInteractionWithImage( - interaction: GuildChatInputCommandInteraction, - deferred: DeferredPublicMessageInteractionResponseBehavior, + suspend fun sendEmbedForPublicSlashCommandWithImage( + ctx: PublicSlashCommandContext, title: String, description: String, thumbnailUrl: String ) { - deferred.respond { - embeds = mutableListOf( + ctx.respond { + embeds.add( getEmbedWithImage( title, description, - interaction.user.username + "#" + interaction.user.discriminator, + ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator, thumbnailUrl ) ) } } - private fun getEmbed(title: String, description: String, source: String): EmbedBuilder { + fun getEmbed(title: String, description: String, source: String): EmbedBuilder { val now: LocalDateTime = LocalDateTime.now() val ebb = EmbedBuilder() ebb.title = title @@ -75,7 +74,7 @@ object MessageUtil { return ebb } - private fun getEmbedWithImage( + fun getEmbedWithImage( title: String, description: String, source: String, diff --git a/src/main/kotlin/de/limited_dev/botendo/util/Status.kt b/src/main/kotlin/de/limited_dev/botendo/util/Status.kt index 98972b7..f8d6201 100644 --- a/src/main/kotlin/de/limited_dev/botendo/util/Status.kt +++ b/src/main/kotlin/de/limited_dev/botendo/util/Status.kt @@ -19,13 +19,12 @@ package de.limited_dev.botendo.util -import de.limited_dev.botendo.Bot - object Status { //TODO: impl. suspend fun updateStatus() { - Bot.kord.editPresence { + /* Bot.kord.editPresence { this.playing("") } + */ } } diff --git a/src/main/resources/simplelogger.properties b/src/main/resources/simplelogger.properties index 1a45d23..d92ae71 100644 --- a/src/main/resources/simplelogger.properties +++ b/src/main/resources/simplelogger.properties @@ -16,5 +16,3 @@ # along with this program. If not, see . # # -org.slf4j.simpleLogger.defaultLogLevel=trace -org.slf4j.simpleLogger.showDateTime=true