diff --git a/.gitignore b/.gitignore
index 49298b8..0cba8fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
### CUSTOM ###
/run/
+/data/
+data/
/.idea/
diff --git a/README.md b/README.md
index 4fb6227..2d87a9b 100644
--- a/README.md
+++ b/README.md
@@ -3,33 +3,32 @@
"6th times the charm" ~ me
A Discord music bot, written in Kotlin using the kord library.
-
## Contributors
-
-

-
+[](https://gitlab.com/moonleay)
## Special Thanks to
- HopeBaron for helping me a lot
-## Known issues
+## Issues
-- The Repeat feature does not function
-- The Queue does not show the current song, if there is no song next up
-- Not all comments are listed below
+- Report issues to issues@moonleay.net or message @moonleay on Discord
-## Commands
+## Commands & Features
-- info -- Show basic infos about the bot
-- play -- Play a song
-- stop -- Stop playing a song and leave the vc
+- Commands
+ - info -- Show basic infos about the bot
+ - play -- Play a song and or add it to queue
+ - upsert -- Play a song next up
+ - stop -- Stop playing a song and leave the vc
+ - skip -- Skip to the next song
+ - queue -- Show what songs are next up
+ - nowplaying -- Show what is currently playing
+ - seek -- Seek to a specific time in the song
+- Features
+ - Button Controller -- You can control the currently playing music using buttons.
## How to self-host (using the Docker container)
@@ -61,9 +60,3 @@ A Discord music bot, written in Kotlin using the kord library.
Install IntellJ and import the project from git.
Done.
-
-## Docker commands 4 me
-
-- docker run -it -m 2g -v/home/limited_dev/Documents/Code/Botendo/run/data/:/data/:rw limiteddev/botendo:x.x.x
-- docker build -t limiteddev/botendo:x.x.x .
-- docker push limiteddev/botendo:x.x.x
diff --git a/build.gradle.kts b/build.gradle.kts
index 12da46b..f31be78 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,20 +1,19 @@
/*
- * Botendo
- * Copyright (C) 2023 limited_dev
+ * 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 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 .
+ * 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 .
*/
import org.jetbrains.gradle.ext.ProjectSettings
@@ -30,15 +29,15 @@ plugins {
//Botendo version 6
val ownerID = 372703841151614976L
-group = "de.limited_dev.botendo"
+group = "net.moonleay.botendo"
version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_SHORT_SHA")}-prod" }
?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" }
- ?: "6.3.0"
+ ?: "6.5.5"
-val kordver = "1.5.6"
-val lavaver = "4.0.0"
-val coroutinesver = "1.1.0"
-//val ffmpegver = "5.1.2-1.5.8"
+val kordext_ver = "1.7.1-SNAPSHOT"
+val lavakord_ver = "6.0.0"
+val coroutines_ver = "1.7.3"
+val slf4j_ver = "2.0.9"
val mavenArtifact = "Botendo"
project.base.archivesName.set(mavenArtifact)
@@ -71,6 +70,14 @@ repositories {
}
}
}
+ maven {
+ name = "sonatype"
+ url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots")
+ }
+ maven {
+ name = "sonatype 2"
+ url = uri("https://oss.sonatype.org/content/repositories/snapshots")
+ }
}
val shadow by configurations.getting
@@ -79,18 +86,15 @@ implementation.extendsFrom(shadow)
dependencies {
//Discord
- shadow("com.kotlindiscord.kord.extensions:kord-extensions:$kordver")
- shadow("dev.schlaubi.lavakord:kord:$lavaver")
+ shadow("com.kotlindiscord.kord.extensions:kord-extensions:$kordext_ver")
+ shadow("dev.schlaubi.lavakord:kord:$lavakord_ver")
//Util
- shadow("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesver")
+ shadow("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_ver")
//Logging
- shadow("org.slf4j:slf4j-api:2.0.3")
- shadow("org.slf4j:slf4j-simple:2.0.3")
-
- //ffmpeg
- //shadow("org.bytedeco:ffmpeg:$ffmpegver")
+ shadow("org.slf4j:slf4j-api:$slf4j_ver")
+ shadow("org.slf4j:slf4j-simple:$slf4j_ver")
}
@@ -100,9 +104,9 @@ val templateDest = project.buildDir.resolve("generated/templates")
val templateProps = mapOf(
"version" to project.version as String,
"ownerID" to ownerID,
- "kordversion" to kordver,
- "lavaversion" to lavaver,
- "coroutinesversion" to coroutinesver
+ "kordversion" to kordext_ver,
+ "lavaversion" to lavakord_ver,
+ "coroutinesversion" to coroutines_ver
)
@@ -119,7 +123,7 @@ tasks {
withType {
manifest {
- attributes["Main-Class"] = "de.limited_dev.botendo.MainKt"
+ attributes["Main-Class"] = "net.moonleay.botendo.MainKt"
}
// To add all of the dependencies
from(sourceSets.main.get().output)
diff --git a/gradle.properties b/gradle.properties
index b103626..b2ec467 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,19 +1,18 @@
#
-# Botendo
-# Copyright (C) 2023 limited_dev
+# 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 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 .
+# 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 .
#
kotlin.code.style=official
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 249e583..d64cd49 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 0c59a78..22d4fe0 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,23 +1,25 @@
#
-# Botendo
-# Copyright (C) 2023 limited_dev
+# 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 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 .
+# 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 .
#
+
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 0c7a043..3052411 100755
--- a/gradlew
+++ b/gradlew
@@ -1,22 +1,21 @@
#!/bin/sh
#
-# Botendo
-# Copyright (C) 2023 limited_dev
+# 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 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 .
+# 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 .
#
##############################################################################
@@ -58,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -83,13 +82,11 @@ do
esac
done
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
-
-APP_NAME="Gradle"
+# This is normally unused
+# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -136,22 +133,29 @@ location of your Java installation."
fi
else
JAVACMD=java
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
+ fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -196,11 +200,15 @@ if "$cygwin" || "$msys" ; then
done
fi
-# Collect all arguments for the java command;
-# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
-# shell script including quotes and variable substitutions, so put them in
-# double quotes to make sure that they get re-expanded; and
-# * put everything else in single quotes, so that it's not re-expanded.
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
@@ -208,6 +216,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
diff --git a/gradlew.bat b/gradlew.bat
index 107acd3..93e3f59 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
-@if "%DEBUG%" == "" @echo off
+@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
+if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 7a3ef44..3934113 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,20 +1,19 @@
/*
- * Botendo
- * Copyright (C) 2023 limited_dev
+ * 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 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 .
+ * 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 .
*/
rootProject.name = "Botendo"
diff --git a/src/main/kotlin/de/limited_dev/botendo/Bot.kt b/src/main/kotlin/de/limited_dev/botendo/Bot.kt
deleted file mode 100644
index ac04a8f..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/Bot.kt
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo
-
-import com.kotlindiscord.kord.extensions.ExtensibleBot
-import de.limited_dev.botendo.buttons.ButtonManager
-import de.limited_dev.botendo.data.CredentialManager
-import de.limited_dev.botendo.extensions.music.*
-import de.limited_dev.botendo.extensions.util.InfoExtension
-import de.limited_dev.botendo.extensions.util.PotatoExtension
-import de.limited_dev.botendo.util.Logger
-import de.limited_dev.botendo.util.MessageUtil
-import dev.kord.common.Color
-import dev.kord.core.behavior.interaction.response.respond
-import dev.kord.core.event.interaction.ButtonInteractionCreateEvent
-import dev.kord.core.on
-import dev.schlaubi.lavakord.LavaKord
-import dev.schlaubi.lavakord.kord.lavakord
-
-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(::PotatoExtension)
- }
-
- 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 {
- val inter = this.interaction
- val response = inter.deferPublicResponse()
- val u = inter.user
- val g = this.interaction.getOriginalInteractionResponse().getGuild()
- for (b in 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()
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/Main.kt b/src/main/kotlin/de/limited_dev/botendo/Main.kt
deleted file mode 100644
index 59b9dd8..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/Main.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo
-
-import de.limited_dev.botendo.build.BuildConstants
-
-
-///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.${BuildConstants.version}, Kord Extensions v.${BuildConstants.kordVersion}, LavaKord v.${BuildConstants.lavaVersion}, Coroutines v.${BuildConstants.coroutinesVersion}")
- Bot.start()
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/Button.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/Button.kt
deleted file mode 100644
index 0511e2e..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/buttons/Button.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-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
- ) {
-
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/ButtonManager.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/ButtonManager.kt
deleted file mode 100644
index 614858d..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/buttons/ButtonManager.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.buttons
-
-import de.limited_dev.botendo.buttons.music.*
-
-object ButtonManager {
- val buttons = listOf(RepeatButton(), PauseButton(), SkipButton(), QueueButton(), StopButton())
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/music/PauseButton.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/music/PauseButton.kt
deleted file mode 100644
index f23ed45..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/buttons/music/PauseButton.kt
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-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)
- }
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/music/QueueButton.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/music/QueueButton.kt
deleted file mode 100644
index 6a7615c..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/buttons/music/QueueButton.kt
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-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)
- }
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/music/RepeatButton.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/music/RepeatButton.kt
deleted file mode 100644
index d354134..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/buttons/music/RepeatButton.kt
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-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)
- }
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/music/SkipButton.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/music/SkipButton.kt
deleted file mode 100644
index 38c1992..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/buttons/music/SkipButton.kt
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-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)
- }
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/buttons/music/StopButton.kt b/src/main/kotlin/de/limited_dev/botendo/buttons/music/StopButton.kt
deleted file mode 100644
index fabc991..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/buttons/music/StopButton.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-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
- )
- )
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExtension.kt
deleted file mode 100644
index cb0f1d5..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/NowPlayingExtension.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.extensions.music
-
-import com.kotlindiscord.kord.extensions.extensions.Extension
-import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
-import com.kotlindiscord.kord.extensions.types.respond
-import de.limited_dev.botendo.Bot
-import de.limited_dev.botendo.extensions.music.components.MusicManager
-import de.limited_dev.botendo.util.ButtonUtil
-import de.limited_dev.botendo.util.MessageUtil
-import de.limited_dev.botendo.util.TimeUtil
-import de.limited_dev.botendo.util.UrlUtil
-import dev.kord.common.Color
-import dev.kord.rest.builder.message.create.actionRow
-import dev.schlaubi.lavakord.audio.Link
-import dev.schlaubi.lavakord.kord.getLink
-
-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 = 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(
- 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
- )
- )
-
- this.actionRow {
- ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating)
- }
- }
- }
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExtension.kt
deleted file mode 100644
index 137c16e..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/PlayExtension.kt
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.extensions.music
-
-import com.kotlindiscord.kord.extensions.commands.Arguments
-import com.kotlindiscord.kord.extensions.commands.converters.impl.string
-import com.kotlindiscord.kord.extensions.extensions.Extension
-import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
-import com.kotlindiscord.kord.extensions.types.respond
-import de.limited_dev.botendo.Bot
-import de.limited_dev.botendo.extensions.music.components.MusicManager
-import de.limited_dev.botendo.util.MessageUtil
-import dev.kord.common.Color
-import dev.schlaubi.lavakord.audio.Link
-import dev.schlaubi.lavakord.kord.getLink
-
-
-class PlayExtension : Extension() {
-
- override val name = "play"
-
- override suspend fun setup() {
- publicSlashCommand(::PlayArgs) {
- name = "play"
- description = "Play music"
- this.action {
- val guildId = this.guild!!.id
- val link = 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)
-
- }
- }
- }
-
- inner class PlayArgs : Arguments() {
- val linkquery by string {
- name = "linkqery"
- description = "Song link or search query"
- }
- }
-}
-
diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExtension.kt
deleted file mode 100644
index 69bb99f..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/QueueExtension.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.extensions.music
-
-import com.kotlindiscord.kord.extensions.extensions.Extension
-import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
-import com.kotlindiscord.kord.extensions.types.respond
-import de.limited_dev.botendo.Bot
-import de.limited_dev.botendo.extensions.music.components.MusicManager
-import de.limited_dev.botendo.util.ButtonUtil
-import de.limited_dev.botendo.util.MessageUtil
-import de.limited_dev.botendo.util.TimeUtil
-import dev.kord.common.Color
-import dev.kord.rest.builder.message.create.actionRow
-import dev.schlaubi.lavakord.audio.Link
-
-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 = 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 {
- ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating)
- }
- }
- }
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExtension.kt
deleted file mode 100644
index 039f4e9..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/SkipExtension.kt
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.extensions.music
-
-import com.kotlindiscord.kord.extensions.extensions.Extension
-import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
-import com.kotlindiscord.kord.extensions.types.respond
-import de.limited_dev.botendo.Bot
-import de.limited_dev.botendo.extensions.music.components.MusicManager
-import de.limited_dev.botendo.util.ButtonUtil
-import de.limited_dev.botendo.util.MessageUtil
-import de.limited_dev.botendo.util.TimeUtil
-import de.limited_dev.botendo.util.UrlUtil
-import dev.kord.common.Color
-import dev.kord.rest.builder.message.create.actionRow
-import dev.schlaubi.lavakord.audio.Link
-
-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 = 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()
- } 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}",
- "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)
- }
- }
- }
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExtension.kt
deleted file mode 100644
index 7c361ba..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/StopExtension.kt
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.extensions.music
-
-import com.kotlindiscord.kord.extensions.extensions.Extension
-import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
-import com.kotlindiscord.kord.extensions.types.respond
-import de.limited_dev.botendo.Bot
-import de.limited_dev.botendo.extensions.music.components.MusicManager
-import de.limited_dev.botendo.util.MessageUtil
-import dev.kord.common.Color
-import dev.schlaubi.lavakord.audio.Link
-import dev.schlaubi.lavakord.kord.getLink
-
-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 = 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
- )
- )
- }
- }
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/GuildTrackScheduler.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/GuildTrackScheduler.kt
deleted file mode 100644
index 0efb9f3..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/GuildTrackScheduler.kt
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.extensions.music.components
-
-import de.limited_dev.botendo.util.Logger
-import dev.schlaubi.lavakord.audio.*
-import dev.schlaubi.lavakord.audio.player.Player
-import dev.schlaubi.lavakord.rest.models.PartialTrack
-import java.util.concurrent.BlockingQueue
-import java.util.concurrent.LinkedBlockingQueue
-
-class GuildTrackScheduler(val pl: Player) {
-
- private var queue: BlockingQueue = 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) {
- if (this.pl.playingTrack == null) {
- play(track)
- } else {
- queue.offer(track)
- }
- }
-
- suspend fun playNext() {
- if (!queue.isEmpty())
- this.pl.playTrack(queue.poll())
- else
- this.pl.stopTrack()
- }
-
- 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 {
- onTrackEnd(this)
- }
-
- pl.on {
- onTrackStuck(this)
- }
-
- pl.on {
- 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()
- }
- }
-
- 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 {
- return queue.toList()
- }
-
- fun getHead(): PartialTrack {
- return queue.first()
- }
-
- fun isEmpty(): Boolean {
- return queue.isEmpty()
- }
-}
-
diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt
deleted file mode 100644
index 8ee57ec..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/extensions/music/components/MusicManager.kt
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.extensions.music.components
-
-import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext
-import com.kotlindiscord.kord.extensions.components.forms.ModalForm
-import com.kotlindiscord.kord.extensions.types.respond
-import de.limited_dev.botendo.extensions.music.PlayExtension
-import de.limited_dev.botendo.util.ButtonUtil
-import de.limited_dev.botendo.util.MessageUtil
-import de.limited_dev.botendo.util.TimeUtil
-import de.limited_dev.botendo.util.UrlUtil
-import dev.kord.common.Color
-import dev.kord.common.entity.Snowflake
-import dev.kord.core.entity.Guild
-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
-
-object MusicManager {
- private var musicManagerMap: MutableMap = mutableMapOf()
-
- fun getGuildTrackScheduler(guild: Guild, player: Player): GuildTrackScheduler {
- return musicManagerMap.computeIfAbsent(guild.id) {
- GuildTrackScheduler(player)
- }
- }
-
-
- suspend fun addToQueue(
- ctx: PublicSlashCommandContext,
- link: Link,
- search: String
- ) {
- addToQueue(ctx, link, search, false)
- }
-
- suspend fun addToQueue(
- ctx: PublicSlashCommandContext,
- link: Link,
- search: String,
- 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)
- if (!silent)
- ctx.respond {
- this.embeds.add(
- MessageUtil.getEmbedWithImage(
- Color(0x52E01A),
- "Queuing 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)
- }
- if (!silent)
- ctx.respond {
- this.embeds.add(
- MessageUtil.getEmbedWithImage(
- Color(0x52E01A),
- "Queuing playlist from link",
- "**${item.tracks.first().info.title}**\n*${item.playlistInfo.name}*\nby ${item.tracks.first().info.author} :: ${
- TimeUtil.getTimeFormatedRaw(
- item.tracks.first().info.length
- )
- }\n" +
- ">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator,
- "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg"
- )
- )
-
- this.actionRow {
- this.components.addAll(
- ButtonUtil.getMusicControllerButtons(
- player.paused,
- gts.repeating
- ).components
- )
- }
- }
- }
-
- TrackResponse.LoadType.SEARCH_RESULT -> {
- gts.queue(item.tracks.first())
- if (!silent)
- ctx.respond {
- this.embeds.add(
- MessageUtil.getEmbedWithImage(
- Color(0x52E01A),
- "Queuing 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
- )
- )
- }
- }
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExtension.kt
deleted file mode 100644
index 34b151b..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/extensions/util/InfoExtension.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.extensions.util
-
-import com.kotlindiscord.kord.extensions.extensions.Extension
-import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
-import de.limited_dev.botendo.build.BuildConstants
-import de.limited_dev.botendo.util.MessageUtil
-import dev.kord.common.Color
-
-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." + BuildConstants.version + "***\n" +
- "Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" +
- "lavalink.kt ***v." + BuildConstants.lavaVersion + "***\n" +
- "Coroutines ***v." + BuildConstants.coroutinesVersion + "***\n\n\n" +
- "***Bot made by moonleay#7441***\n" +
- "(c) 2023, licensed under GPL-3.0"
- )
- }
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/extensions/util/PotatoExtension.kt b/src/main/kotlin/de/limited_dev/botendo/extensions/util/PotatoExtension.kt
deleted file mode 100644
index 2f46c5b..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/extensions/util/PotatoExtension.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.extensions.util
-
-import com.kotlindiscord.kord.extensions.extensions.Extension
-import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
-import de.limited_dev.botendo.util.MessageUtil
-import dev.kord.common.Color
-
-class PotatoExtension : Extension() {
- override val name = "potato"
- override suspend fun setup() {
- publicSlashCommand {
- name = "potato"
- description = "Potato"
- this.action {
- MessageUtil.sendEmbedForPublicSlashCommandWithImage(
- this, Color(0xE0311A), "Potato",
- "Potato",
- "https://static.tumblr.com/c06d8e0928395746a63b9c5d3cb1ce66/sl9iajp/gxFmqk38z/tumblr_static_potato-equality.jpg"
- )
- }
- }
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/util/Logger.kt b/src/main/kotlin/de/limited_dev/botendo/util/Logger.kt
deleted file mode 100644
index 4164218..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/util/Logger.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.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)).toString() + "] <" + msg + ">"
- )
- } catch (e: ClassNotFoundException) {
- e.printStackTrace()
- }
- // Ich kann nicht mehr
- // [Klasse.Funktion] [T/M HH:MM]
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/util/MessageUtil.kt b/src/main/kotlin/de/limited_dev/botendo/util/MessageUtil.kt
deleted file mode 100644
index 5085188..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/util/MessageUtil.kt
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.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,
- 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,
- 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
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/util/Status.kt b/src/main/kotlin/de/limited_dev/botendo/util/Status.kt
deleted file mode 100644
index f8d6201..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/util/Status.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.util
-
-object Status {
- //TODO: impl.
- suspend fun updateStatus() {
- /* Bot.kord.editPresence {
- this.playing("")
- }
- */
- }
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/util/TimeUtil.kt b/src/main/kotlin/de/limited_dev/botendo/util/TimeUtil.kt
deleted file mode 100644
index d2a9676..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/util/TimeUtil.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.botendo.util
-
-import java.util.concurrent.TimeUnit
-
-object TimeUtil {
- ///Convert Miliseconds to xdays xhours xmins xsecs
- fun getTimeFormatedShortend(time: Long): String {
- var time = time
- 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(time: Long): String {
- var time = time
- 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
- }
-
-}
diff --git a/src/main/kotlin/de/limited_dev/botendo/util/UrlUtil.kt b/src/main/kotlin/de/limited_dev/botendo/util/UrlUtil.kt
deleted file mode 100644
index ed67935..0000000
--- a/src/main/kotlin/de/limited_dev/botendo/util/UrlUtil.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Botendo
- * Copyright (C) 2023 limited_dev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package de.limited_dev.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]
- }
-}
diff --git a/src/main/kotlin/net/moonleay/botendo/Bot.kt b/src/main/kotlin/net/moonleay/botendo/Bot.kt
new file mode 100644
index 0000000..ca3bb19
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/Bot.kt
@@ -0,0 +1,144 @@
+/*
+ * 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 .
+ */
+
+package net.moonleay.botendo
+
+import com.kotlindiscord.kord.extensions.ExtensibleBot
+import dev.kord.common.Color
+import dev.kord.common.entity.Snowflake
+import dev.kord.core.behavior.getChannelOf
+import dev.kord.core.behavior.interaction.response.respond
+import dev.kord.core.entity.channel.VoiceChannel
+import dev.kord.core.event.interaction.ButtonInteractionCreateEvent
+import dev.kord.core.event.user.VoiceStateUpdateEvent
+import dev.kord.core.on
+import dev.kord.rest.builder.message.embed
+import dev.schlaubi.lavakord.LavaKord
+import dev.schlaubi.lavakord.audio.Link
+import dev.schlaubi.lavakord.kord.getLink
+import dev.schlaubi.lavakord.kord.lavakord
+import kotlinx.coroutines.flow.count
+import net.moonleay.botendo.data.CredentialManager
+import net.moonleay.botendo.extensions.music.*
+import net.moonleay.botendo.extensions.music.components.MusicManager
+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)
+ add(::SeekExtension)
+ }
+
+ this.presence {
+ this.streaming("music", "https://twitch.tv/moonleaytv")
+ }
+ }
+
+ //Add LavaLink
+ lava = bot.kordRef.lavakord()
+
+ //Add the LavaLink node from config
+ lava.addNode(CredentialManager.linkip, CredentialManager.linkpw)
+
+ //Register Button presses
+ bot.kordRef.on {
+ 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
+ }
+ // Button not found
+ response.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Error"
+ this.description = "Could not find button with id \"${inter.componentId}\".\nPlease report this."
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ }
+
+ // Allow the bot to leave the VC if there are no users in the VC
+ bot.kordRef.on {
+ if (this.state.userId == bot.kordRef.selfId) {
+ // Ignore self
+ return@on
+ }
+ val g = this.state.getGuild().asGuild()
+ val link = lava.getLink(g.id)
+ if (link.state != Link.State.CONNECTED) {
+ // Ignore if not connected
+ return@on
+ }
+ val myChannel = link.lastChannelId!!
+ if (g.getChannelOrNull(Snowflake(myChannel)) == null) {
+ // Ignore if channel cannot be found
+ return@on
+ }
+ val ch = g.getChannelOf(Snowflake(myChannel))
+ if (ch.voiceStates.count() > 1) {
+ // Ignore if there are other users in the channel
+ return@on
+ }
+ // Stop playing if there are no users in the channel
+ val pl = MusicManager.getMusicManager(g)!!.pl
+ pl.stopTrack()
+ link.destroy()
+ }
+
+ //Start the bot
+ bot.start()
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/Main.kt b/src/main/kotlin/net/moonleay/botendo/Main.kt
new file mode 100644
index 0000000..0555150
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/Main.kt
@@ -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 .
+ */
+
+package net.moonleay.botendo
+
+import net.moonleay.botendo.util.Logger
+
+
+///Show the splash and launch the Bot
+suspend fun main(args: Array) {
+ 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}")
+ if(args.isEmpty() || args[0] != "--debug") {
+ Logger.out("Waiting 10 seconds for Lavalink to start...")
+ Thread.sleep(10000)
+ }
+ Bot.start()
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/buttons/Button.kt b/src/main/kotlin/net/moonleay/botendo/buttons/Button.kt
new file mode 100644
index 0000000..e0c10ef
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/buttons/Button.kt
@@ -0,0 +1,34 @@
+/*
+ * 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 .
+ */
+
+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
+ ) {
+
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/buttons/ButtonManager.kt b/src/main/kotlin/net/moonleay/botendo/buttons/ButtonManager.kt
new file mode 100644
index 0000000..3ab406e
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/buttons/ButtonManager.kt
@@ -0,0 +1,31 @@
+/*
+ * 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 .
+ */
+
+package net.moonleay.botendo.buttons
+
+import net.moonleay.botendo.buttons.music.*
+
+object ButtonManager {
+ val buttons = listOf(
+ RepeatButton(),
+ PauseButton(),
+ SkipButton(),
+ QueueButton(),
+ StopButton()
+ )
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/buttons/music/PauseButton.kt b/src/main/kotlin/net/moonleay/botendo/buttons/music/PauseButton.kt
new file mode 100644
index 0000000..a03ee51
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/buttons/music/PauseButton.kt
@@ -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 .
+ */
+
+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.component.ActionRowBuilder
+import dev.kord.rest.builder.message.actionRow
+import dev.kord.rest.builder.message.embed
+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.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not connected to a VC"
+ this.description = "Please connect to a VC"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ }
+
+ val channelId = voiceState.channelId
+ if (link.state == Link.State.NOT_CONNECTED) {
+ response.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not connected"
+ this.description = "I'm not in a VC and therefore, I am not playing anything."
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
+ response.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not in my VC"
+ this.description = "We are not in the same VC and therefore, you cannot control the music"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ }
+
+ player.pause(!player.paused)
+
+ val gts = MusicManager.getGuildTrackScheduler(guild, player)
+ response.respond {
+ this.embed {
+ this.color = Color(0x52E01A)
+ this.title = if (player.paused) "I paused" else "I'm continuing"
+ this.description = if (player.paused) "I paused the song" else "I'm continuing to play the song."
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+
+ this.actionRow(fun ActionRowBuilder.() {
+ components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
+ })
+ }
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/buttons/music/QueueButton.kt b/src/main/kotlin/net/moonleay/botendo/buttons/music/QueueButton.kt
new file mode 100644
index 0000000..c786818
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/buttons/music/QueueButton.kt
@@ -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 .
+ */
+
+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.component.ActionRowBuilder
+import dev.kord.rest.builder.message.actionRow
+import dev.kord.rest.builder.message.embed
+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.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not connected"
+ this.description = "I'm not in a VC and therefore, I am not playing anything."
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ }
+
+ if (player.playingTrack == null) {
+ response.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not playing"
+ this.description = "I'm not playing anything currently"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ }
+ val track = player.playingTrack!!.info
+ val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
+ val q = gts.getQueue()
+ var desc =
+ """${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length)} (${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.embed {
+ this.color = Color(0x52E01A)
+ this.title = "Queue"
+ this.description = desc
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+
+ this.actionRow(fun ActionRowBuilder.() {
+ components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
+ })
+ }
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/buttons/music/RepeatButton.kt b/src/main/kotlin/net/moonleay/botendo/buttons/music/RepeatButton.kt
new file mode 100644
index 0000000..462f207
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/buttons/music/RepeatButton.kt
@@ -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 .
+ */
+
+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.component.ActionRowBuilder
+import dev.kord.rest.builder.message.actionRow
+import dev.kord.rest.builder.message.embed
+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.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not connected to a VC"
+ this.description = "Please connect to a VC"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ }
+
+ val channelId = voiceState.channelId
+ if (link.state == Link.State.NOT_CONNECTED) {
+ response.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not connected"
+ this.description = "I'm not in a VC and therefore, I am not playing anything."
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
+ response.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not in my VC"
+ this.description = "We are not in the same VC and therefore, you cannot control the music"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ }
+
+ val gts = MusicManager.getGuildTrackScheduler(guild, player)
+ gts.repeating = !gts.repeating
+ response.respond {
+ this.embed {
+ this.color = Color(0x52E01A)
+ this.title = if (gts.repeating) "Now Repeating" else "Now Continuing"
+ this.description =
+ if (gts.repeating) "The current track will now loop" else "The next track will play when this song finishes"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+
+ this.actionRow(fun ActionRowBuilder.() {
+ components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
+ })
+ }
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/buttons/music/SkipButton.kt b/src/main/kotlin/net/moonleay/botendo/buttons/music/SkipButton.kt
new file mode 100644
index 0000000..8f04ea1
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/buttons/music/SkipButton.kt
@@ -0,0 +1,150 @@
+/*
+ * 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 .
+ */
+
+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.component.ActionRowBuilder
+import dev.kord.rest.builder.message.actionRow
+import dev.kord.rest.builder.message.embed
+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.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not connected to a VC"
+ this.description = "Please connect to a VC"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ }
+
+ val channelId = voiceState.channelId
+ if (link.state == Link.State.NOT_CONNECTED) {
+ response.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not connected"
+ this.description = "I'm not in a VC and therefore, I am not playing anything."
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
+ response.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not in my VC"
+ this.description = "We are not in the same VC and therefore, you cannot control the music"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ }
+ if (player.playingTrack == null) {
+ response.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not Playing"
+ this.description = "I'm not playing anything currently"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ }
+ var track = player.playingTrack!!.info
+ val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
+ if (!gts.isEmpty()) {
+ track = gts.getHead().info
+ gts.playNext(link)
+ response.respond {
+ this.embed {
+ this.color = Color(0x52E01A)
+ this.title = "Skipped song; now playing"
+ this.description = "**${track.title}**\n*Now Playing*\nby ${track.author} :: ${
+ TimeUtil.getTimeFormatedRaw(
+ track.length
+ )
+ }\n" +
+ ">>>${track.uri}"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ this.thumbnail {
+ this.url = "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.embed {
+ this.color = Color(0x52E01A)
+ this.title = "Skipped song"
+ this.description = "Nothing"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ this.actionRow(fun ActionRowBuilder.() {
+ components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
+ })
+ }
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/buttons/music/StopButton.kt b/src/main/kotlin/net/moonleay/botendo/buttons/music/StopButton.kt
new file mode 100644
index 0000000..eb1a213
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/buttons/music/StopButton.kt
@@ -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 .
+ */
+
+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.embed
+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.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not connected to a VC"
+ this.description = "Please connect to a VC"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ }
+
+ val channelId = voiceState.channelId
+ if (link.state == Link.State.NOT_CONNECTED) {
+ response.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not connected"
+ this.description = "I'm not in a VC and therefore, I am not playing anything."
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
+ response.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not in my VC"
+ this.description = "We are not in the same VC and therefore, you cannot control the music"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ return
+ }
+
+ player.stopTrack()
+ link.destroy()
+ MusicManager.getGuildTrackScheduler(guild.asGuild(), player).clear()
+ response.respond {
+ this.embed {
+ this.color = Color(0x52E01A)
+ this.title = "I stopped and left"
+ this.description = "just like your girlfriend"
+ this.footer {
+ this.text = MessageUtil.getFooter(user)
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/de/limited_dev/botendo/data/CredentialManager.kt b/src/main/kotlin/net/moonleay/botendo/data/CredentialManager.kt
similarity index 74%
rename from src/main/kotlin/de/limited_dev/botendo/data/CredentialManager.kt
rename to src/main/kotlin/net/moonleay/botendo/data/CredentialManager.kt
index af04e33..23ca661 100644
--- a/src/main/kotlin/de/limited_dev/botendo/data/CredentialManager.kt
+++ b/src/main/kotlin/net/moonleay/botendo/data/CredentialManager.kt
@@ -1,23 +1,22 @@
/*
- * Botendo
- * Copyright (C) 2023 limited_dev
+ * 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 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 .
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
*/
-package de.limited_dev.botendo.data
+package net.moonleay.botendo.data
import java.io.*
import java.util.*
diff --git a/src/main/kotlin/net/moonleay/botendo/extensions/music/NowPlayingExtension.kt b/src/main/kotlin/net/moonleay/botendo/extensions/music/NowPlayingExtension.kt
new file mode 100644
index 0000000..de60cde
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/extensions/music/NowPlayingExtension.kt
@@ -0,0 +1,111 @@
+/*
+ * 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 .
+ */
+
+package net.moonleay.botendo.extensions.music
+
+import com.kotlindiscord.kord.extensions.extensions.Extension
+import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
+import dev.kord.common.Color
+import dev.kord.rest.builder.component.ActionRowBuilder
+import dev.kord.rest.builder.message.actionRow
+import dev.kord.rest.builder.message.embed
+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
+ val u = this.user
+ if (link.state == Link.State.NOT_CONNECTED) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not connected"
+ this.description = "I'm not in a VC and therefore, I am not playing anything."
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+ val track = player.playingTrack
+ if (track == null) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not Playing"
+ this.description = "I'm not playing anything currently"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+ val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
+
+ this.respond {
+ this.embed {
+ this.color = Color(0x52E01A)
+ this.title = "Currently playing"
+ this.description = "**${track.info.title}**\n*Now Playing*\nby ${track.info.author} ; ${
+ TimeUtil.getTimeFormatedRaw(
+ player.position
+ )
+ }: ${
+ TimeUtil.getTimeFormatedRaw(
+ track.info.length
+ )
+ }\n" +
+ ">>>${track.info.uri}"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ if(track.info.uri == null){
+ this.thumbnail {
+ this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.info.uri!!) + "/maxresdefault.jpg"
+ }
+ }
+ }
+
+ this.actionRow(fun ActionRowBuilder.() {
+ components.addAll(
+ ButtonUtil.getMusicControllerButtons(
+ player.paused,
+ gts.repeating
+ ).components
+ )
+ })
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/extensions/music/PlayExtension.kt b/src/main/kotlin/net/moonleay/botendo/extensions/music/PlayExtension.kt
new file mode 100644
index 0000000..7342c14
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/extensions/music/PlayExtension.kt
@@ -0,0 +1,100 @@
+/*
+ * 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 .
+ */
+
+package net.moonleay.botendo.extensions.music
+
+import com.kotlindiscord.kord.extensions.extensions.Extension
+import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
+import dev.kord.common.Color
+import dev.kord.rest.builder.message.embed
+import dev.schlaubi.lavakord.audio.Link
+import dev.schlaubi.lavakord.kord.getLink
+import net.moonleay.botendo.Bot
+import net.moonleay.botendo.extensions.music.components.LinkArguments
+import net.moonleay.botendo.extensions.music.components.MusicManager
+import net.moonleay.botendo.util.MessageUtil
+import net.moonleay.botendo.util.UserUtil
+
+
+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 = Bot.lava.getLink(guildId)
+ val u = this.user
+ val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
+ if (vcsUser == null) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not connected to a VC"
+ this.description = "Please connect to a VC"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ 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 {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not in my VC"
+ this.description = "We are not in the same VC and therefore, you cannot play any music"
+ this.author {
+ this.name = UserUtil.getCommandSrc(u)
+ }
+ }
+ }
+ return@action
+ }
+
+ val query = arguments.linkquery
+ val search = if (query.startsWith("http")) {
+ query
+ } else {
+ "ytsearch:$query"
+ }
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0A81A)
+ this.title = "Searching..."
+ this.description = "We are looking for $query"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ MusicManager.addToQueue(this, link, search)
+ }
+ }
+ }
+}
+
diff --git a/src/main/kotlin/net/moonleay/botendo/extensions/music/QueueExtension.kt b/src/main/kotlin/net/moonleay/botendo/extensions/music/QueueExtension.kt
new file mode 100644
index 0000000..f63078a
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/extensions/music/QueueExtension.kt
@@ -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 .
+ */
+
+package net.moonleay.botendo.extensions.music
+
+import com.kotlindiscord.kord.extensions.extensions.Extension
+import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
+import dev.kord.common.Color
+import dev.kord.rest.builder.component.ActionRowBuilder
+import dev.kord.rest.builder.message.actionRow
+import dev.kord.rest.builder.message.embed
+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
+ val u = this.user
+ if (link.state == Link.State.NOT_CONNECTED) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not connected"
+ this.description = "I'm not in a VC and therefore, I am not playing anything."
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+ val track = player.playingTrack
+ if (track == null) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Queue empty"
+ this.description = "I'm not playing anything currently"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+ val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
+ val q = gts.getQueue()
+ var desc =
+ """${"**" + track.info.title + " - " + TimeUtil.getTimeFormatedShortend(track.info.length)} (${track.info.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.embed {
+ this.color = Color(0x52E01A)
+ this.title = "Queue"
+ this.description = desc
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+
+ this.actionRow(fun ActionRowBuilder.() {
+ components.addAll(
+ ButtonUtil.getMusicControllerButtons(
+ player.paused,
+ gts.repeating
+ ).components
+ )
+ })
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/extensions/music/SeekExtension.kt b/src/main/kotlin/net/moonleay/botendo/extensions/music/SeekExtension.kt
new file mode 100644
index 0000000..f5bfb34
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/extensions/music/SeekExtension.kt
@@ -0,0 +1,155 @@
+/*
+ * 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 .
+ */
+
+package net.moonleay.botendo.extensions.music
+
+import com.kotlindiscord.kord.extensions.extensions.Extension
+import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
+import dev.kord.common.Color
+import dev.kord.rest.builder.component.ActionRowBuilder
+import dev.kord.rest.builder.message.actionRow
+import dev.kord.rest.builder.message.embed
+import dev.schlaubi.lavakord.audio.Link
+import net.moonleay.botendo.extensions.music.components.MusicManager
+import net.moonleay.botendo.extensions.music.components.SeekArguments
+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 SeekExtension : Extension() {
+ override val name = "seek"
+ override suspend fun setup() {
+ publicSlashCommand(::SeekArguments) {
+ name = "seek"
+ description = "Skip to a certain point in a track"
+ 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) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not connected to a VC"
+ this.description = "Please connect to a VC"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+
+ val channelId = voiceState.channelId
+ if (link.state == Link.State.NOT_CONNECTED) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not connected"
+ this.description = "I'm not in a VC and therefore, I am not playing anything."
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not in my VC"
+ this.description = "We are not in the same VC and therefore, you cannot control the music"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+ if (player.playingTrack == null) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not playing"
+ this.description = "I'm not playing anything currently"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+ var track = player.playingTrack!!.info
+ val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
+ val targetPos = TimeUtil.getTimeUnformated(this.arguments.position)
+ if (player.playingTrack!!.info.length > targetPos && targetPos >= 0) {
+ player.seekTo(targetPos)
+ } else {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Invalid position"
+ this.description = "The position you specified is invalid"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+
+
+ this.respond {
+ this.embed {
+ this.color = Color(0x52E01A)
+ this.title = "Jumped; now playing"
+ this.description = "**${track.title}**\n*Now Playing*\nby ${track.author} ; ${
+ TimeUtil.getTimeFormatedRaw(
+ player.position
+ )
+ }: ${
+ TimeUtil.getTimeFormatedRaw(
+ track.length
+ )
+ }\n" +
+ ">>>${track.uri}"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ this.thumbnail {
+ this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
+
+ }
+ }
+
+ this.actionRow(fun ActionRowBuilder.() {
+ components.addAll(
+ ButtonUtil.getMusicControllerButtons(
+ player.paused,
+ gts.repeating
+ ).components
+ )
+ })
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/extensions/music/SkipExtension.kt b/src/main/kotlin/net/moonleay/botendo/extensions/music/SkipExtension.kt
new file mode 100644
index 0000000..e11cdc6
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/extensions/music/SkipExtension.kt
@@ -0,0 +1,139 @@
+/*
+ * 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 .
+ */
+
+package net.moonleay.botendo.extensions.music
+
+import com.kotlindiscord.kord.extensions.extensions.Extension
+import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
+import dev.kord.common.Color
+import dev.kord.rest.builder.component.ActionRowBuilder
+import dev.kord.rest.builder.message.actionRow
+import dev.kord.rest.builder.message.embed
+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) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not connected to a VC"
+ this.description = "Please connect to a VC"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+
+ val channelId = voiceState.channelId
+ if (link.state == Link.State.NOT_CONNECTED) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not connected"
+ this.description = "I'm not in a VC and therefore, I am not playing anything."
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not in my VC"
+ this.description = "We are not in the same VC and therefore, you cannot control the music"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+ var track = player.playingTrack!!.info
+ if (track == null) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not playing"
+ this.description = "I'm not playing anything currently"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+ val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
+ if (!gts.isEmpty()) {
+ track = gts.getHead().info
+ gts.playNext(link)
+ } else {
+ player.stopTrack()
+ }
+
+
+ this.respond {
+ this.embed {
+ this.color = Color(0x52E01A)
+ this.title = "Skipped song; now playing"
+ this.description = "**${track.title}**\n*Now Playing*\nby ${track.author} ;: ${
+ TimeUtil.getTimeFormatedRaw(
+ track.length
+ )
+ }\n" +
+ ">>>${track.uri}"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ this.thumbnail {
+ this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
+ }
+ }
+
+ this.actionRow(fun ActionRowBuilder.() {
+ components.addAll(
+ ButtonUtil.getMusicControllerButtons(
+ player.paused,
+ gts.repeating
+ ).components
+ )
+ })
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/extensions/music/StopExtension.kt b/src/main/kotlin/net/moonleay/botendo/extensions/music/StopExtension.kt
new file mode 100644
index 0000000..5c0722a
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/extensions/music/StopExtension.kt
@@ -0,0 +1,97 @@
+/*
+ * 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 .
+ */
+
+package net.moonleay.botendo.extensions.music
+
+import com.kotlindiscord.kord.extensions.extensions.Extension
+import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
+import dev.kord.common.Color
+import dev.kord.rest.builder.message.embed
+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.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not connected to a VC"
+ this.description = "Please connect to a VC"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+ val channelId = vcsUser.channelId
+ if (link.state == Link.State.NOT_CONNECTED) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "Not connected"
+ this.description = "I'm not in a VC and therefore, I am not playing anything."
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not in my VC"
+ this.description = "We are not in the same VC"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+ player.stopTrack()
+ link.destroy()
+ MusicManager.getGuildTrackScheduler(this.getGuild()!!.asGuild(), player).clear()
+ this.respond {
+ this.embed {
+ this.color = Color(0x52E01A)
+ this.title = "I stopped and left"
+ this.description = "just like your girlfriend"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/botendo/extensions/music/UpsertExtension.kt b/src/main/kotlin/net/moonleay/botendo/extensions/music/UpsertExtension.kt
new file mode 100644
index 0000000..f2d90d7
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/extensions/music/UpsertExtension.kt
@@ -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 .
+ */
+
+package net.moonleay.botendo.extensions.music
+
+import com.kotlindiscord.kord.extensions.extensions.Extension
+import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
+import dev.kord.common.Color
+import dev.kord.rest.builder.message.embed
+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 {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not connected to a VC"
+ this.description = "Please connect to a VC"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ 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 {
+ this.embed {
+ this.color = Color(0xE0311A)
+ this.title = "You are not in my VC"
+ this.description = "We are not in the same VC and therefore, you cannot play any music"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ return@action
+ }
+
+ val query = arguments.linkquery
+ val search = if (query.startsWith("http")) {
+ query
+ } else {
+ "ytsearch:$query"
+ }
+ this.respond {
+ this.embed {
+ this.color = Color(0xE0A81A)
+ this.title = "Searching..."
+ this.description = "We are looking for $query"
+ this.footer {
+ this.text = MessageUtil.getFooter(u)
+ }
+ }
+ }
+ MusicManager.upsertIntoQueue(this, link, search)
+ }
+ }
+ }
+}
+
diff --git a/src/main/kotlin/net/moonleay/botendo/extensions/music/components/GuildTrackScheduler.kt b/src/main/kotlin/net/moonleay/botendo/extensions/music/components/GuildTrackScheduler.kt
new file mode 100644
index 0000000..ed90f17
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/botendo/extensions/music/components/GuildTrackScheduler.kt
@@ -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 .
+ */
+
+package net.moonleay.botendo.extensions.music.components
+
+import dev.arbjerg.lavalink.protocol.v4.Track
+import dev.schlaubi.lavakord.audio.*
+import dev.schlaubi.lavakord.audio.player.Player
+import net.moonleay.botendo.Bot
+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