From a9c4fe5da3a1bf801b3c394db951ac20c8f64e3b Mon Sep 17 00:00:00 2001 From: limited_dev Date: Tue, 28 Mar 2023 03:02:58 +0200 Subject: [PATCH] chore: changed back to lavalink.kt, started working on queue System, started working on music playing --- build.gradle.kts | 6 +- src/main/kotlin/de/limited_dev/botendo/Bot.kt | 28 +++- .../slash/component/SlashCommandManager.kt | 4 + .../commands/slash/music/PlayCommand.kt | 68 ++++++++++ .../commands/slash/music/StopCommand.kt | 42 ++++++ .../music/component/GuildMusicManager.kt | 23 ++++ .../slash/music/component/MusicManager.kt | 124 ++++++++++++++++++ .../slash/music/component/TrackScheduler.kt | 23 ++++ 8 files changed, 309 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/de/limited_dev/botendo/commands/slash/music/PlayCommand.kt create mode 100644 src/main/kotlin/de/limited_dev/botendo/commands/slash/music/StopCommand.kt create mode 100644 src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/GuildMusicManager.kt create mode 100644 src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/MusicManager.kt create mode 100644 src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/TrackScheduler.kt diff --git a/build.gradle.kts b/build.gradle.kts index 0a50ca7..29f7dea 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.1" -val lavaver = "1.3.77" +val lavaver = "3.8.0" val coroutinesver = "1.1.0" val mavenArtifact = "Botendo" @@ -69,7 +69,7 @@ repositories { dependencies { implementation("dev.kord:kord-core:$kordver") - implementation("com.sedmelluq:lavaplayer:$lavaver") + 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") @@ -117,7 +117,7 @@ tasks { withType { dependencies { - include(dependency("com.sedmelluq:lavaplayer:$lavaver")) + 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")) diff --git a/src/main/kotlin/de/limited_dev/botendo/Bot.kt b/src/main/kotlin/de/limited_dev/botendo/Bot.kt index 616379b..8e02011 100644 --- a/src/main/kotlin/de/limited_dev/botendo/Bot.kt +++ b/src/main/kotlin/de/limited_dev/botendo/Bot.kt @@ -23,6 +23,7 @@ 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 de.limited_dev.botendo.util.Logger +import de.limited_dev.botendo.util.MessageUtil import de.limited_dev.botendo.util.TokenManager import dev.kord.core.Kord import dev.kord.core.event.interaction.GuildChatInputCommandInteractionCreateEvent @@ -32,10 +33,13 @@ import dev.kord.gateway.PrivilegedIntent import dev.kord.rest.builder.interaction.boolean import dev.kord.rest.builder.interaction.integer import dev.kord.rest.builder.interaction.string +import dev.schlaubi.lavakord.LavaKord +import dev.schlaubi.lavakord.kord.lavakord object Bot { //The kord object gets set at app launch - var kord: Kord? = null + lateinit var kord: Kord + lateinit var lava: LavaKord suspend fun start() { Logger.out("Starting Bot...") @@ -48,14 +52,14 @@ object Bot { return } - //Register slash commands to bot & Discord + //Register slash commands to bot SlashCommandManager.register() //Add Bot token to kord kord = Kord(TokenManager.token) //Register Command Listener - kord!!.on { + kord.on { val response = interaction.deferPublicResponse() val command = interaction.command Logger.out("Command /${command.rootName}") @@ -81,12 +85,16 @@ object Bot { } } c.onSlashCommand(interaction, response, opt) - //response.respond { } + return@on } + MessageUtil.sendEmbedForInteraction( + interaction, response, "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 { + kord.createGlobalApplicationCommands { for (sc in SlashCommandManager.commands) { this.input(sc.name, sc.description, builder = { if (sc.options != null) { @@ -117,10 +125,18 @@ object Bot { } } + //Add LavaLink + lava = kord.lavakord() + + //Add the LavaLink node + lava.addNode("ws://192.168.178.2:2333", "youshallnotpass") + + + Logger.out("Logging in") //Start the bot - kord!!.login { + kord.login { // Load gateway privileges @OptIn(PrivilegedIntent::class) intents += Intent.GuildMembers 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 index 62bde2f..dcc3a67 100644 --- 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 @@ -19,6 +19,8 @@ package de.limited_dev.botendo.commands.slash.component +import de.limited_dev.botendo.commands.slash.music.PlayCommand +import de.limited_dev.botendo.commands.slash.music.StopCommand import de.limited_dev.botendo.commands.slash.util.InfoCommand object SlashCommandManager { @@ -27,5 +29,7 @@ object SlashCommandManager { fun register() { commands.add(InfoCommand()) + commands.add(PlayCommand()) + commands.add(StopCommand()) } } 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 new file mode 100644 index 0000000..bb8a009 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/PlayCommand.kt @@ -0,0 +1,68 @@ +/* + * 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.component.options.OptionType +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, + response: DeferredPublicMessageInteractionResponseBehavior, + args: Map + ) { + val guildId = interaction.guildId + val link = Bot.lava.getLink(guildId.toString()) + + val voiceState = interaction.user.getVoiceStateOrNull() + if (voiceState == null) { + MessageUtil.sendEmbedForInteraction( + interaction, + response, + "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) + } + + val query = args[this.options!![0]] + val search = if (query!!.startsWith("http")) { + query + } else { + "ytsearch:$query" + } + } +} 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 new file mode 100644 index 0000000..8bc0933 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/StopCommand.kt @@ -0,0 +1,42 @@ +/* + * 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 dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior +import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction + +class StopCommand : SlashCommand("stop", "Stop playing and start leavin'", null) { + override suspend fun onSlashCommand( + interaction: GuildChatInputCommandInteraction, + response: DeferredPublicMessageInteractionResponseBehavior, + args: Map + ) { + val guildId = interaction.guildId + val link = Bot.lava.getLink(guildId.toString()) + val player = link.player + player.stopTrack() + link.destroy() + MessageUtil.sendEmbedForInteraction(interaction, response, "I stopped and left", "just like your girlfriend") + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/GuildMusicManager.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/GuildMusicManager.kt new file mode 100644 index 0000000..24695e5 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/GuildMusicManager.kt @@ -0,0 +1,23 @@ +/* + * 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 + +class GuildMusicManager { +} 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 new file mode 100644 index 0000000..25d0efa --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/MusicManager.kt @@ -0,0 +1,124 @@ +/* + * 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 dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior +import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction +import dev.schlaubi.lavakord.audio.Link +import dev.schlaubi.lavakord.audio.TrackEndEvent +import dev.schlaubi.lavakord.audio.on +import dev.schlaubi.lavakord.rest.TrackResponse +import dev.schlaubi.lavakord.rest.loadItem + +object MusicManager { + private var musicManagerMap: MutableMap? = null + + init { + musicManagerMap = HashMap() + } + + suspend fun addToQueue( + interaction: GuildChatInputCommandInteraction, + response: DeferredPublicMessageInteractionResponseBehavior, + link: Link, + search: String + ) { + addToQueue(interaction, response, link, search, false) + } + + suspend fun addToQueue( + interaction: GuildChatInputCommandInteraction, + response: DeferredPublicMessageInteractionResponseBehavior, + link: Link, + search: String, + silent: Boolean + ) { + val player = link.player + val item = link.loadItem(search) + + player.on { + + } + + when (item.loadType) { + TrackResponse.LoadType.TRACK_LOADED -> { + player.playTrack(item.track) + if (!silent) + MessageUtil.sendEmbedForInteraction( + interaction, response, + "Playing track from link", + "**${item.track.info.title}**\n*Queue*\nby ${item.track.info.author} :: ${ + TimeUtil.getTimeFormatedRaw( + item.track.info.length + ) + }" + ) + } + + TrackResponse.LoadType.PLAYLIST_LOADED -> { + val l = item.tracks.asReversed() + for (p in l) { + player.playTrack(p) + } + if (!silent) + MessageUtil.sendEmbedForInteraction( + interaction, response, + "Playing 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 + ) + }" + ) + } + + TrackResponse.LoadType.SEARCH_RESULT -> { + player.playTrack(item.tracks.first()) + if (!silent) + MessageUtil.sendEmbedForInteraction( + interaction, response, + "Playing from query", + "**${item.tracks.first().info.title}**\n*Queue*\nby ${item.tracks.first().info.author} :: ${ + TimeUtil.getTimeFormatedRaw( + item.tracks.first().info.length + ) + }" + ) + } + + TrackResponse.LoadType.NO_MATCHES -> { + if (!silent) + MessageUtil.sendEmbedForInteraction(interaction, response, "Not found", "There were not matches.") + } + + TrackResponse.LoadType.LOAD_FAILED -> { + if (!silent) + MessageUtil.sendEmbedForInteraction( + interaction, + response, + "Load failed", + "There was an error while loading." + ) + } + } + } +} diff --git a/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/TrackScheduler.kt b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/TrackScheduler.kt new file mode 100644 index 0000000..1e07d70 --- /dev/null +++ b/src/main/kotlin/de/limited_dev/botendo/commands/slash/music/component/TrackScheduler.kt @@ -0,0 +1,23 @@ +/* + * 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 + +class TrackScheduler { +}