feat: added button controls for controlling music, added presence, added color codes to bot output, added some comments into the code

fix: fixed issues with skipping a song, when there is no next sond in the queue
chore: renamed Dockerfile, updated README.md

Signed-off-by: limited_dev <loginakkisativ@gmail.com>
This commit is contained in:
limited_dev 2023-04-26 17:48:53 +02:00
parent 7753f11e60
commit 465101f68a
24 changed files with 856 additions and 39 deletions

View file

@ -17,7 +17,7 @@ A Discord music bot, written in Kotlin using the kord library.
## Special Thanks to ## Special Thanks to
- HopeBaron for taking the time to help me fix this pos. - HopeBaron for helping me a whole lot
## Commands ## Commands
@ -27,6 +27,11 @@ A Discord music bot, written in Kotlin using the kord library.
## How to self-host (using the Docker container) ## How to self-host (using the Docker container)
1. Pull the container
2. Map /data/ to a folder on disk
3. Run the Bot once
4. Follow step 4 - 7 of "How to self-host (using the JAR)"
## How to self-host (using the JAR) ## How to self-host (using the JAR)
1. Download the latest release from the Package Registry ("Packages and registries" > "Package Registry") 1. Download the latest release from the Package Registry ("Packages and registries" > "Package Registry")

View file

@ -33,7 +33,7 @@ val ownerID = 372703841151614976L
group = "de.limited_dev.botendo" group = "de.limited_dev.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.1.1" ?: "6.2.0"
val kordver = "1.5.6" val kordver = "1.5.6"
val lavaver = "3.8.0" val lavaver = "3.8.0"
@ -44,7 +44,6 @@ project.base.archivesName.set(mavenArtifact)
repositories { repositories {
mavenCentral() mavenCentral()
maven("https://m2.dv8tion.net/releases")
maven { maven {
name = "Gitlab" name = "Gitlab"
val projectId = System.getenv("CI_PROJECT_ID") val projectId = System.getenv("CI_PROJECT_ID")

View file

@ -20,11 +20,15 @@
package de.limited_dev.botendo package de.limited_dev.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.extensions.music.* import de.limited_dev.botendo.extensions.music.*
import de.limited_dev.botendo.extensions.util.InfoExtension import de.limited_dev.botendo.extensions.util.InfoExtension
import de.limited_dev.botendo.extensions.util.PotatoExtension import de.limited_dev.botendo.extensions.util.PotatoExtension
import de.limited_dev.botendo.util.CredentialManager import de.limited_dev.botendo.util.CredentialManager
import de.limited_dev.botendo.util.Logger 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.event.interaction.ButtonInteractionCreateEvent
import dev.kord.core.on import dev.kord.core.on
import dev.schlaubi.lavakord.LavaKord import dev.schlaubi.lavakord.LavaKord
@ -62,6 +66,10 @@ object Bot {
add(::QueueExtension) add(::QueueExtension)
add(::PotatoExtension) add(::PotatoExtension)
} }
this.presence {
this.streaming("music", "https://twitch.tv/limited_dev")
}
} }
//Add LavaLink //Add LavaLink
@ -72,7 +80,29 @@ object Bot {
//Register Button presses //Register Button presses
bot.kordRef.on<ButtonInteractionCreateEvent> { bot.kordRef.on<ButtonInteractionCreateEvent> {
val inter = this.interaction
val response = inter.deferPublicResponse()
val u = inter.user
val g = this.interaction.getOriginalInteractionResponse().getGuild()
var flag = false
for (b in ButtonManager.buttons) {
if (b.id != inter.componentId || flag)
continue
b.onInteraction(response, g, u)
flag = true
}
if (!flag) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"Error",
"Could not find button with id \"${inter.componentId}\".\nPlease report this.",
u.asUser().username + "#" + u.asUser().discriminator
)
)
}
}
} }
//Start the bot //Start the bot

View file

