chore: finally moved from de.limited_dev to net.moonleay, fixed Discriminator in info command
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
This commit is contained in:
parent
1c00f856ab
commit
612d7b58cc
27 changed files with 111 additions and 125 deletions
106
src/main/kotlin/net/moonleay/botendo/Bot.kt
Normal file
106
src/main/kotlin/net/moonleay/botendo/Bot.kt
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
import com.kotlindiscord.kord.extensions.ExtensibleBot
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.event.interaction.ButtonInteractionCreateEvent
|
||||
import dev.kord.core.on
|
||||
import dev.schlaubi.lavakord.LavaKord
|
||||
import dev.schlaubi.lavakord.kord.lavakord
|
||||
import net.moonleay.botendo.data.CredentialManager
|
||||
import net.moonleay.botendo.extensions.music.*
|
||||
import net.moonleay.botendo.extensions.util.InfoExtension
|
||||
import net.moonleay.botendo.util.Logger
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
object Bot {
|
||||
//The kord object gets set at app launch
|
||||
private lateinit var bot: ExtensibleBot
|
||||
lateinit var lava: LavaKord
|
||||
suspend fun start() {
|
||||
Logger.out("Starting Bot...")
|
||||
|
||||
//Load config
|
||||
CredentialManager.load()
|
||||
|
||||
//Don't run the bot when there is no bot token in config
|
||||
if (CredentialManager.token == "empty") {
|
||||
Logger.out("The config does not contain a bot token")
|
||||
return
|
||||
}
|
||||
|
||||
//Add Bot token to kord
|
||||
//kord = Kord(CredentialManager.token)
|
||||
bot = ExtensibleBot(CredentialManager.token) {
|
||||
applicationCommands {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
extensions {
|
||||
add(::InfoExtension)
|
||||
add(::PlayExtension)
|
||||
add(::StopExtension)
|
||||
add(::SkipExtension)
|
||||
add(::NowPlayingExtension)
|
||||
add(::QueueExtension)
|
||||
add(::UpsertExtension)
|
||||
}
|
||||
|
||||
this.presence {
|
||||
this.streaming("music", "https://twitch.tv/limited_dev")
|
||||
}
|
||||
}
|
||||
|
||||
//Add LavaLink
|
||||
lava = bot.kordRef.lavakord()
|
||||
|
||||
//Add the LavaLink node from config
|
||||
lava.addNode(CredentialManager.linkip, CredentialManager.linkpw)
|
||||
|
||||
//Register Button presses
|
||||
bot.kordRef.on<ButtonInteractionCreateEvent> {
|
||||
val inter = this.interaction
|
||||
val response = inter.deferPublicResponse()
|
||||
val u = inter.user
|
||||
val g = this.interaction.getOriginalInteractionResponse().getGuild()
|
||||
for (b in net.moonleay.botendo.buttons.ButtonManager.buttons) {
|
||||
if (b.id != inter.componentId)
|
||||
continue
|
||||
b.onInteraction(response, g, u)
|
||||
return@on
|
||||
}
|
||||
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
|
||||
bot.start()
|
||||
}
|
||||
}
|
37
src/main/kotlin/net/moonleay/botendo/Main.kt
Normal file
37
src/main/kotlin/net/moonleay/botendo/Main.kt
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
|
||||
///Show the splash and launch the Bot
|
||||
suspend fun main() {
|
||||
println(
|
||||
"M#\"\"\"\"\"\"\"'M dP dP \n" +
|
||||
"## mmmm. `M 88 88 \n" +
|
||||
"#' .M .d8888b. d8888P .d8888b. 88d888b. .d888b88 .d8888b. \n" +
|
||||
"M# MMMb.'YM 88' `88 88 88ooood8 88' `88 88' `88 88' `88 \n" +
|
||||
"M# MMMM' M 88. .88 88 88. ... 88 88 88. .88 88. .88 \n" +
|
||||
"M# .;M `88888P' dP `88888P' dP dP `88888P8 `88888P' \n" +
|
||||
"M#########M \n" +
|
||||
" "
|
||||
)
|
||||
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()
|
||||
}
|
35
src/main/kotlin/net/moonleay/botendo/buttons/Button.kt
Normal file
35
src/main/kotlin/net/moonleay/botendo/buttons/Button.kt
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.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
|
||||
) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.buttons
|
||||
|
||||
import net.moonleay.botendo.buttons.music.*
|
||||
|
||||
object ButtonManager {
|
||||
val buttons = listOf(
|
||||
RepeatButton(),
|
||||
PauseButton(),
|
||||
SkipButton(),
|
||||
QueueButton(),
|
||||
StopButton()
|
||||
)
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* 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.buttons.music
|
||||
|
||||
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
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
class PauseButton : net.moonleay.botendo.buttons.Button("btn.music.pause") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = net.moonleay.botendo.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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.buttons.music
|
||||
|
||||
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
|
||||
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 : net.moonleay.botendo.buttons.Button("btn.music.queue") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = net.moonleay.botendo.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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.buttons.music
|
||||
|
||||
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
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
class RepeatButton : net.moonleay.botendo.buttons.Button("btn.music.repeat") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = net.moonleay.botendo.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
146
src/main/kotlin/net/moonleay/botendo/buttons/music/SkipButton.kt
Normal file
146
src/main/kotlin/net/moonleay/botendo/buttons/music/SkipButton.kt
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* 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.buttons.music
|
||||
|
||||
|
||||
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
|
||||
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 : net.moonleay.botendo.buttons.Button("btn.music.skip") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = net.moonleay.botendo.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(link)
|
||||
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}",
|
||||
user.asUser().username + "#" + user.asUser().discriminator,
|
||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
|
||||
)
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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.buttons.music
|
||||
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
class StopButton : net.moonleay.botendo.buttons.Button("btn.music.stop") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = net.moonleay.botendo.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
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.data
|
||||
|
||||
import java.io.*
|
||||
import java.util.*
|
||||
|
||||
object CredentialManager {
|
||||
private const val foldername = "data"
|
||||
private const val filename = "credentials.nils"
|
||||
var token: String = "empty"
|
||||
var linkip: String = "empty"
|
||||
var linkpw: String = "empty"
|
||||
|
||||
///Load the needed credentials, generate a config if there is none
|
||||
fun load() {
|
||||
val folder = File(foldername)
|
||||
if (!folder.exists()) {
|
||||
save()
|
||||
return
|
||||
}
|
||||
val configFile = File(folder, filename)
|
||||
if (!configFile.exists()) {
|
||||
save()
|
||||
return
|
||||
}
|
||||
try {
|
||||
val input: InputStream = FileInputStream(foldername + File.separator + filename)
|
||||
val prop = Properties()
|
||||
prop.load(input)
|
||||
token = if (prop.getProperty("token").equals("empty")) "empty" else prop.getProperty("token")
|
||||
linkip = if (prop.getProperty("lavaip").equals("empty")) "empty" else prop.getProperty("lavaip")
|
||||
linkpw = if (prop.getProperty("lavapw").equals("empty")) "empty" else prop.getProperty("lavapw")
|
||||
input.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
///generate a new sample config
|
||||
private fun save() {
|
||||
val folder = File(foldername)
|
||||
if (!folder.exists()) {
|
||||
try {
|
||||
folder.mkdirs()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
val configFile = File(foldername + File.separator + filename)
|
||||
if (!configFile.exists()) {
|
||||
try {
|
||||
configFile.createNewFile()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
try {
|
||||
val output: OutputStream = FileOutputStream(foldername + File.separator + filename)
|
||||
val prop = Properties()
|
||||
prop.setProperty("token", "empty")
|
||||
prop.setProperty("lavaip", "empty")
|
||||
prop.setProperty("lavapw", "empty")
|
||||
prop.store(output, null)
|
||||
output.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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.kord.rest.builder.message.create.actionRow
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import dev.schlaubi.lavakord.kord.getLink
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
import net.moonleay.botendo.util.TimeUtil
|
||||
import net.moonleay.botendo.util.UrlUtil
|
||||
|
||||
class NowPlayingExtension : Extension() {
|
||||
override val name = "nowplaying"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "nowplaying"
|
||||
description = "Show what's currently playing"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
|
||||
val player = link.player
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0A81A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything."
|
||||
)
|
||||
return@action
|
||||
}
|
||||
val track = player.playingTrack
|
||||
if (track == null) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0A81A),
|
||||
"Not Playing",
|
||||
"I'm not playing anything currently"
|
||||
)
|
||||
return@action
|
||||
}
|
||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbedWithImage(
|
||||
Color(0x52E01A),
|
||||
"Currently playing",
|
||||
"**${track.title}**\n*Now Playing*\nby ${track.author} ; ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
player.position
|
||||
)
|
||||
}: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
track.length.inWholeMilliseconds
|
||||
)
|
||||
}\n" +
|
||||
">>>${track.uri}",
|
||||
user.asUser().username + "#" + user.asUser().discriminator,
|
||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri.toString()) + "/maxresdefault.jpg"
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 PlayExtension : Extension() {
|
||||
|
||||
override val name = "play"
|
||||
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand(::LinkArguments) {
|
||||
name = "play"
|
||||
description = "Play 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.addToQueue(this, link, search)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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.kord.rest.builder.message.create.actionRow
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
import net.moonleay.botendo.util.TimeUtil
|
||||
|
||||
class QueueExtension : Extension() {
|
||||
override val name = "queue"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "queue"
|
||||
description = "Show whats up next"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0311A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything."
|
||||
)
|
||||
return@action
|
||||
}
|
||||
val track = player.playingTrack
|
||||
if (track == null) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0A81A),
|
||||
"Queue empty",
|
||||
"I'm not playing anything currently"
|
||||
)
|
||||
return@action
|
||||
}
|
||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||
val q = gts.getQueue()
|
||||
var desc =
|
||||
"""${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length.inWholeMilliseconds)} (${track.author})**""" + "\n"
|
||||
for ((i, tr) in q.withIndex()) {
|
||||
if (i >= 14)
|
||||
continue
|
||||
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
|
||||
}
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0x52E01A),
|
||||
"Queue",
|
||||
desc,
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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.kord.rest.builder.message.create.actionRow
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
import net.moonleay.botendo.util.TimeUtil
|
||||
import net.moonleay.botendo.util.UrlUtil
|
||||
|
||||
class SkipExtension : Extension() {
|
||||
override val name = "skip"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "skip"
|
||||
description = "Skip to the next song in queue"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val u = this.user
|
||||
val voiceState = u.asMember(guildId).getVoiceStateOrNull()
|
||||
if (voiceState == null) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0311A),
|
||||
"You are not connected to a VC",
|
||||
"Please connect to a VC"
|
||||
)
|
||||
return@action
|
||||
}
|
||||
|
||||
val channelId = voiceState.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0311A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything."
|
||||
)
|
||||
return@action
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0311A),
|
||||
"You are not in my VC",
|
||||
"We are not in the same VC and therefore, you cannot control the music"
|
||||
)
|
||||
return@action
|
||||
}
|
||||
var track = player.playingTrack
|
||||
if (track == null) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0311A),
|
||||
"Not playing",
|
||||
"I'm not playing anything currently"
|
||||
)
|
||||
return@action
|
||||
}
|
||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||
if (!gts.isEmpty()) {
|
||||
track = gts.getHead().toTrack()
|
||||
gts.playNext(link)
|
||||
} else {
|
||||
player.stopTrack()
|
||||
}
|
||||
|
||||
|
||||
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}",
|
||||
user.asUser().username + "#" + user.asUser().discriminator,
|
||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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.MusicManager
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
class StopExtension : Extension() {
|
||||
override val name = "stop"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "stop"
|
||||
description = "Stop playing and start leavin'"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
|
||||
val player = link.player
|
||||
val u = this.user
|
||||
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
||||
if (vcsUser == null) {
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not connected to a VC",
|
||||
"Please connect to my VC", u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return@action
|
||||
}
|
||||
val channelId = vcsUser.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything.",
|
||||
u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return@action
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not in my VC",
|
||||
"We are not in the same VC", u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return@action
|
||||
}
|
||||
player.stopTrack()
|
||||
link.destroy()
|
||||
MusicManager.getGuildTrackScheduler(this.getGuild()!!.asGuild(), player).clear()
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0x52E01A),
|
||||
"I stopped and left",
|
||||
"just like your girlfriend",
|
||||
u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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 dev.schlaubi.lavakord.audio.*
|
||||
import dev.schlaubi.lavakord.audio.player.Player
|
||||
import dev.schlaubi.lavakord.rest.models.PartialTrack
|
||||
import net.moonleay.botendo.util.Logger
|
||||
import java.util.concurrent.BlockingQueue
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
|
||||
class GuildTrackScheduler(val pl: Player) {
|
||||
|
||||
private var queue: BlockingQueue<PartialTrack> = LinkedBlockingQueue()
|
||||
var repeating = false
|
||||
private var hasRegisteredEvents = false
|
||||
|
||||
///Add a track to queue and start playing, if there is no song currently playing
|
||||
suspend fun queue(track: PartialTrack, type: MusicManager.AddType) {
|
||||
if (this.pl.playingTrack == null) {
|
||||
play(track)
|
||||
return
|
||||
}
|
||||
when (type) {
|
||||
MusicManager.AddType.QUEUE -> {
|
||||
queue.offer(track)
|
||||
}
|
||||
|
||||
MusicManager.AddType.UPSERT -> {
|
||||
val nq = LinkedBlockingQueue<PartialTrack>()
|
||||
nq.offer(track)
|
||||
for (t in queue.toList()) {
|
||||
nq.offer(t)
|
||||
}
|
||||
queue = nq
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun playNext(link: Link) {
|
||||
if (!queue.isEmpty())
|
||||
this.pl.playTrack(queue.poll())
|
||||
else {
|
||||
this.pl.stopTrack()
|
||||
link.destroy()
|
||||
clear()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun play(tr: PartialTrack) {
|
||||
this.pl.playTrack(tr)
|
||||
}
|
||||
|
||||
fun addEvents() {
|
||||
if (hasRegisteredEvents)
|
||||
return
|
||||
hasRegisteredEvents = true
|
||||
|
||||
Logger.out("Adding track events to GuildTrackScheduler...")
|
||||
|
||||
pl.on<Event, TrackEndEvent> {
|
||||
onTrackEnd(this)
|
||||
}
|
||||
|
||||
pl.on<Event, TrackStuckEvent> {
|
||||
onTrackStuck(this)
|
||||
}
|
||||
|
||||
pl.on<Event, TrackExceptionEvent> {
|
||||
onTrackExc(this)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onTrackEnd(e: TrackEndEvent) {
|
||||
if (e.reason.mayStartNext) {
|
||||
if (repeating) {
|
||||
Logger.out("Repeating track...")
|
||||
this.pl.playTrack(e.getTrack().copy())
|
||||
return
|
||||
}
|
||||
Logger.out("Track has ended; Playing next...")
|
||||
playNext(net.moonleay.botendo.Bot.lava.getLink(e.guildId))
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onTrackStuck(e: TrackStuckEvent) {
|
||||
Logger.out("Track is stuck, retrying...")
|
||||
this.pl.playTrack(e.getTrack().copy())
|
||||
}
|
||||
|
||||
private suspend fun onTrackExc(e: TrackExceptionEvent) {
|
||||
Logger.out("Track had an exception, retrying...")
|
||||
this.pl.playTrack(e.getTrack().copy())
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
Logger.out("Clearing queue...")
|
||||
repeating = false
|
||||
queue.clear()
|
||||
}
|
||||
|
||||
fun getQueue(): List<PartialTrack> {
|
||||
return queue.toList()
|
||||
}
|
||||
|
||||
fun getHead(): PartialTrack {
|
||||
return queue.first()
|
||||
}
|
||||
|
||||
fun isEmpty(): Boolean {
|
||||
return queue.isEmpty()
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* 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.application.slash.PublicSlashCommandContext
|
||||
import com.kotlindiscord.kord.extensions.components.forms.ModalForm
|
||||
import com.kotlindiscord.kord.extensions.types.respond
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.common.entity.Snowflake
|
||||
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.player.Player
|
||||
import dev.schlaubi.lavakord.rest.loadItem
|
||||
import dev.schlaubi.lavakord.rest.models.TrackResponse
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
import net.moonleay.botendo.util.TimeUtil
|
||||
import net.moonleay.botendo.util.UrlUtil
|
||||
|
||||
object MusicManager {
|
||||
private var musicManagerMap: MutableMap<Snowflake, GuildTrackScheduler> = mutableMapOf()
|
||||
|
||||
fun getGuildTrackScheduler(guild: Guild, player: Player): GuildTrackScheduler {
|
||||
return musicManagerMap.computeIfAbsent(guild.id) {
|
||||
GuildTrackScheduler(player)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
suspend fun addToQueue(
|
||||
ctx: PublicSlashCommandContext<LinkArguments, ModalForm>,
|
||||
link: Link,
|
||||
search: String
|
||||
) {
|
||||
addToQueue(ctx, link, search, AddType.QUEUE, false)
|
||||
}
|
||||
|
||||
suspend fun upsertIntoQueue(
|
||||
ctx: PublicSlashCommandContext<LinkArguments, ModalForm>,
|
||||
link: Link,
|
||||
search: String
|
||||
) {
|
||||
addToQueue(ctx, link, search, AddType.UPSERT, false)
|
||||
}
|
||||
|
||||
suspend fun addToQueue(
|
||||
ctx: PublicSlashCommandContext<LinkArguments, ModalForm>,
|
||||
link: Link,
|
||||
search: String,
|
||||
type: AddType,
|
||||
silent: Boolean
|
||||
) {
|
||||
val player = link.player
|
||||
val item = link.loadItem(search)
|
||||
val gts = getGuildTrackScheduler(ctx.guild!!.asGuild(), player)
|
||||
val u = ctx.user.asUser()
|
||||
|
||||
gts.addEvents()
|
||||
|
||||
when (item.loadType) {
|
||||
TrackResponse.LoadType.TRACK_LOADED -> {
|
||||
gts.queue(item.track, type)
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbedWithImage(
|
||||
Color(0x52E01A),
|
||||
"${type.s} track from link",
|
||||
"**${item.track.info.title}**\n*Queue*\nby ${item.track.info.author} ;: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
item.track.info.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${item.track.info.uri}", u.username + "#" + u.discriminator,
|
||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg"
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TrackResponse.LoadType.PLAYLIST_LOADED -> {
|
||||
val l = item.tracks.reversed()
|
||||
for (partialTrack in l) {
|
||||
gts.queue(partialTrack, type)
|
||||
}
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0x52E01A),
|
||||
"${type.s} playlist from link",
|
||||
"**${item.tracks.first().info.title}**\n*${item.playlistInfo.name}*\nby ${item.tracks.first().info.author} ;: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
item.tracks.first().info.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TrackResponse.LoadType.SEARCH_RESULT -> {
|
||||
gts.queue(item.tracks.first(), type)
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbedWithImage(
|
||||
Color(0x52E01A),
|
||||
"${type.s} track from query",
|
||||
"**${item.tracks.first().info.title}**\n*Queue*\nby ${item.tracks.first().info.author} ;: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
item.tracks.first().info.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator,
|
||||
"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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TrackResponse.LoadType.NO_MATCHES -> {
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Not found",
|
||||
"There were no matches.",
|
||||
u.username + "#" + u.discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
TrackResponse.LoadType.LOAD_FAILED -> {
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Load failed",
|
||||
"There was an error while loading.", u.username + "#" + u.discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class AddType(val s: String) {
|
||||
QUEUE("Added"),
|
||||
UPSERT("Upserted")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.util
|
||||
|
||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||
import dev.kord.common.Color
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
class InfoExtension : Extension() {
|
||||
override val name = "info"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "info"
|
||||
description = "Show infos about the bot"
|
||||
this.action {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this, Color(0x52E01A), "Botendo",
|
||||
"Botendo ***v." + net.moonleay.botendo.build.BuildConstants.version + "***\n" +
|
||||
"Kord-Extensions ***v." + net.moonleay.botendo.build.BuildConstants.kordVersion + "***\n" +
|
||||
"lavalink.kt ***v." + net.moonleay.botendo.build.BuildConstants.lavaVersion + "***\n" +
|
||||
"Coroutines ***v." + net.moonleay.botendo.build.BuildConstants.coroutinesVersion + "***\n\n\n" +
|
||||
"***Bot made by moonleay#0069***\n" +
|
||||
"(c) 2023, licensed under GPL-3.0"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
46
src/main/kotlin/net/moonleay/botendo/util/ButtonUtil.kt
Normal file
46
src/main/kotlin/net/moonleay/botendo/util/ButtonUtil.kt
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.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
|
||||
}
|
||||
|
||||
}
|
42
src/main/kotlin/net/moonleay/botendo/util/Logger.kt
Normal file
42
src/main/kotlin/net/moonleay/botendo/util/Logger.kt
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.util
|
||||
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
object Logger {
|
||||
private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("yy/MM/dd HH:mm:ss")
|
||||
|
||||
fun out(msg: String) {
|
||||
val caller = Thread.currentThread().stackTrace[2]
|
||||
val now: LocalDateTime = LocalDateTime.now()
|
||||
try {
|
||||
println(
|
||||
("[" + Class.forName(caller.className).simpleName + "." +
|
||||
caller.methodName + ":" + caller.lineNumber + "] [" + dtf.format(now)) + "] <" + msg + ">"
|
||||
)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// Ich kann nicht mehr
|
||||
// [Class.function] [T/M HH:MM] <MESSAGE>
|
||||
}
|
||||
}
|
104
src/main/kotlin/net/moonleay/botendo/util/MessageUtil.kt
Normal file
104
src/main/kotlin/net/moonleay/botendo/util/MessageUtil.kt
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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.util
|
||||
|
||||
import com.kotlindiscord.kord.extensions.commands.Arguments
|
||||
import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext
|
||||
import com.kotlindiscord.kord.extensions.components.forms.ModalForm
|
||||
import com.kotlindiscord.kord.extensions.types.respond
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.rest.builder.message.EmbedBuilder
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
object MessageUtil {
|
||||
private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss")
|
||||
|
||||
///Send an embedded message as a reply
|
||||
suspend fun sendEmbedForPublicSlashCommand(
|
||||
ctx: PublicSlashCommandContext<Arguments, ModalForm>,
|
||||
color: Color,
|
||||
title: String,
|
||||
description: String
|
||||
) {
|
||||
ctx.respond {
|
||||
embeds.add(
|
||||
getEmbed(
|
||||
color,
|
||||
title,
|
||||
description,
|
||||
ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
///Send an embedded message with an image as a reply
|
||||
suspend fun sendEmbedForPublicSlashCommandWithImage(
|
||||
ctx: PublicSlashCommandContext<Arguments, ModalForm>,
|
||||
color: Color,
|
||||
title: String,
|
||||
description: String,
|
||||
thumbnailUrl: String
|
||||
) {
|
||||
ctx.respond {
|
||||
embeds.add(
|
||||
getEmbedWithImage(
|
||||
color,
|
||||
title,
|
||||
description,
|
||||
ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator,
|
||||
thumbnailUrl
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
///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 ebb = EmbedBuilder()
|
||||
ebb.title = title
|
||||
ebb.description = description
|
||||
ebb.footer = EmbedBuilder.Footer()
|
||||
ebb.footer!!.text = ">" + dtf.format(now) + " - $source"
|
||||
ebb.color = color
|
||||
return ebb
|
||||
}
|
||||
|
||||
///Get an embedded msg with image, title, description and a src
|
||||
fun getEmbedWithImage(
|
||||
color: Color,
|
||||
title: String,
|
||||
description: String,
|
||||
source: String,
|
||||
thumbnailUrl: String
|
||||
): EmbedBuilder {
|
||||
val ebb = getEmbed(color, title, description, source)
|
||||
ebb.thumbnail = EmbedBuilder.Thumbnail()
|
||||
ebb.thumbnail!!.url = thumbnailUrl
|
||||
return ebb
|
||||
}
|
||||
}
|
30
src/main/kotlin/net/moonleay/botendo/util/Status.kt
Normal file
30
src/main/kotlin/net/moonleay/botendo/util/Status.kt
Normal 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.util
|
||||
|
||||
object Status {
|
||||
//TODO: impl.
|
||||
suspend fun updateStatus() {
|
||||
/* Bot.kord.editPresence {
|
||||
this.playing("")
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
90
src/main/kotlin/net/moonleay/botendo/util/TimeUtil.kt
Normal file
90
src/main/kotlin/net/moonleay/botendo/util/TimeUtil.kt
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* 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.util
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object TimeUtil {
|
||||
///Convert Miliseconds to xdays xhours xmins xsecs
|
||||
fun getTimeFormatedShortend(timeIn: Long): String {
|
||||
var time = timeIn
|
||||
val days = TimeUnit.MILLISECONDS
|
||||
.toDays(time)
|
||||
time -= TimeUnit.DAYS.toMillis(days)
|
||||
val hours = TimeUnit.MILLISECONDS
|
||||
.toHours(time)
|
||||
time -= TimeUnit.HOURS.toMillis(hours)
|
||||
val minutes = TimeUnit.MILLISECONDS
|
||||
.toMinutes(time)
|
||||
time -= TimeUnit.MINUTES.toMillis(minutes)
|
||||
val seconds = TimeUnit.MILLISECONDS
|
||||
.toSeconds(time)
|
||||
var s = ""
|
||||
if (days >= 1) {
|
||||
s += days.toString() + "d "
|
||||
}
|
||||
if (hours >= 1) {
|
||||
s += hours.toString() + "h "
|
||||
}
|
||||
if (minutes >= 1) {
|
||||
s += minutes.toString() + "m "
|
||||
}
|
||||
if (seconds >= 1 && hours < 1) {
|
||||
s += seconds.toString() + "s"
|
||||
}
|
||||
if (s.isEmpty() || s.isBlank()) {
|
||||
s = "0s"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
fun getTimeFormatedRaw(timeIn: Long): String {
|
||||
var time = timeIn
|
||||
val days = TimeUnit.MILLISECONDS
|
||||
.toDays(time)
|
||||
time -= TimeUnit.DAYS.toMillis(days)
|
||||
val hours = TimeUnit.MILLISECONDS
|
||||
.toHours(time)
|
||||
time -= TimeUnit.HOURS.toMillis(hours)
|
||||
val minutes = TimeUnit.MILLISECONDS
|
||||
.toMinutes(time)
|
||||
time -= TimeUnit.MINUTES.toMillis(minutes)
|
||||
val seconds = TimeUnit.MILLISECONDS
|
||||
.toSeconds(time)
|
||||
var s = ""
|
||||
if (days >= 1) {
|
||||
s += days.toString() + "d "
|
||||
}
|
||||
if (hours >= 1) {
|
||||
s += hours.toString() + "h "
|
||||
}
|
||||
if (minutes >= 1) {
|
||||
s += minutes.toString() + "m "
|
||||
}
|
||||
if (seconds >= 1) {
|
||||
s += seconds.toString() + "s"
|
||||
}
|
||||
if (s.isEmpty() || s.isBlank()) {
|
||||
s = "0s"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
}
|
27
src/main/kotlin/net/moonleay/botendo/util/UrlUtil.kt
Normal file
27
src/main/kotlin/net/moonleay/botendo/util/UrlUtil.kt
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.util
|
||||
|
||||
object UrlUtil {
|
||||
///Strip the video ID from a YouTube link
|
||||
fun getYtThumbnailUrl(uri: String): String {
|
||||
return uri.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue