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 "6th times the charm" ~ me
A Discord music bot, written in Kotlin using the kord library. 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"/> [![Latest Release](https://gitlab.com/moonleay/botendo/-/badges/release.svg)](https://gitlab.com/moonleay/botendo/-/releases)
<img src="https://img.shields.io/badge/0%25-optimized-orange" alt="0% optimized"/> [![pipeline status](https://gitlab.com/moonleay/botendo/badges/master/pipeline.svg)](https://gitlab.com/moonleay/botendo/-/commits/master)
<img src="https://img.shields.io/badge/fuck%20it-ship%20it-orange" alt="fuck it, ship it"/> [![coverage report](https://gitlab.com/moonleay/botendo/badges/master/coverage.svg)](https://gitlab.com/moonleay/botendo/-/commits/master)
</div>
## Contributors ## Contributors
@ -21,13 +20,14 @@ A Discord music bot, written in Kotlin using the kord library.
## Known issues ## 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 & Features
- Commands - Commands
- info -- Show basic infos about the bot - info -- Show basic infos about the bot
- play -- Play a song - 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 - stop -- Stop playing a song and leave the vc
- skip -- Skip to the next song - skip -- Skip to the next song
- queue -- Show what songs are next up - queue -- Show what songs are next up

View file

@ -30,10 +30,10 @@ plugins {
//Botendo version 6 //Botendo version 6
val ownerID = 372703841151614976L 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" } version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_SHORT_SHA")}-prod" }
?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" } ?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" }
?: "6.3.3" ?: "6.4.0"
val kordver = "1.5.6" val kordver = "1.5.6"
val lavaver = "4.0.0" val lavaver = "4.0.0"
@ -115,7 +115,7 @@ tasks {
withType<Jar> { withType<Jar> {
manifest { manifest {
attributes["Main-Class"] = "de.limited_dev.botendo.MainKt" attributes["Main-Class"] = "net.moonleay.botendo.MainKt"
} }
// To add all of the dependencies // To add all of the dependencies
from(sourceSets.main.get().output) 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 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.common.Color
import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.event.interaction.ButtonInteractionCreateEvent import dev.kord.core.event.interaction.ButtonInteractionCreateEvent
import dev.kord.core.on import dev.kord.core.on
import dev.schlaubi.lavakord.LavaKord import dev.schlaubi.lavakord.LavaKord
import dev.schlaubi.lavakord.kord.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 { object Bot {
//The kord object gets set at app launch //The kord object gets set at app launch
@ -64,7 +62,7 @@ object Bot {
add(::SkipExtension) add(::SkipExtension)
add(::NowPlayingExtension) add(::NowPlayingExtension)
add(::QueueExtension) add(::QueueExtension)
add(::PotatoExtension) add(::UpsertExtension)
} }
this.presence { this.presence {
@ -84,7 +82,7 @@ object Bot {
val response = inter.deferPublicResponse() val response = inter.deferPublicResponse()
val u = inter.user val u = inter.user
val g = this.interaction.getOriginalInteractionResponse().getGuild() 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) if (b.id != inter.componentId)
continue continue
b.onInteraction(response, g, u) b.onInteraction(response, g, u)

View file

@ -17,9 +17,7 @@
* *
*/ */
package de.limited_dev.botendo package net.moonleay.botendo
import de.limited_dev.botendo.build.BuildConstants
///Show the splash and launch the Bot ///Show the splash and launch the Bot
@ -34,6 +32,6 @@ suspend fun main() {
"M#########M \n" + "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() 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.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.entity.Guild 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 { 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.common.Color
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.behavior.interaction.response.respond 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.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow import dev.kord.rest.builder.message.modify.actionRow
import dev.schlaubi.lavakord.audio.Link 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( override suspend fun onInteraction(
response: DeferredPublicMessageInteractionResponseBehavior, response: DeferredPublicMessageInteractionResponseBehavior,
guild: Guild, guild: Guild,
user: User user: User
) { ) {
val guildId = guild.id 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 player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull() val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) { 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.common.Color
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.behavior.interaction.response.respond 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.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow import dev.kord.rest.builder.message.modify.actionRow
import dev.schlaubi.lavakord.audio.Link 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( override suspend fun onInteraction(
response: DeferredPublicMessageInteractionResponseBehavior, response: DeferredPublicMessageInteractionResponseBehavior,
guild: Guild, guild: Guild,
user: User user: User
) { ) {
val guildId = guild.id 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 player = link.player
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
response.respond { 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.common.Color
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.behavior.interaction.response.respond 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.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow import dev.kord.rest.builder.message.modify.actionRow
import dev.schlaubi.lavakord.audio.Link 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( override suspend fun onInteraction(
response: DeferredPublicMessageInteractionResponseBehavior, response: DeferredPublicMessageInteractionResponseBehavior,
guild: Guild, guild: Guild,
user: User user: User
) { ) {
val guildId = guild.id 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 player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull() val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) { 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.common.Color
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.behavior.interaction.response.respond 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.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow import dev.kord.rest.builder.message.modify.actionRow
import dev.schlaubi.lavakord.audio.Link 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( override suspend fun onInteraction(
response: DeferredPublicMessageInteractionResponseBehavior, response: DeferredPublicMessageInteractionResponseBehavior,
guild: Guild, guild: Guild,
user: User user: User
) { ) {
val guildId = guild.id 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 player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull() val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) { if (voiceState == null) {
@ -100,7 +99,7 @@ class SkipButton : Button("btn.music.skip") {
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player) val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
if (!gts.isEmpty()) { if (!gts.isEmpty()) {
track = gts.getHead().toTrack() track = gts.getHead().toTrack()
gts.playNext() gts.playNext(link)
response.respond { response.respond {
this.embeds = mutableListOf( this.embeds = mutableListOf(
MessageUtil.getEmbedWithImage( MessageUtil.getEmbedWithImage(
@ -112,8 +111,8 @@ class SkipButton : Button("btn.music.skip") {
) )
}\n" + }\n" +
">>>${track.uri}", ">>>${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.common.Color
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.Guild import dev.kord.core.entity.Guild
import dev.kord.core.entity.User import dev.kord.core.entity.User
import dev.schlaubi.lavakord.audio.Link 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( override suspend fun onInteraction(
response: DeferredPublicMessageInteractionResponseBehavior, response: DeferredPublicMessageInteractionResponseBehavior,
guild: Guild, guild: Guild,
user: User user: User
) { ) {
val guildId = guild.id 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 player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull() val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) { 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.io.*
import java.util.* 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.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond 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.common.Color
import dev.kord.rest.builder.message.create.actionRow import dev.kord.rest.builder.message.create.actionRow
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.kord.getLink 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() { class NowPlayingExtension : Extension() {
override val name = "nowplaying" override val name = "nowplaying"
@ -41,7 +40,7 @@ class NowPlayingExtension : Extension() {
description = "Show what's currently playing" description = "Show what's currently playing"
this.action { this.action {
val guildId = this.guild!!.id 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 player = link.player
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
MessageUtil.sendEmbedForPublicSlashCommand( 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.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond 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.kord.common.Color
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.kord.getLink 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() { class PlayExtension : Extension() {
@ -37,12 +35,12 @@ class PlayExtension : Extension() {
override val name = "play" override val name = "play"
override suspend fun setup() { override suspend fun setup() {
publicSlashCommand(::PlayArgs) { publicSlashCommand(::LinkArguments) {
name = "play" name = "play"
description = "Play music" description = "Play music"
this.action { this.action {
val guildId = this.guild!!.id 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 u = this.user
val vcsUser = u.asMember(guildId).getVoiceStateOrNull() val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
if (vcsUser == null) { 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.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond 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.common.Color
import dev.kord.rest.builder.message.create.actionRow import dev.kord.rest.builder.message.create.actionRow
import dev.schlaubi.lavakord.audio.Link 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() { class QueueExtension : Extension() {
override val name = "queue" override val name = "queue"
@ -39,7 +38,7 @@ class QueueExtension : Extension() {
description = "Show whats up next" description = "Show whats up next"
this.action { this.action {
val guildId = this.guild!!.id 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 player = link.player
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
MessageUtil.sendEmbedForPublicSlashCommand( 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.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond 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.common.Color
import dev.kord.rest.builder.message.create.actionRow import dev.kord.rest.builder.message.create.actionRow
import dev.schlaubi.lavakord.audio.Link 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() { class SkipExtension : Extension() {
override val name = "skip" override val name = "skip"
@ -40,7 +39,7 @@ class SkipExtension : Extension() {
description = "Skip to the next song in queue" description = "Skip to the next song in queue"
this.action { this.action {
val guildId = this.guild!!.id 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 player = link.player
val u = this.user val u = this.user
val voiceState = u.asMember(guildId).getVoiceStateOrNull() val voiceState = u.asMember(guildId).getVoiceStateOrNull()
@ -85,7 +84,7 @@ class SkipExtension : Extension() {
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player) val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
if (!gts.isEmpty()) { if (!gts.isEmpty()) {
track = gts.getHead().toTrack() track = gts.getHead().toTrack()
gts.playNext() gts.playNext(link)
} else { } else {
player.stopTrack() player.stopTrack()
} }
@ -102,8 +101,8 @@ class SkipExtension : Extension() {
) )
}\n" + }\n" +
">>>${track.uri}", ">>>${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.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond 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.kord.common.Color
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.kord.getLink import dev.schlaubi.lavakord.kord.getLink
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.MessageUtil
class StopExtension : Extension() { class StopExtension : Extension() {
override val name = "stop" override val name = "stop"
@ -37,7 +36,7 @@ class StopExtension : Extension() {
description = "Stop playing and start leavin'" description = "Stop playing and start leavin'"
this.action { this.action {
val guildId = this.guild!!.id 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 player = link.player
val u = this.user val u = this.user
val vcsUser = u.asMember(guildId).getVoiceStateOrNull() 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.*
import dev.schlaubi.lavakord.audio.player.Player import dev.schlaubi.lavakord.audio.player.Player
import dev.schlaubi.lavakord.rest.models.PartialTrack import dev.schlaubi.lavakord.rest.models.PartialTrack
import net.moonleay.botendo.util.Logger
import java.util.concurrent.BlockingQueue import java.util.concurrent.BlockingQueue
import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.LinkedBlockingQueue
@ -33,19 +33,35 @@ class GuildTrackScheduler(val pl: Player) {
private var hasRegisteredEvents = false private var hasRegisteredEvents = false
///Add a track to queue and start playing, if there is no song currently playing ///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) { if (this.pl.playingTrack == null) {
play(track) play(track)
} else { return
}
when (type) {
MusicManager.AddType.QUEUE -> {
queue.offer(track) 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()) if (!queue.isEmpty())
this.pl.playTrack(queue.poll()) this.pl.playTrack(queue.poll())
else else {
this.pl.stopTrack() this.pl.stopTrack()
link.destroy()
clear()
}
} }
private suspend fun play(tr: PartialTrack) { private suspend fun play(tr: PartialTrack) {
@ -80,7 +96,7 @@ class GuildTrackScheduler(val pl: Player) {
return return
} }
Logger.out("Track has ended; Playing next...") 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.commands.application.slash.PublicSlashCommandContext
import com.kotlindiscord.kord.extensions.components.forms.ModalForm import com.kotlindiscord.kord.extensions.components.forms.ModalForm
import com.kotlindiscord.kord.extensions.types.respond 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.Color
import dev.kord.common.entity.Snowflake import dev.kord.common.entity.Snowflake
import dev.kord.core.entity.Guild 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.audio.player.Player
import dev.schlaubi.lavakord.rest.loadItem import dev.schlaubi.lavakord.rest.loadItem
import dev.schlaubi.lavakord.rest.models.TrackResponse 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 { object MusicManager {
private var musicManagerMap: MutableMap<Snowflake, GuildTrackScheduler> = mutableMapOf() private var musicManagerMap: MutableMap<Snowflake, GuildTrackScheduler> = mutableMapOf()
@ -47,17 +46,26 @@ object MusicManager {
suspend fun addToQueue( suspend fun addToQueue(
ctx: PublicSlashCommandContext<PlayExtension.PlayArgs, ModalForm>, ctx: PublicSlashCommandContext<LinkArguments, ModalForm>,
link: Link, link: Link,
search: String 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( suspend fun addToQueue(
ctx: PublicSlashCommandContext<PlayExtension.PlayArgs, ModalForm>, ctx: PublicSlashCommandContext<LinkArguments, ModalForm>,
link: Link, link: Link,
search: String, search: String,
type: AddType,
silent: Boolean silent: Boolean
) { ) {
val player = link.player val player = link.player
@ -69,13 +77,13 @@ object MusicManager {
when (item.loadType) { when (item.loadType) {
TrackResponse.LoadType.TRACK_LOADED -> { TrackResponse.LoadType.TRACK_LOADED -> {
gts.queue(item.track) gts.queue(item.track, type)
if (!silent) if (!silent)
ctx.respond { ctx.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbedWithImage( MessageUtil.getEmbedWithImage(
Color(0x52E01A), Color(0x52E01A),
"Queuing track from link", "${type.s} track from link",
"**${item.track.info.title}**\n*Queue*\nby ${item.track.info.author} ;: ${ "**${item.track.info.title}**\n*Queue*\nby ${item.track.info.author} ;: ${
TimeUtil.getTimeFormatedRaw( TimeUtil.getTimeFormatedRaw(
item.track.info.length item.track.info.length
@ -100,21 +108,20 @@ object MusicManager {
TrackResponse.LoadType.PLAYLIST_LOADED -> { TrackResponse.LoadType.PLAYLIST_LOADED -> {
val l = item.tracks.reversed() val l = item.tracks.reversed()
for (partialTrack in l) { for (partialTrack in l) {
gts.queue(partialTrack) gts.queue(partialTrack, type)
} }
if (!silent) if (!silent)
ctx.respond { ctx.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbedWithImage( MessageUtil.getEmbed(
Color(0x52E01A), 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} ;: ${ "**${item.tracks.first().info.title}**\n*${item.playlistInfo.name}*\nby ${item.tracks.first().info.author} ;: ${
TimeUtil.getTimeFormatedRaw( TimeUtil.getTimeFormatedRaw(
item.tracks.first().info.length item.tracks.first().info.length
) )
}\n" + }\n" +
">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator, ">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg"
) )
) )
@ -130,13 +137,13 @@ object MusicManager {
} }
TrackResponse.LoadType.SEARCH_RESULT -> { TrackResponse.LoadType.SEARCH_RESULT -> {
gts.queue(item.tracks.first()) gts.queue(item.tracks.first(), type)
if (!silent) if (!silent)
ctx.respond { ctx.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbedWithImage( MessageUtil.getEmbedWithImage(
Color(0x52E01A), Color(0x52E01A),
"Queuing track from query", "${type.s} track from query",
"**${item.tracks.first().info.title}**\n*Queue*\nby ${item.tracks.first().info.author} ;: ${ "**${item.tracks.first().info.title}**\n*Queue*\nby ${item.tracks.first().info.author} ;: ${
TimeUtil.getTimeFormatedRaw( TimeUtil.getTimeFormatedRaw(
item.tracks.first().info.length 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.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand 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 dev.kord.common.Color
import net.moonleay.botendo.util.MessageUtil
class InfoExtension : Extension() { class InfoExtension : Extension() {
override val name = "info" override val name = "info"
@ -34,11 +33,11 @@ class InfoExtension : Extension() {
this.action { this.action {
MessageUtil.sendEmbedForPublicSlashCommand( MessageUtil.sendEmbedForPublicSlashCommand(
this, Color(0x52E01A), "Botendo", this, Color(0x52E01A), "Botendo",
"Botendo ***v." + BuildConstants.version + "***\n" + "Botendo ***v." + net.moonleay.botendo.build.BuildConstants.version + "***\n" +
"Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" + "Kord-Extensions ***v." + net.moonleay.botendo.build.BuildConstants.kordVersion + "***\n" +
"lavalink.kt ***v." + BuildConstants.lavaVersion + "***\n" + "lavalink.kt ***v." + net.moonleay.botendo.build.BuildConstants.lavaVersion + "***\n" +
"Coroutines ***v." + BuildConstants.coroutinesVersion + "***\n\n\n" + "Coroutines ***v." + net.moonleay.botendo.build.BuildConstants.coroutinesVersion + "***\n\n\n" +
"***Bot made by moonleay#7441***\n" + "***Bot made by moonleay#0001***\n" +
"(c) 2023, licensed under GPL-3.0" "(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.common.entity.ButtonStyle
import dev.kord.rest.builder.component.ActionRowBuilder 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.LocalDateTime
import java.time.format.DateTimeFormatter 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.Arguments
import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext 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 { object Status {
//TODO: impl. //TODO: impl.

View file

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

View file

@ -17,7 +17,7 @@
* *
*/ */
package de.limited_dev.botendo.util package net.moonleay.botendo.util
object UrlUtil { object UrlUtil {
///Strip the video ID from a YouTube link ///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}"
}