@ -0,0 +1,35 @@
/*
* Botendo
* Copyright (C) 2023 limited_dev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package de.limited_dev.botendo.buttons
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.entity.Guild
import dev.kord.core.entity.User
open class Button(val id: String) {
open suspend fun onInteraction(
response: DeferredPublicMessageInteractionResponseBehavior,
guild: Guild,
user: User
) {
}
}

View file

@ -0,0 +1,26 @@
/*
* Botendo
* Copyright (C) 2023 limited_dev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package de.limited_dev.botendo.buttons
import de.limited_dev.botendo.buttons.music.*
object ButtonManager {
val buttons = listOf(RepeatButton(), PauseButton(), SkipButton(), QueueButton(), StopButton())
}

View file

@ -0,0 +1,105 @@
/*
* Botendo
* Copyright (C) 2023 limited_dev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package de.limited_dev.botendo.buttons.music
import de.limited_dev.botendo.Bot
import de.limited_dev.botendo.buttons.Button
import de.limited_dev.botendo.extensions.music.components.MusicManager
import de.limited_dev.botendo.util.ButtonUtil
import de.limited_dev.botendo.util.MessageUtil
import dev.kord.common.Color
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.Guild
import dev.kord.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow
import dev.schlaubi.lavakord.audio.Link
class PauseButton : Button("btn.music.pause") {
override suspend fun onInteraction(
response: DeferredPublicMessageInteractionResponseBehavior,
guild: Guild,
user: User
) {
val guildId = guild.id
val link = Bot.lava.getLink(guildId.toString())
val player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"You are not connected to a VC",
"Please connect to a VC",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
}
val channelId = voiceState.channelId
if (link.state == Link.State.NOT_CONNECTED) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"Not connected",
"I'm not in a VC and therefore, I am not playing anything.",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"You are not in my VC",
"We are not in the same VC and therefore, you cannot control the music",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
}
player.pause(!player.paused)
val gts = MusicManager.getGuildTrackScheduler(guild, player)
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0x52E01A),
if (player.paused) "I paused" else "I'm continuing",
if (player.paused) "I paused the song" else "I'm continuing to play the song.",
user.asUser().username + "#" + user.asUser().discriminator
)
)
this.actionRow {
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
}
}
}
}

View file

@ -0,0 +1,96 @@
/*
* Botendo
* Copyright (C) 2023 limited_dev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package de.limited_dev.botendo.buttons.music
import de.limited_dev.botendo.Bot
import de.limited_dev.botendo.buttons.Button
import de.limited_dev.botendo.extensions.music.components.MusicManager
import de.limited_dev.botendo.util.ButtonUtil
import de.limited_dev.botendo.util.MessageUtil
import de.limited_dev.botendo.util.TimeUtil
import dev.kord.common.Color
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.Guild
import dev.kord.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow
import dev.schlaubi.lavakord.audio.Link
class QueueButton : Button("btn.music.queue") {
override suspend fun onInteraction(
response: DeferredPublicMessageInteractionResponseBehavior,
guild: Guild,
user: User
) {
val guildId = guild.id
val link = Bot.lava.getLink(guildId.toString())
val player = link.player
if (link.state == Link.State.NOT_CONNECTED) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"Not connected",
"I'm not in a VC and therefore, I am not playing anything.",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
}
val track = player.playingTrack
if (track == null) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"Not playing",
"I'm not playing anything currently", user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
}
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
val q = gts.getQueue()
var desc =
"""${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length.inWholeMilliseconds)} (${track.author})**""" + "\n"
for ((i, tr) in q.withIndex()) {
if (i >= 14)
continue
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
}
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0x52E01A),
"Queue",
desc,
user.asUser().username + "#" + user.asUser().discriminator
)
)
this.actionRow {
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
}
}
}
}

View file

@ -0,0 +1,104 @@
/*
* Botendo
* Copyright (C) 2023 limited_dev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package de.limited_dev.botendo.buttons.music
import de.limited_dev.botendo.Bot
import de.limited_dev.botendo.buttons.Button
import de.limited_dev.botendo.extensions.music.components.MusicManager
import de.limited_dev.botendo.util.ButtonUtil
import de.limited_dev.botendo.util.MessageUtil
import dev.kord.common.Color
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.Guild
import dev.kord.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow
import dev.schlaubi.lavakord.audio.Link
class RepeatButton : Button("btn.music.repeat") {
override suspend fun onInteraction(
response: DeferredPublicMessageInteractionResponseBehavior,
guild: Guild,
user: User
) {
val guildId = guild.id
val link = Bot.lava.getLink(guildId.toString())
val player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"You are not connected to a VC",
"Please connect to a VC",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
}
val channelId = voiceState.channelId
if (link.state == Link.State.NOT_CONNECTED) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"Not connected",
"I'm not in a VC and therefore, I am not playing anything.",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"You are not in my VC",
"We are not in the same VC and therefore, you cannot control the music",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
}
val gts = MusicManager.getGuildTrackScheduler(guild, player)
gts.repeating = !gts.repeating
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0x52E01A),
if (gts.repeating) "Now Repeating" else "Now Continuing",
if (gts.repeating) "The current track will now loop" else "The next track will play when this song finishes",
user.asUser().username + "#" + user.asUser().discriminator
)
)
this.actionRow {
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
}
}
}
}

View file

@ -0,0 +1,147 @@
/*
* Botendo
* Copyright (C) 2023 limited_dev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package de.limited_dev.botendo.buttons.music
import de.limited_dev.botendo.Bot
import de.limited_dev.botendo.buttons.Button
import de.limited_dev.botendo.extensions.music.components.MusicManager
import de.limited_dev.botendo.util.ButtonUtil
import de.limited_dev.botendo.util.MessageUtil
import de.limited_dev.botendo.util.TimeUtil
import de.limited_dev.botendo.util.UrlUtil
import dev.kord.common.Color
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.Guild
import dev.kord.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow
import dev.schlaubi.lavakord.audio.Link
class SkipButton : Button("btn.music.skip") {
override suspend fun onInteraction(
response: DeferredPublicMessageInteractionResponseBehavior,
guild: Guild,
user: User
) {
val guildId = guild.id
val link = Bot.lava.getLink(guildId.toString())
val player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"You are not connected to a VC",
"Please connect to a VC",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
}
val channelId = voiceState.channelId
if (link.state == Link.State.NOT_CONNECTED) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"Not connected",
"I'm not in a VC and therefore, I am not playing anything.",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"You are not in my VC",
"We are not in the same VC and therefore, you cannot control the music",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
}
var track = player.playingTrack
if (track == null) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"Not playing",
"I'm not playing anything currently", user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
}
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
if (!gts.isEmpty()) {
track = gts.getHead().toTrack()
gts.playNext()
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbedWithImage(
Color(0x52E01A),
"Skipped song; now playing",
"**${track.title}**\n*Now Playing*\nby ${track.author} :: ${
TimeUtil.getTimeFormatedRaw(
track.length.inWholeMilliseconds
)
}\n" +
">>>${track.uri}",
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg",
user.asUser().username + "#" + user.asUser().discriminator
)
)
this.actionRow {
this.components.addAll(
ButtonUtil.getMusicControllerButtons(
player.paused,
gts.repeating
).components
)
}
}
return
}
player.stopTrack()
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0x52E01A),
"Skipped song; now playing",
"Nothing",
user.asUser().username + "#" + user.asUser().discriminator
)
)
this.actionRow {
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
}
}
}
}

View file

@ -0,0 +1,98 @@
/*
* Botendo
* Copyright (C) 2023 limited_dev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package de.limited_dev.botendo.buttons.music
import de.limited_dev.botendo.Bot
import de.limited_dev.botendo.buttons.Button
import de.limited_dev.botendo.extensions.music.components.MusicManager
import de.limited_dev.botendo.util.MessageUtil
import dev.kord.common.Color
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.Guild
import dev.kord.core.entity.User
import dev.schlaubi.lavakord.audio.Link
class StopButton : Button("btn.music.stop") {
override suspend fun onInteraction(
response: DeferredPublicMessageInteractionResponseBehavior,
guild: Guild,
user: User
) {
val guildId = guild.id
val link = Bot.lava.getLink(guildId.toString())
val player = link.player
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"You are not connected to a VC",
"Please connect to a VC",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
}
val channelId = voiceState.channelId
if (link.state == Link.State.NOT_CONNECTED) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"Not connected",
"I'm not in a VC and therefore, I am not playing anything.",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0xE0311A),
"You are not in my VC",
"We are not in the same VC and therefore, you cannot control the music",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
return
}
player.stopTrack()
link.destroy()
MusicManager.getGuildTrackScheduler(guild.asGuild(), player).clear()
response.respond {
this.embeds = mutableListOf(
MessageUtil.getEmbed(
Color(0x52E01A),
"I stopped and left",
"just like your girlfriend",
user.asUser().username + "#" + user.asUser().discriminator
)
)
}
}
}

View file

@ -21,10 +21,15 @@ package de.limited_dev.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 de.limited_dev.botendo.Bot 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.MessageUtil
import de.limited_dev.botendo.util.TimeUtil import de.limited_dev.botendo.util.TimeUtil
import de.limited_dev.botendo.util.UrlUtil 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.audio.Link
import dev.schlaubi.lavakord.kord.getLink import dev.schlaubi.lavakord.kord.getLink
@ -41,6 +46,7 @@ class NowPlayingExtension : Extension() {
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
MessageUtil.sendEmbedForPublicSlashCommand( MessageUtil.sendEmbedForPublicSlashCommand(
this, this,
Color(0xE0A81A),
"Not connected", "Not connected",
"I'm not in a VC and therefore, I am not playing anything." "I'm not in a VC and therefore, I am not playing anything."
) )
@ -50,26 +56,38 @@ class NowPlayingExtension : Extension() {
if (track == null) { if (track == null) {
MessageUtil.sendEmbedForPublicSlashCommand( MessageUtil.sendEmbedForPublicSlashCommand(
this, this,
Color(0xE0A81A),
"Not Playing", "Not Playing",
"I'm not playing anything currently" "I'm not playing anything currently"
) )
return@action return@action
} }
MessageUtil.sendEmbedForPublicSlashCommandWithImage( val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
this,
"Currently playing", this.respond {
"**${track.title}**\n*Now Playing*\nby ${track.author} :${ this.embeds.add(
TimeUtil.getTimeFormatedRaw( MessageUtil.getEmbedWithImage(
track.position.inWholeMilliseconds Color(0x52E01A),
"Currently playing",
"**${track.title}**\n*Now Playing*\nby ${track.author} :${
TimeUtil.getTimeFormatedRaw(
track.position.inWholeMilliseconds
)
}: ${
TimeUtil.getTimeFormatedRaw(
track.length.inWholeMilliseconds
)
}\n" +
">>>${track.uri}",
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg",
user.asUser().username + "#" + user.asUser().discriminator
) )
}: ${ )
TimeUtil.getTimeFormatedRaw(
track.length.inWholeMilliseconds this.actionRow {
) ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating)
}\n" + }
">>>${track.uri}", }
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
)
} }
} }
} }

View file

@ -27,6 +27,7 @@ import com.kotlindiscord.kord.extensions.types.respond
import de.limited_dev.botendo.Bot import de.limited_dev.botendo.Bot
import de.limited_dev.botendo.extensions.music.components.MusicManager import de.limited_dev.botendo.extensions.music.components.MusicManager
import de.limited_dev.botendo.util.MessageUtil import de.limited_dev.botendo.util.MessageUtil
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
@ -48,6 +49,7 @@ class PlayExtension : Extension() {
this.respond { this.respond {
embeds.add( embeds.add(
MessageUtil.getEmbed( MessageUtil.getEmbed(
Color(0xE0311A),
"You are not connected to a VC", "You are not connected to a VC",
"Please connect to a VC", "Please connect to a VC",
u.asUser().username + "#" + u.asUser().discriminator u.asUser().username + "#" + u.asUser().discriminator
@ -65,6 +67,7 @@ class PlayExtension : Extension() {
this.respond { this.respond {
embeds.add( embeds.add(
MessageUtil.getEmbed( MessageUtil.getEmbed(
Color(0xE0311A),
"You are not in my VC", "You are not in my VC",
"We are not in the same VC and therefore, you cannot play any music", "We are not in the same VC and therefore, you cannot play any music",
u.asUser().username + "#" + u.asUser().discriminator u.asUser().username + "#" + u.asUser().discriminator
@ -83,6 +86,7 @@ class PlayExtension : Extension() {
this.respond { this.respond {
embeds.add( embeds.add(
MessageUtil.getEmbed( MessageUtil.getEmbed(
Color(0xE0A81A),
"Searching...", "Searching...",
"We are looking for $query", "We are looking for $query",
u.asUser().username + "#" + u.asUser().discriminator u.asUser().username + "#" + u.asUser().discriminator

View file

@ -21,10 +21,14 @@ package de.limited_dev.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 de.limited_dev.botendo.Bot import de.limited_dev.botendo.Bot
import de.limited_dev.botendo.extensions.music.components.MusicManager 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.MessageUtil
import de.limited_dev.botendo.util.TimeUtil 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 dev.schlaubi.lavakord.audio.Link
class QueueExtension : Extension() { class QueueExtension : Extension() {
@ -40,6 +44,7 @@ class QueueExtension : Extension() {
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
MessageUtil.sendEmbedForPublicSlashCommand( MessageUtil.sendEmbedForPublicSlashCommand(
this, this,
Color(0xE0311A),
"Not connected", "Not connected",
"I'm not in a VC and therefore, I am not playing anything." "I'm not in a VC and therefore, I am not playing anything."
) )
@ -49,6 +54,7 @@ class QueueExtension : Extension() {
if (track == null) { if (track == null) {
MessageUtil.sendEmbedForPublicSlashCommand( MessageUtil.sendEmbedForPublicSlashCommand(
this, this,
Color(0xE0A81A),
"Queue empty", "Queue empty",
"I'm not playing anything currently" "I'm not playing anything currently"
) )
@ -63,8 +69,20 @@ class QueueExtension : Extension() {
continue continue
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n" desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
} }
MessageUtil.sendEmbedForPublicSlashCommand(this, "Queue", desc) this.respond {
this.embeds.add(
MessageUtil.getEmbed(
Color(0x52E01A),
"Queue",
desc,
user.asUser().username + "#" + user.asUser().discriminator
)
)
this.actionRow {
ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating)
}
}
} }
} }
} }

View file

@ -21,11 +21,15 @@ package de.limited_dev.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 de.limited_dev.botendo.Bot import de.limited_dev.botendo.Bot
import de.limited_dev.botendo.extensions.music.components.MusicManager 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.MessageUtil
import de.limited_dev.botendo.util.TimeUtil import de.limited_dev.botendo.util.TimeUtil
import de.limited_dev.botendo.util.UrlUtil 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.audio.Link
class SkipExtension : Extension() { class SkipExtension : Extension() {
@ -43,6 +47,7 @@ class SkipExtension : Extension() {
if (voiceState == null) { if (voiceState == null) {
MessageUtil.sendEmbedForPublicSlashCommand( MessageUtil.sendEmbedForPublicSlashCommand(
this, this,
Color(0xE0311A),
"You are not connected to a VC", "You are not connected to a VC",
"Please connect to a VC" "Please connect to a VC"
) )
@ -53,6 +58,7 @@ class SkipExtension : Extension() {
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
MessageUtil.sendEmbedForPublicSlashCommand( MessageUtil.sendEmbedForPublicSlashCommand(
this, this,
Color(0xE0311A),
"Not connected", "Not connected",
"I'm not in a VC and therefore, I am not playing anything." "I'm not in a VC and therefore, I am not playing anything."
) )
@ -60,6 +66,7 @@ class SkipExtension : Extension() {
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
MessageUtil.sendEmbedForPublicSlashCommand( MessageUtil.sendEmbedForPublicSlashCommand(
this, this,
Color(0xE0311A),
"You are not in my VC", "You are not in my VC",
"We are not in the same VC and therefore, you cannot control the music" "We are not in the same VC and therefore, you cannot control the music"
) )
@ -69,26 +76,41 @@ class SkipExtension : Extension() {
if (track == null) { if (track == null) {
MessageUtil.sendEmbedForPublicSlashCommand( MessageUtil.sendEmbedForPublicSlashCommand(
this, this,
Color(0xE0311A),
"Not playing", "Not playing",
"I'm not playing anything currently" "I'm not playing anything currently"
) )
return@action return@action
} }
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player) val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
track = gts.getHead().toTrack() if (!gts.isEmpty()) {
gts.playNext() track = gts.getHead().toTrack()
MessageUtil.sendEmbedForPublicSlashCommandWithImage( gts.playNext()
this, } else {
"Skipped song; now playing", player.stopTrack()
"**${track.title}**\n*Now Playing*\nby ${track.author} :: ${ }
TimeUtil.getTimeFormatedRaw(
track.length.inWholeMilliseconds
)
}\n" +
">>>${track.uri}",
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
)
this.respond {
this.embeds.add(
MessageUtil.getEmbedWithImage(
Color(0x52E01A),
"Skipped song; now playing",
"**${track.title}**\n*Now Playing*\nby ${track.author} :: ${
TimeUtil.getTimeFormatedRaw(
track.length.inWholeMilliseconds
)
}\n" +
">>>${track.uri}",
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg",
user.asUser().username + "#" + user.asUser().discriminator
)
)
this.actionRow {
ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating)
}
}
} }
} }
} }

View file

@ -25,6 +25,7 @@ import com.kotlindiscord.kord.extensions.types.respond
import de.limited_dev.botendo.Bot import de.limited_dev.botendo.Bot
import de.limited_dev.botendo.extensions.music.components.MusicManager import de.limited_dev.botendo.extensions.music.components.MusicManager
import de.limited_dev.botendo.util.MessageUtil import de.limited_dev.botendo.util.MessageUtil
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
@ -44,6 +45,7 @@ class StopExtension : Extension() {
this.respond { this.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbed( MessageUtil.getEmbed(
Color(0xE0311A),
"You are not connected to a VC", "You are not connected to a VC",
"Please connect to my VC", u.asUser().username + "#" + u.asUser().discriminator "Please connect to my VC", u.asUser().username + "#" + u.asUser().discriminator
) )
@ -56,6 +58,7 @@ class StopExtension : Extension() {
this.respond { this.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbed( MessageUtil.getEmbed(
Color(0xE0311A),
"Not connected", "Not connected",
"I'm not in a VC and therefore, I am not playing anything.", "I'm not in a VC and therefore, I am not playing anything.",
u.asUser().username + "#" + u.asUser().discriminator u.asUser().username + "#" + u.asUser().discriminator
@ -67,6 +70,7 @@ class StopExtension : Extension() {
this.respond { this.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbed( MessageUtil.getEmbed(
Color(0xE0311A),
"You are not in my VC", "You are not in my VC",
"We are not in the same VC", u.asUser().username + "#" + u.asUser().discriminator "We are not in the same VC", u.asUser().username + "#" + u.asUser().discriminator
) )
@ -80,6 +84,7 @@ class StopExtension : Extension() {
this.respond { this.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbed( MessageUtil.getEmbed(
Color(0x52E01A),
"I stopped and left", "I stopped and left",
"just like your girlfriend", "just like your girlfriend",
u.asUser().username + "#" + u.asUser().discriminator u.asUser().username + "#" + u.asUser().discriminator

View file

@ -109,5 +109,9 @@ class GuildTrackScheduler(val pl: Player) {
fun getHead(): TrackResponse.PartialTrack { fun getHead(): TrackResponse.PartialTrack {
return queue.first() return queue.first()
} }
fun isEmpty(): Boolean {
return queue.isEmpty()
}
} }

View file

@ -23,11 +23,14 @@ import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashC
import com.kotlindiscord.kord.extensions.components.forms.ModalForm import com.kotlindiscord.kord.extensions.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.extensions.music.PlayExtension
import de.limited_dev.botendo.util.ButtonUtil
import de.limited_dev.botendo.util.MessageUtil import de.limited_dev.botendo.util.MessageUtil
import de.limited_dev.botendo.util.TimeUtil import de.limited_dev.botendo.util.TimeUtil
import de.limited_dev.botendo.util.UrlUtil import de.limited_dev.botendo.util.UrlUtil
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
import dev.kord.rest.builder.message.create.actionRow
import dev.schlaubi.lavakord.audio.Link 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.TrackResponse import dev.schlaubi.lavakord.rest.TrackResponse
@ -71,6 +74,7 @@ object MusicManager {
ctx.respond { ctx.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbedWithImage( MessageUtil.getEmbedWithImage(
Color(0x52E01A),
"Queuing track from link", "Queuing 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(
@ -81,6 +85,15 @@ object MusicManager {
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg" "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg"
) )
) )
this.actionRow {
this.components.addAll(
ButtonUtil.getMusicControllerButtons(
player.paused,
gts.repeating
).components
)
}
} }
} }
@ -93,6 +106,7 @@ object MusicManager {
ctx.respond { ctx.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbedWithImage( MessageUtil.getEmbedWithImage(
Color(0x52E01A),
"Queuing playlist from link", "Queuing 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(
@ -103,6 +117,15 @@ object MusicManager {
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg" "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg"
) )
) )
this.actionRow {
this.components.addAll(
ButtonUtil.getMusicControllerButtons(
player.paused,
gts.repeating
).components
)
}
} }
} }
@ -112,6 +135,7 @@ object MusicManager {
ctx.respond { ctx.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbedWithImage( MessageUtil.getEmbedWithImage(
Color(0x52E01A),
"Queuing track from query", "Queuing 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(
@ -122,6 +146,15 @@ object MusicManager {
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.tracks.first().info.uri) + "/maxresdefault.jpg" "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.tracks.first().info.uri) + "/maxresdefault.jpg"
) )
) )
this.actionRow {
this.components.addAll(
ButtonUtil.getMusicControllerButtons(
player.paused,
gts.repeating
).components
)
}
} }
} }
@ -130,6 +163,7 @@ object MusicManager {
ctx.respond { ctx.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbed( MessageUtil.getEmbed(
Color(0xE0311A),
"Not found", "Not found",
"There were no matches.", "There were no matches.",
u.username + "#" + u.discriminator u.username + "#" + u.discriminator
@ -143,6 +177,7 @@ object MusicManager {
ctx.respond { ctx.respond {
this.embeds.add( this.embeds.add(
MessageUtil.getEmbed( MessageUtil.getEmbed(
Color(0xE0311A),
"Load failed", "Load failed",
"There was an error while loading.", u.username + "#" + u.discriminator "There was an error while loading.", u.username + "#" + u.discriminator
) )

View file

@ -23,6 +23,7 @@ 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.build.BuildConstants
import de.limited_dev.botendo.util.MessageUtil import de.limited_dev.botendo.util.MessageUtil
import dev.kord.common.Color
class InfoExtension : Extension() { class InfoExtension : Extension() {
override val name = "info" override val name = "info"
@ -32,9 +33,9 @@ class InfoExtension : Extension() {
description = "Show infos about the bot" description = "Show infos about the bot"
this.action { this.action {
MessageUtil.sendEmbedForPublicSlashCommand( MessageUtil.sendEmbedForPublicSlashCommand(
this, "Botendo", this, Color(0x52E01A), "Botendo",
"Botendo ***v." + BuildConstants.version + "***\n" + "Botendo ***v." + BuildConstants.version + "***\n" +
"kord-extensions ***v." + BuildConstants.kordVersion + "***\n" + "Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" +
"lavalink.kt ***v." + BuildConstants.lavaVersion + "***\n" + "lavalink.kt ***v." + BuildConstants.lavaVersion + "***\n" +
"Coroutines ***v." + BuildConstants.coroutinesVersion + "***" "Coroutines ***v." + BuildConstants.coroutinesVersion + "***"
) )

View file

@ -22,6 +22,7 @@ package de.limited_dev.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.util.MessageUtil import de.limited_dev.botendo.util.MessageUtil
import dev.kord.common.Color
class PotatoExtension : Extension() { class PotatoExtension : Extension() {
override val name = "potato" override val name = "potato"
@ -31,7 +32,7 @@ class PotatoExtension : Extension() {
description = "Potato" description = "Potato"
this.action { this.action {
MessageUtil.sendEmbedForPublicSlashCommandWithImage( MessageUtil.sendEmbedForPublicSlashCommandWithImage(
this, "Potato", this, Color(0xE0311A), "Potato",
"Potato", "Potato",
"https://static.tumblr.com/c06d8e0928395746a63b9c5d3cb1ce66/sl9iajp/gxFmqk38z/tumblr_static_potato-equality.jpg" "https://static.tumblr.com/c06d8e0928395746a63b9c5d3cb1ce66/sl9iajp/gxFmqk38z/tumblr_static_potato-equality.jpg"
) )

View file

@ -0,0 +1,46 @@
/*
* Botendo
* Copyright (C) 2023 limited_dev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package de.limited_dev.botendo.util
import dev.kord.common.entity.ButtonStyle
import dev.kord.rest.builder.component.ActionRowBuilder
object ButtonUtil {
fun getMusicControllerButtons(isPaused: Boolean, isRepeating: Boolean): ActionRowBuilder {
val ar = ActionRowBuilder()
ar.interactionButton(ButtonStyle.Secondary, "btn.music.repeat") {
this.label = if (isRepeating) "Stop Repeating" else "Repeat"
}
ar.interactionButton(ButtonStyle.Success, "btn.music.pause") {
this.label = if (isPaused) "Continue" else "Pause"
}
ar.interactionButton(ButtonStyle.Primary, "btn.music.skip") {
this.label = "Skip"
}
ar.interactionButton(ButtonStyle.Secondary, "btn.music.queue") {
this.label = "Queue"
}
ar.interactionButton(ButtonStyle.Danger, "btn.music.stop") {
this.label = "Stop"
}
return ar
}
}

View file

@ -23,6 +23,7 @@ import com.kotlindiscord.kord.extensions.commands.Arguments
import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext import com.kotlindiscord.kord.extensions.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 dev.kord.common.Color
import dev.kord.rest.builder.message.EmbedBuilder import dev.kord.rest.builder.message.EmbedBuilder
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -30,14 +31,17 @@ import java.time.format.DateTimeFormatter
object MessageUtil { object MessageUtil {
private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss") private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss")
///Send an embedded message as a reply
suspend fun sendEmbedForPublicSlashCommand( suspend fun sendEmbedForPublicSlashCommand(
ctx: PublicSlashCommandContext<Arguments, ModalForm>, ctx: PublicSlashCommandContext<Arguments, ModalForm>,
color: Color,
title: String, title: String,
description: String description: String
) { ) {
ctx.respond { ctx.respond {
embeds.add( embeds.add(
getEmbed( getEmbed(
color,
title, title,
description, description,
ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator
@ -46,8 +50,10 @@ object MessageUtil {
} }
} }
///Send an embedded message with an image as a reply
suspend fun sendEmbedForPublicSlashCommandWithImage( suspend fun sendEmbedForPublicSlashCommandWithImage(
ctx: PublicSlashCommandContext<Arguments, ModalForm>, ctx: PublicSlashCommandContext<Arguments, ModalForm>,
color: Color,
title: String, title: String,
description: String, description: String,
thumbnailUrl: String thumbnailUrl: String
@ -55,6 +61,7 @@ object MessageUtil {
ctx.respond { ctx.respond {
embeds.add( embeds.add(
getEmbedWithImage( getEmbedWithImage(
color,
title, title,
description, description,
ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator, ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator,
@ -64,23 +71,32 @@ object MessageUtil {
} }
} }
fun getEmbed(title: String, description: String, source: String): EmbedBuilder { ///Get an embedded msg with title, description and a src
fun getEmbed(
color: Color,
title: String,
description: String,
source: String
): EmbedBuilder {
val now: LocalDateTime = LocalDateTime.now() val now: LocalDateTime = LocalDateTime.now()
val ebb = EmbedBuilder() val ebb = EmbedBuilder()
ebb.title = title ebb.title = title
ebb.description = description ebb.description = description
ebb.footer = EmbedBuilder.Footer() ebb.footer = EmbedBuilder.Footer()
ebb.footer!!.text = ">" + dtf.format(now) + " - $source" ebb.footer!!.text = ">" + dtf.format(now) + " - $source"
ebb.color = color
return ebb return ebb
} }
///Get an embedded msg with image, title, description and a src
fun getEmbedWithImage( fun getEmbedWithImage(
color: Color,
title: String, title: String,
description: String, description: String,
source: String, source: String,
thumbnailUrl: String thumbnailUrl: String
): EmbedBuilder { ): EmbedBuilder {
val ebb = getEmbed(title, description, source) val ebb = getEmbed(color, title, description, source)
ebb.thumbnail = EmbedBuilder.Thumbnail() ebb.thumbnail = EmbedBuilder.Thumbnail()
ebb.thumbnail!!.url = thumbnailUrl ebb.thumbnail!!.url = thumbnailUrl
return ebb return ebb

View file

@ -22,7 +22,8 @@ package de.limited_dev.botendo.util
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
object TimeUtil { object TimeUtil {
fun getTimeFormatedShortend(time: Long): String? { ///Convert Miliseconds to xdays xhours xmins xsecs
fun getTimeFormatedShortend(time: Long): String {
var time = time var time = time
val days = TimeUnit.MILLISECONDS val days = TimeUnit.MILLISECONDS
.toDays(time) .toDays(time)
@ -54,7 +55,7 @@ object TimeUtil {
return s return s
} }
fun getTimeFormatedRaw(time: Long): String? { fun getTimeFormatedRaw(time: Long): String {
var time = time var time = time
val days = TimeUnit.MILLISECONDS val days = TimeUnit.MILLISECONDS
.toDays(time) .toDays(time)

View file

@ -20,6 +20,7 @@
package de.limited_dev.botendo.util package de.limited_dev.botendo.util
object UrlUtil { object UrlUtil {
///Strip the video ID from a YouTube link
fun getYtThumbnailUrl(uri: String): String { fun getYtThumbnailUrl(uri: String): String {
return uri.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1] return uri.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
} }