Merge branch 'master' into 'stable'

remove: removed potatoExtension

See merge request moonleay/botendo!4
This commit is contained in:
moonleay 2023-05-20 22:10:35 +00:00
commit 5014685e03
31 changed files with 329 additions and 235 deletions

View file

@ -3,11 +3,10 @@
"6th times the charm" ~ me
A Discord music bot, written in Kotlin using the kord library.
<div class="aside">
<img src="https://img.shields.io/badge/100%25-Selfmade-success" alt="100% Selfmade"/>
<img src="https://img.shields.io/badge/0%25-optimized-orange" alt="0% optimized"/>
<img src="https://img.shields.io/badge/fuck%20it-ship%20it-orange" alt="fuck it, ship it"/>
</div>
[![Latest Release](https://gitlab.com/moonleay/botendo/-/badges/release.svg)](https://gitlab.com/moonleay/botendo/-/releases)
[![pipeline status](https://gitlab.com/moonleay/botendo/badges/master/pipeline.svg)](https://gitlab.com/moonleay/botendo/-/commits/master)
[![coverage report](https://gitlab.com/moonleay/botendo/badges/master/coverage.svg)](https://gitlab.com/moonleay/botendo/-/commits/master)
## Contributors
@ -21,17 +20,18 @@ A Discord music bot, written in Kotlin using the kord library.
## Known issues
- None (currently). Report issues to issues@moonleay.net or moonleay#7441
- None (currently). Report issues to issues@moonleay.net or moonleay#0001
## Commands & Features
- Commands
- info -- Show basic infos about the bot
- play -- Play a song
- stop -- Stop playing a song and leave the vc
- skip -- Skip to the next song
- queue -- Show what songs are next up
- nowplaying -- Show what is currently playing
- info -- Show basic infos about the bot
- play -- Play a song and or add it to queue
- upsert -- Play a song next up
- stop -- Stop playing a song and leave the vc
- skip -- Skip to the next song
- queue -- Show what songs are next up
- nowplaying -- Show what is currently playing
- Features
- Button Controller -- You can control the currently playing music using buttons.

View file

@ -30,10 +30,10 @@ plugins {
//Botendo version 6
val ownerID = 372703841151614976L
group = "de.limited_dev.botendo"
group = "net.moonleay.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.3.3"
?: "6.4.0"
val kordver = "1.5.6"
val lavaver = "4.0.0"
@ -115,7 +115,7 @@ tasks {
withType<Jar> {
manifest {
attributes["Main-Class"] = "de.limited_dev.botendo.MainKt"
attributes["Main-Class"] = "net.moonleay.botendo.MainKt"
}
// To add all of the dependencies
from(sourceSets.main.get().output)

View file

@ -1,42 +0,0 @@
/*
* Botendo
* Copyright (C) 2023 moonleay
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
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"
override suspend fun setup() {
publicSlashCommand {
name = "potato"
description = "Potato"
this.action {
MessageUtil.sendEmbedForPublicSlashCommandWithImage(
this, Color(0xE0311A), "Potato",
"Potato",
"https://static.tumblr.com/c06d8e0928395746a63b9c5d3cb1ce66/sl9iajp/gxFmqk38z/tumblr_static_potato-equality.jpg"
)
}
}
}
}

View file

@ -17,22 +17,20 @@
*
*/
package de.limited_dev.botendo
package net.moonleay.botendo
import com.kotlindiscord.kord.extensions.ExtensibleBot
import de.limited_dev.botendo.buttons.ButtonManager
import de.limited_dev.botendo.data.CredentialManager
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.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
import dev.schlaubi.lavakord.kord.lavakord
import net.moonleay.botendo.data.CredentialManager
import net.moonleay.botendo.extensions.music.*
import net.moonleay.botendo.extensions.util.InfoExtension
import net.moonleay.botendo.util.Logger
import net.moonleay.botendo.util.MessageUtil
object Bot {
//The kord object gets set at app launch
@ -64,7 +62,7 @@ object Bot {
add(::SkipExtension)
add(::NowPlayingExtension)
add(::QueueExtension)
add(::PotatoExtension)
add(::UpsertExtension)
}
this.presence {
@ -84,7 +82,7 @@ object Bot {
val response = inter.deferPublicResponse()
val u = inter.user
val g = this.interaction.getOriginalInteractionResponse().getGuild()
for (b in ButtonManager.buttons) {
for (b in net.moonleay.botendo.buttons.ButtonManager.buttons) {
if (b.id != inter.componentId)
continue
b.onInteraction(response, g, u)

View file

@ -17,9 +17,7 @@
*
*/
package de.limited_dev.botendo
import de.limited_dev.botendo.build.BuildConstants
package net.moonleay.botendo
///Show the splash and launch the Bot
@ -34,6 +32,6 @@ suspend fun main() {
"M#########M \n" +
" "
)
println("Bot v.${BuildConstants.version}, Kord Extensions v.${BuildConstants.kordVersion}, LavaKord v.${BuildConstants.lavaVersion}, Coroutines v.${BuildConstants.coroutinesVersion}")
println("Bot v.${net.moonleay.botendo.build.BuildConstants.version}, Kord Extensions v.${net.moonleay.botendo.build.BuildConstants.kordVersion}, LavaKord v.${net.moonleay.botendo.build.BuildConstants.lavaVersion}, Coroutines v.${net.moonleay.botendo.build.BuildConstants.coroutinesVersion}")
Bot.start()
}

View file

@ -17,7 +17,7 @@
*
*/
package de.limited_dev.botendo.buttons
package net.moonleay.botendo.buttons
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.entity.Guild

View file

@ -17,10 +17,16 @@
*
*/
package de.limited_dev.botendo.buttons
package net.moonleay.botendo.buttons
import de.limited_dev.botendo.buttons.music.*
import net.moonleay.botendo.buttons.music.*
object ButtonManager {
val buttons = listOf(RepeatButton(), PauseButton(), SkipButton(), QueueButton(), StopButton())
val buttons = listOf(
RepeatButton(),
PauseButton(),
SkipButton(),
QueueButton(),
StopButton()
)
}

View file

@ -17,13 +17,8 @@
*
*/
package de.limited_dev.botendo.buttons.music
package net.moonleay.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
@ -31,15 +26,18 @@ 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
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil
import net.moonleay.botendo.util.MessageUtil
class PauseButton : Button("btn.music.pause") {
class PauseButton : net.moonleay.botendo.buttons.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 link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
val player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) {

View file

@ -17,14 +17,8 @@
*
*/
package de.limited_dev.botendo.buttons.music
package net.moonleay.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
@ -32,15 +26,19 @@ 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
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil
import net.moonleay.botendo.util.MessageUtil
import net.moonleay.botendo.util.TimeUtil
class QueueButton : Button("btn.music.queue") {
class QueueButton : net.moonleay.botendo.buttons.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 link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
val player = link.player
if (link.state == Link.State.NOT_CONNECTED) {
response.respond {

View file

@ -17,13 +17,8 @@
*
*/
package de.limited_dev.botendo.buttons.music
package net.moonleay.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
@ -31,15 +26,18 @@ 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
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil
import net.moonleay.botendo.util.MessageUtil
class RepeatButton : Button("btn.music.repeat") {
class RepeatButton : net.moonleay.botendo.buttons.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 link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
val player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) {

View file

@ -17,15 +17,9 @@
*
*/
package de.limited_dev.botendo.buttons.music
package net.moonleay.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
@ -33,15 +27,20 @@ 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
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil
import net.moonleay.botendo.util.MessageUtil
import net.moonleay.botendo.util.TimeUtil
import net.moonleay.botendo.util.UrlUtil
class SkipButton : Button("btn.music.skip") {
class SkipButton : net.moonleay.botendo.buttons.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 link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
val player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) {
@ -100,7 +99,7 @@ class SkipButton : Button("btn.music.skip") {
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
if (!gts.isEmpty()) {
track = gts.getHead().toTrack()
gts.playNext()
gts.playNext(link)
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbedWithImage(
@ -112,8 +111,8 @@ class SkipButton : Button("btn.music.skip") {
)
}\n" +
">>>${track.uri}",
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg",
user.asUser().username + "#" + user.asUser().discriminator
user.asUser().username + "#" + user.asUser().discriminator,
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
)
)

View file

@ -17,27 +17,25 @@
*
*/
package de.limited_dev.botendo.buttons.music
package net.moonleay.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
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.MessageUtil
class StopButton : Button("btn.music.stop") {
class StopButton : net.moonleay.botendo.buttons.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 link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
val player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) {

View file

@ -17,7 +17,7 @@
*
*/
package de.limited_dev.botendo.data
package net.moonleay.botendo.data
import java.io.*
import java.util.*

View file

@ -17,21 +17,20 @@
*
*/
package de.limited_dev.botendo.extensions.music
package net.moonleay.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
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil
import net.moonleay.botendo.util.MessageUtil
import net.moonleay.botendo.util.TimeUtil
import net.moonleay.botendo.util.UrlUtil
class NowPlayingExtension : Extension() {
override val name = "nowplaying"
@ -41,7 +40,7 @@ class NowPlayingExtension : Extension() {
description = "Show what's currently playing"
this.action {
val guildId = this.guild!!.id
val link = Bot.lava.getLink(guildId)
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
val player = link.player
if (link.state == Link.State.NOT_CONNECTED) {
MessageUtil.sendEmbedForPublicSlashCommand(

View file

@ -17,19 +17,17 @@
*
*/
package de.limited_dev.botendo.extensions.music
package net.moonleay.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.kord.common.Color
import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.kord.getLink
import net.moonleay.botendo.extensions.music.components.LinkArguments
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.MessageUtil
class PlayExtension : Extension() {
@ -37,12 +35,12 @@ class PlayExtension : Extension() {
override val name = "play"
override suspend fun setup() {
publicSlashCommand(::PlayArgs) {
publicSlashCommand(::LinkArguments) {
name = "play"
description = "Play music"
this.action {
val guildId = this.guild!!.id
val link = Bot.lava.getLink(guildId)
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
val u = this.user
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
if (vcsUser == null) {
@ -97,12 +95,5 @@ class PlayExtension : Extension() {
}
}
}
inner class PlayArgs : Arguments() {
val linkquery by string {
name = "linkqery"
description = "Song link or search query"
}
}
}

View file

@ -17,19 +17,18 @@
*
*/
package de.limited_dev.botendo.extensions.music
package net.moonleay.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
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil
import net.moonleay.botendo.util.MessageUtil
import net.moonleay.botendo.util.TimeUtil
class QueueExtension : Extension() {
override val name = "queue"
@ -39,7 +38,7 @@ class QueueExtension : Extension() {
description = "Show whats up next"
this.action {
val guildId = this.guild!!.id
val link = Bot.lava.getLink(guildId.toString())
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
val player = link.player
if (link.state == Link.State.NOT_CONNECTED) {
MessageUtil.sendEmbedForPublicSlashCommand(

View file

@ -17,20 +17,19 @@
*
*/
package de.limited_dev.botendo.extensions.music
package net.moonleay.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 net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil
import net.moonleay.botendo.util.MessageUtil
import net.moonleay.botendo.util.TimeUtil
import net.moonleay.botendo.util.UrlUtil
class SkipExtension : Extension() {
override val name = "skip"
@ -40,7 +39,7 @@ class SkipExtension : Extension() {
description = "Skip to the next song in queue"
this.action {
val guildId = this.guild!!.id
val link = Bot.lava.getLink(guildId.toString())
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
val player = link.player
val u = this.user
val voiceState = u.asMember(guildId).getVoiceStateOrNull()
@ -85,7 +84,7 @@ class SkipExtension : Extension() {
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
if (!gts.isEmpty()) {
track = gts.getHead().toTrack()
gts.playNext()
gts.playNext(link)
} else {
player.stopTrack()
}
@ -102,8 +101,8 @@ class SkipExtension : Extension() {
)
}\n" +
">>>${track.uri}",
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg",
user.asUser().username + "#" + user.asUser().discriminator
user.asUser().username + "#" + user.asUser().discriminator,
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
)
)

View file

@ -17,17 +17,16 @@
*
*/
package de.limited_dev.botendo.extensions.music
package net.moonleay.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.kord.common.Color
import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.kord.getLink
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.MessageUtil
class StopExtension : Extension() {
override val name = "stop"
@ -37,7 +36,7 @@ class StopExtension : Extension() {
description = "Stop playing and start leavin'"
this.action {
val guildId = this.guild!!.id
val link = Bot.lava.getLink(guildId)
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
val player = link.player
val u = this.user
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()

View file

@ -0,0 +1,99 @@
/*
* Botendo
* Copyright (C) 2023 moonleay
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
package net.moonleay.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 dev.kord.common.Color
import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.kord.getLink
import net.moonleay.botendo.extensions.music.components.LinkArguments
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.MessageUtil
class UpsertExtension : Extension() {
override val name = "upsert"
override suspend fun setup() {
publicSlashCommand(::LinkArguments) {
name = "upsert"
description = "Upsert music"
this.action {
val guildId = this.guild!!.id
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
val u = this.user
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
if (vcsUser == null) {
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
)
)
}
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(
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
)
)
}
return@action
}
val query = arguments.linkquery
val search = if (query.startsWith("http")) {
query
} else {
"ytsearch:$query"
}
this.respond {
embeds.add(
MessageUtil.getEmbed(
Color(0xE0A81A),
"Searching...",
"We are looking for $query",
u.asUser().username + "#" + u.asUser().discriminator
)
)
}
MusicManager.upsertIntoQueue(this, link, search)
}
}
}
}

View file

@ -17,12 +17,12 @@
*
*/
package de.limited_dev.botendo.extensions.music.components
package net.moonleay.botendo.extensions.music.components
import de.limited_dev.botendo.util.Logger
import dev.schlaubi.lavakord.audio.*
import dev.schlaubi.lavakord.audio.player.Player
import dev.schlaubi.lavakord.rest.models.PartialTrack
import net.moonleay.botendo.util.Logger
import java.util.concurrent.BlockingQueue
import java.util.concurrent.LinkedBlockingQueue
@ -33,19 +33,35 @@ class GuildTrackScheduler(val pl: Player) {
private var hasRegisteredEvents = false
///Add a track to queue and start playing, if there is no song currently playing
suspend fun queue(track: PartialTrack) {
suspend fun queue(track: PartialTrack, type: MusicManager.AddType) {
if (this.pl.playingTrack == null) {
play(track)
} else {
queue.offer(track)
return
}
when (type) {
MusicManager.AddType.QUEUE -> {
queue.offer(track)
}
MusicManager.AddType.UPSERT -> {
val nq = LinkedBlockingQueue<PartialTrack>()
nq.offer(track)
for (t in queue.toList()) {
nq.offer(t)
}
queue = nq
}
}
}
suspend fun playNext() {
suspend fun playNext(link: Link) {
if (!queue.isEmpty())
this.pl.playTrack(queue.poll())
else
else {
this.pl.stopTrack()
link.destroy()
clear()
}
}
private suspend fun play(tr: PartialTrack) {
@ -80,7 +96,7 @@ class GuildTrackScheduler(val pl: Player) {
return
}
Logger.out("Track has ended; Playing next...")
playNext()
playNext(net.moonleay.botendo.Bot.lava.getLink(e.guildId))
}
}

View file

@ -0,0 +1,30 @@
/*
* Botendo
* Copyright (C) 2023 moonleay
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
package net.moonleay.botendo.extensions.music.components
import com.kotlindiscord.kord.extensions.commands.Arguments
import com.kotlindiscord.kord.extensions.commands.converters.impl.string
class LinkArguments : Arguments() {
val linkquery by string {
name = "linkqery"
description = "Song link or search query"
}
}

View file

@ -17,16 +17,11 @@
*
*/
package de.limited_dev.botendo.extensions.music.components
package net.moonleay.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.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
@ -35,6 +30,10 @@ import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.audio.player.Player
import dev.schlaubi.lavakord.rest.loadItem
import dev.schlaubi.lavakord.rest.models.TrackResponse
import net.moonleay.botendo.util.ButtonUtil
import net.moonleay.botendo.util.MessageUtil
import net.moonleay.botendo.util.TimeUtil
import net.moonleay.botendo.util.UrlUtil
object MusicManager {
private var musicManagerMap: MutableMap<Snowflake, GuildTrackScheduler> = mutableMapOf()
@ -47,17 +46,26 @@ object MusicManager {
suspend fun addToQueue(
ctx: PublicSlashCommandContext<PlayExtension.PlayArgs, ModalForm>,
ctx: PublicSlashCommandContext<LinkArguments, ModalForm>,
link: Link,
search: String
) {
addToQueue(ctx, link, search, false)
addToQueue(ctx, link, search, AddType.QUEUE, false)
}
suspend fun upsertIntoQueue(
ctx: PublicSlashCommandContext<LinkArguments, ModalForm>,
link: Link,
search: String
) {
addToQueue(ctx, link, search, AddType.UPSERT, false)
}
suspend fun addToQueue(
ctx: PublicSlashCommandContext<PlayExtension.PlayArgs, ModalForm>,
ctx: PublicSlashCommandContext<LinkArguments, ModalForm>,
link: Link,
search: String,
type: AddType,
silent: Boolean
) {
val player = link.player
@ -69,13 +77,13 @@ object MusicManager {
when (item.loadType) {
TrackResponse.LoadType.TRACK_LOADED -> {
gts.queue(item.track)
gts.queue(item.track, type)
if (!silent)
ctx.respond {
this.embeds.add(
MessageUtil.getEmbedWithImage(
Color(0x52E01A),
"Queuing track from link",
"${type.s} track from link",
"**${item.track.info.title}**\n*Queue*\nby ${item.track.info.author} ;: ${
TimeUtil.getTimeFormatedRaw(
item.track.info.length
@ -100,21 +108,20 @@ object MusicManager {
TrackResponse.LoadType.PLAYLIST_LOADED -> {
val l = item.tracks.reversed()
for (partialTrack in l) {
gts.queue(partialTrack)
gts.queue(partialTrack, type)
}
if (!silent)
ctx.respond {
this.embeds.add(
MessageUtil.getEmbedWithImage(
MessageUtil.getEmbed(
Color(0x52E01A),
"Queuing playlist from link",
"${type.s} 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"
">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator
)
)
@ -130,13 +137,13 @@ object MusicManager {
}
TrackResponse.LoadType.SEARCH_RESULT -> {
gts.queue(item.tracks.first())
gts.queue(item.tracks.first(), type)
if (!silent)
ctx.respond {
this.embeds.add(
MessageUtil.getEmbedWithImage(
Color(0x52E01A),
"Queuing track from query",
"${type.s} track from query",
"**${item.tracks.first().info.title}**\n*Queue*\nby ${item.tracks.first().info.author} ;: ${
TimeUtil.getTimeFormatedRaw(
item.tracks.first().info.length
@ -186,4 +193,9 @@ object MusicManager {
}
}
}
enum class AddType(val s: String) {
QUEUE("Added"),
UPSERT("Upserted")
}
}

View file

@ -17,13 +17,12 @@
*
*/
package de.limited_dev.botendo.extensions.util
package net.moonleay.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
import dev.kord.common.Color
import net.moonleay.botendo.util.MessageUtil
class InfoExtension : Extension() {
override val name = "info"
@ -34,11 +33,11 @@ class InfoExtension : Extension() {
this.action {
MessageUtil.sendEmbedForPublicSlashCommand(
this, Color(0x52E01A), "Botendo",
"Botendo ***v." + BuildConstants.version + "***\n" +
"Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" +
"lavalink.kt ***v." + BuildConstants.lavaVersion + "***\n" +
"Coroutines ***v." + BuildConstants.coroutinesVersion + "***\n\n\n" +
"***Bot made by moonleay#7441***\n" +
"Botendo ***v." + net.moonleay.botendo.build.BuildConstants.version + "***\n" +
"Kord-Extensions ***v." + net.moonleay.botendo.build.BuildConstants.kordVersion + "***\n" +
"lavalink.kt ***v." + net.moonleay.botendo.build.BuildConstants.lavaVersion + "***\n" +
"Coroutines ***v." + net.moonleay.botendo.build.BuildConstants.coroutinesVersion + "***\n\n\n" +
"***Bot made by moonleay#0001***\n" +
"(c) 2023, licensed under GPL-3.0"
)
}

View file

@ -17,7 +17,7 @@
*
*/
package de.limited_dev.botendo.util
package net.moonleay.botendo.util
import dev.kord.common.entity.ButtonStyle
import dev.kord.rest.builder.component.ActionRowBuilder

View file

@ -17,7 +17,7 @@
*
*/
package de.limited_dev.botendo.util
package net.moonleay.botendo.util
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

View file

@ -17,7 +17,7 @@
*
*/
package de.limited_dev.botendo.util
package net.moonleay.botendo.util
import com.kotlindiscord.kord.extensions.commands.Arguments
import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext

View file

@ -17,7 +17,7 @@
*
*/
package de.limited_dev.botendo.util
package net.moonleay.botendo.util
object Status {
//TODO: impl.

View file

@ -17,7 +17,7 @@
*
*/
package de.limited_dev.botendo.util
package net.moonleay.botendo.util
import java.util.concurrent.TimeUnit

View file

@ -17,7 +17,7 @@
*
*/
package de.limited_dev.botendo.util
package net.moonleay.botendo.util
object UrlUtil {
///Strip the video ID from a YouTube link

View file

@ -1,28 +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 <https://www.gnu.org/licenses/>.
*
*/
package de.limited_dev.botendo.build
internal object BuildConstants {
const val version = "${version}"
const val ownerID = "${ownerID}"
const val kordVersion = "${kordversion}"
const val lavaVersion = "${lavaversion}"
const val coroutinesVersion = "${coroutinesversion}"
}

View file

@ -0,0 +1,28 @@
/*
* Botendo
* Copyright (C) 2023 moonleay
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
package net.moonleay.botendo.build
internal object BuildConstants {
const val version = "${version}"
const val ownerID = "${ownerID}"
const val kordVersion = "${kordversion}"
const val lavaVersion = "${lavaversion}"
const val coroutinesVersion = "${coroutinesversion}"
}