Compare commits
34 commits
Author | SHA1 | Date | |
---|---|---|---|
8cc3e70f24 | |||
1dec02f40f | |||
e3d107199e | |||
425c9bf1cd | |||
3d66548a3d | |||
9b51693a75 | |||
8b6b7dc5d5 | |||
ae507dc4aa | |||
232a854863 | |||
a7bafe5a7e | |||
aa81261dd9 | |||
acefe1b712 | |||
fab645d945 | |||
6cc91f0cfe | |||
6c83ea6b4c | |||
e1fdc954ce | |||
a2ce58010a | |||
589997c29e | |||
55ccb175e1 | |||
3a9795794c | |||
5a65aad3e2 | |||
1cbf631f27 | |||
f94d6c6ae7 | |||
b59b72b3b8 | |||
266da050d2 | |||
cccd602a94 | |||
26137e8806 | |||
aabab047f7 | |||
d8f8231028 | |||
47f92a0765 | |||
ee6b31a868 | |||
c087a484a4 | |||
142f60ec71 | |||
2e309dfc52 |
39 changed files with 950 additions and 652 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,5 +1,7 @@
|
||||||
### CUSTOM ###
|
### CUSTOM ###
|
||||||
/run/
|
/run/
|
||||||
|
/data/
|
||||||
|
data/
|
||||||
/.idea/
|
/.idea/
|
||||||
|
|
||||||
|
|
||||||
|
|
19
README.md
19
README.md
|
@ -4,23 +4,17 @@
|
||||||
|
|
||||||
A Discord music bot, written in Kotlin using the kord library.
|
A Discord music bot, written in Kotlin using the kord library.
|
||||||
|
|
||||||
[![Latest Release](https://gitlab.com/moonleay/botendo/-/badges/release.svg)](https://gitlab.com/moonleay/botendo/-/releases)
|
|
||||||
[![pipeline status](https://gitlab.com/moonleay/botendo/badges/master/pipeline.svg)](https://gitlab.com/moonleay/botendo/-/commits/master)
|
|
||||||
[![coverage report](https://gitlab.com/moonleay/botendo/badges/master/coverage.svg)](https://gitlab.com/moonleay/botendo/-/commits/master)
|
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
<div class="aside">
|
[![Developer](https://img.shields.io/badge/moonleay-Developer-red)](https://gitlab.com/moonleay)
|
||||||
<img src="https://img.shields.io/badge/moonleay-Head%20Developer-red" alt="moonleay: Head Developer"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## Special Thanks to
|
## Special Thanks to
|
||||||
|
|
||||||
- HopeBaron for helping me a lot
|
- HopeBaron for helping me a lot
|
||||||
|
|
||||||
## Known issues
|
## Issues
|
||||||
|
|
||||||
- None (currently). Report issues to issues@moonleay.net or moonleay#0069
|
- Report issues to issues@moonleay.net or message @moonleay on Discord
|
||||||
|
|
||||||
## Commands & Features
|
## Commands & Features
|
||||||
|
|
||||||
|
@ -32,6 +26,7 @@ A Discord music bot, written in Kotlin using the kord library.
|
||||||
- skip -- Skip to the next song
|
- skip -- Skip to the next song
|
||||||
- queue -- Show what songs are next up
|
- queue -- Show what songs are next up
|
||||||
- nowplaying -- Show what is currently playing
|
- nowplaying -- Show what is currently playing
|
||||||
|
- seek -- Seek to a specific time in the song
|
||||||
- Features
|
- Features
|
||||||
- Button Controller -- You can control the currently playing music using buttons.
|
- Button Controller -- You can control the currently playing music using buttons.
|
||||||
|
|
||||||
|
@ -65,9 +60,3 @@ A Discord music bot, written in Kotlin using the kord library.
|
||||||
|
|
||||||
Install IntellJ and import the project from git.
|
Install IntellJ and import the project from git.
|
||||||
Done.
|
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
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import org.jetbrains.gradle.ext.ProjectSettings
|
import org.jetbrains.gradle.ext.ProjectSettings
|
||||||
|
@ -33,11 +32,12 @@ val ownerID = 372703841151614976L
|
||||||
group = "net.moonleay.botendo"
|
group = "net.moonleay.botendo"
|
||||||
version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_SHORT_SHA")}-prod" }
|
version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_SHORT_SHA")}-prod" }
|
||||||
?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" }
|
?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" }
|
||||||
?: "6.4.0"
|
?: "6.5.5"
|
||||||
|
|
||||||
val kordver = "1.5.6"
|
val kordext_ver = "1.7.1-SNAPSHOT"
|
||||||
val lavaver = "4.0.0"
|
val lavakord_ver = "6.0.0"
|
||||||
val coroutinesver = "1.1.0"
|
val coroutines_ver = "1.7.3"
|
||||||
|
val slf4j_ver = "2.0.9"
|
||||||
|
|
||||||
val mavenArtifact = "Botendo"
|
val mavenArtifact = "Botendo"
|
||||||
project.base.archivesName.set(mavenArtifact)
|
project.base.archivesName.set(mavenArtifact)
|
||||||
|
@ -70,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
|
val shadow by configurations.getting
|
||||||
|
@ -78,15 +86,15 @@ implementation.extendsFrom(shadow)
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
//Discord
|
//Discord
|
||||||
shadow("com.kotlindiscord.kord.extensions:kord-extensions:$kordver")
|
shadow("com.kotlindiscord.kord.extensions:kord-extensions:$kordext_ver")
|
||||||
shadow("dev.schlaubi.lavakord:kord:$lavaver")
|
shadow("dev.schlaubi.lavakord:kord:$lavakord_ver")
|
||||||
|
|
||||||
//Util
|
//Util
|
||||||
shadow("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesver")
|
shadow("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_ver")
|
||||||
|
|
||||||
//Logging
|
//Logging
|
||||||
shadow("org.slf4j:slf4j-api:2.0.3")
|
shadow("org.slf4j:slf4j-api:$slf4j_ver")
|
||||||
shadow("org.slf4j:slf4j-simple:2.0.3")
|
shadow("org.slf4j:slf4j-simple:$slf4j_ver")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,9 +104,9 @@ val templateDest = project.buildDir.resolve("generated/templates")
|
||||||
val templateProps = mapOf(
|
val templateProps = mapOf(
|
||||||
"version" to project.version as String,
|
"version" to project.version as String,
|
||||||
"ownerID" to ownerID,
|
"ownerID" to ownerID,
|
||||||
"kordversion" to kordver,
|
"kordversion" to kordext_ver,
|
||||||
"lavaversion" to lavaver,
|
"lavaversion" to lavakord_ver,
|
||||||
"coroutinesversion" to coroutinesver
|
"coroutinesversion" to coroutines_ver
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,5 +15,4 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
#
|
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
6
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -15,9 +15,11 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
#
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
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
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
42
gradlew
vendored
42
gradlew
vendored
|
@ -17,7 +17,6 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
#
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
|
@ -58,7 +57,7 @@
|
||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (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.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
@ -83,13 +82,11 @@ do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
@ -136,22 +133,29 @@ location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD=java
|
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
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
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 ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
'' | soft) :;; #(
|
'' | 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" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
|
@ -196,11 +200,15 @@ if "$cygwin" || "$msys" ; then
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Collect all arguments for the java command;
|
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
# double quotes to make sure that they get re-expanded; and
|
|
||||||
# * put everything else in single quotes, so that it's not re-expanded.
|
# 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 -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
@ -208,6 +216,12 @@ set -- \
|
||||||
org.gradle.wrapper.GradleWrapperMain \
|
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.
|
# Use "xargs" to parse quoted args.
|
||||||
#
|
#
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
|
15
gradlew.bat
vendored
15
gradlew.bat
vendored
|
@ -14,7 +14,7 @@
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
|
@ -25,7 +25,8 @@
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if "%ERRORLEVEL%" == "0" goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
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
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
exit /b 1
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
/*
|
/*
|
||||||
* Botendo
|
* Botendo
|
||||||
* Copyright (C) 2023 limited_dev
|
* Copyright (C) 2023 moonleay
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rootProject.name = "Botendo"
|
rootProject.name = "Botendo"
|
||||||
|
|
|
@ -14,20 +14,28 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo
|
package net.moonleay.botendo
|
||||||
|
|
||||||
import com.kotlindiscord.kord.extensions.ExtensibleBot
|
import com.kotlindiscord.kord.extensions.ExtensibleBot
|
||||||
import dev.kord.common.Color
|
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.behavior.interaction.response.respond
|
||||||
|
import dev.kord.core.entity.channel.VoiceChannel
|
||||||
import dev.kord.core.event.interaction.ButtonInteractionCreateEvent
|
import dev.kord.core.event.interaction.ButtonInteractionCreateEvent
|
||||||
|
import dev.kord.core.event.user.VoiceStateUpdateEvent
|
||||||
import dev.kord.core.on
|
import dev.kord.core.on
|
||||||
|
import dev.kord.rest.builder.message.embed
|
||||||
import dev.schlaubi.lavakord.LavaKord
|
import dev.schlaubi.lavakord.LavaKord
|
||||||
|
import dev.schlaubi.lavakord.audio.Link
|
||||||
|
import dev.schlaubi.lavakord.kord.getLink
|
||||||
import dev.schlaubi.lavakord.kord.lavakord
|
import dev.schlaubi.lavakord.kord.lavakord
|
||||||
|
import kotlinx.coroutines.flow.count
|
||||||
import net.moonleay.botendo.data.CredentialManager
|
import net.moonleay.botendo.data.CredentialManager
|
||||||
import net.moonleay.botendo.extensions.music.*
|
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.extensions.util.InfoExtension
|
||||||
import net.moonleay.botendo.util.Logger
|
import net.moonleay.botendo.util.Logger
|
||||||
import net.moonleay.botendo.util.MessageUtil
|
import net.moonleay.botendo.util.MessageUtil
|
||||||
|
@ -63,10 +71,11 @@ object Bot {
|
||||||
add(::NowPlayingExtension)
|
add(::NowPlayingExtension)
|
||||||
add(::QueueExtension)
|
add(::QueueExtension)
|
||||||
add(::UpsertExtension)
|
add(::UpsertExtension)
|
||||||
|
add(::SeekExtension)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.presence {
|
this.presence {
|
||||||
this.streaming("music", "https://twitch.tv/limited_dev")
|
this.streaming("music", "https://twitch.tv/moonleaytv")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,18 +97,47 @@ object Bot {
|
||||||
b.onInteraction(response, g, u)
|
b.onInteraction(response, g, u)
|
||||||
return@on
|
return@on
|
||||||
}
|
}
|
||||||
|
// Button not found
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "Error"
|
||||||
"Error",
|
this.description = "Could not find button with id \"${inter.componentId}\".\nPlease report this."
|
||||||
"Could not find button with id \"${inter.componentId}\".\nPlease report this.",
|
this.footer {
|
||||||
u.asUser().username + "#" + u.asUser().discriminator
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow the bot to leave the VC if there are no users in the VC
|
||||||
|
bot.kordRef.on<VoiceStateUpdateEvent> {
|
||||||
|
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<VoiceChannel>(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
|
//Start the bot
|
||||||
bot.start()
|
bot.start()
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,15 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo
|
package net.moonleay.botendo
|
||||||
|
|
||||||
|
import net.moonleay.botendo.util.Logger
|
||||||
|
|
||||||
|
|
||||||
///Show the splash and launch the Bot
|
///Show the splash and launch the Bot
|
||||||
suspend fun main() {
|
suspend fun main(args: Array<String>) {
|
||||||
println(
|
println(
|
||||||
"M#\"\"\"\"\"\"\"'M dP dP \n" +
|
"M#\"\"\"\"\"\"\"'M dP dP \n" +
|
||||||
"## mmmm. `M 88 88 \n" +
|
"## mmmm. `M 88 88 \n" +
|
||||||
|
@ -33,5 +34,9 @@ suspend fun main() {
|
||||||
" "
|
" "
|
||||||
)
|
)
|
||||||
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}")
|
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()
|
Bot.start()
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.buttons
|
package net.moonleay.botendo.buttons
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.buttons
|
package net.moonleay.botendo.buttons
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.buttons.music
|
package net.moonleay.botendo.buttons.music
|
||||||
|
@ -24,7 +23,9 @@ import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteract
|
||||||
import dev.kord.core.behavior.interaction.response.respond
|
import dev.kord.core.behavior.interaction.response.respond
|
||||||
import dev.kord.core.entity.Guild
|
import dev.kord.core.entity.Guild
|
||||||
import dev.kord.core.entity.User
|
import dev.kord.core.entity.User
|
||||||
import dev.kord.rest.builder.message.modify.actionRow
|
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.audio.Link
|
||||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||||
import net.moonleay.botendo.util.ButtonUtil
|
import net.moonleay.botendo.util.ButtonUtil
|
||||||
|
@ -42,14 +43,14 @@ class PauseButton : net.moonleay.botendo.buttons.Button("btn.music.pause") {
|
||||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||||
if (voiceState == null) {
|
if (voiceState == null) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not connected to a VC"
|
||||||
"You are not connected to a VC",
|
this.description = "Please connect to a VC"
|
||||||
"Please connect to a VC",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -57,26 +58,26 @@ class PauseButton : net.moonleay.botendo.buttons.Button("btn.music.pause") {
|
||||||
val channelId = voiceState.channelId
|
val channelId = voiceState.channelId
|
||||||
if (link.state == Link.State.NOT_CONNECTED) {
|
if (link.state == Link.State.NOT_CONNECTED) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "Not connected"
|
||||||
"Not connected",
|
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||||
"I'm not in a VC and therefore, I am not playing anything.",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not in my VC"
|
||||||
"You are not in my VC",
|
this.description = "We are not in the same VC and therefore, you cannot control the music"
|
||||||
"We are not in the same VC and therefore, you cannot control the music",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -85,19 +86,18 @@ class PauseButton : net.moonleay.botendo.buttons.Button("btn.music.pause") {
|
||||||
|
|
||||||
val gts = MusicManager.getGuildTrackScheduler(guild, player)
|
val gts = MusicManager.getGuildTrackScheduler(guild, player)
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = if (player.paused) "I paused" else "I'm continuing"
|
||||||
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."
|
||||||
if (player.paused) "I paused the song" else "I'm continuing to play the song.",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
this.actionRow {
|
|
||||||
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.actionRow(fun ActionRowBuilder.() {
|
||||||
|
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.buttons.music
|
package net.moonleay.botendo.buttons.music
|
||||||
|
@ -24,7 +23,9 @@ import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteract
|
||||||
import dev.kord.core.behavior.interaction.response.respond
|
import dev.kord.core.behavior.interaction.response.respond
|
||||||
import dev.kord.core.entity.Guild
|
import dev.kord.core.entity.Guild
|
||||||
import dev.kord.core.entity.User
|
import dev.kord.core.entity.User
|
||||||
import dev.kord.rest.builder.message.modify.actionRow
|
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.audio.Link
|
||||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||||
import net.moonleay.botendo.util.ButtonUtil
|
import net.moonleay.botendo.util.ButtonUtil
|
||||||
|
@ -42,53 +43,54 @@ class QueueButton : net.moonleay.botendo.buttons.Button("btn.music.queue") {
|
||||||
val player = link.player
|
val player = link.player
|
||||||
if (link.state == Link.State.NOT_CONNECTED) {
|
if (link.state == Link.State.NOT_CONNECTED) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "Not connected"
|
||||||
"Not connected",
|
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||||
"I'm not in a VC and therefore, I am not playing anything.",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val track = player.playingTrack
|
if (player.playingTrack == null) {
|
||||||
if (track == null) {
|
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "Not playing"
|
||||||
"Not playing",
|
this.description = "I'm not playing anything currently"
|
||||||
"I'm not playing anything currently", user.asUser().username + "#" + user.asUser().discriminator
|
this.footer {
|
||||||
)
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
val track = player.playingTrack!!.info
|
||||||
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
|
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
|
||||||
val q = gts.getQueue()
|
val q = gts.getQueue()
|
||||||
var desc =
|
var desc =
|
||||||
"""${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length.inWholeMilliseconds)} (${track.author})**""" + "\n"
|
"""${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length)} (${track.author})**""" + "\n"
|
||||||
for ((i, tr) in q.withIndex()) {
|
for ((i, tr) in q.withIndex()) {
|
||||||
if (i >= 14)
|
if (i >= 14)
|
||||||
continue
|
continue
|
||||||
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
|
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
|
||||||
}
|
}
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = "Queue"
|
||||||
"Queue",
|
this.description = desc
|
||||||
desc,
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
|
||||||
|
|
||||||
this.actionRow {
|
|
||||||
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.actionRow(fun ActionRowBuilder.() {
|
||||||
|
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.buttons.music
|
package net.moonleay.botendo.buttons.music
|
||||||
|
@ -24,7 +23,9 @@ import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteract
|
||||||
import dev.kord.core.behavior.interaction.response.respond
|
import dev.kord.core.behavior.interaction.response.respond
|
||||||
import dev.kord.core.entity.Guild
|
import dev.kord.core.entity.Guild
|
||||||
import dev.kord.core.entity.User
|
import dev.kord.core.entity.User
|
||||||
import dev.kord.rest.builder.message.modify.actionRow
|
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.audio.Link
|
||||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||||
import net.moonleay.botendo.util.ButtonUtil
|
import net.moonleay.botendo.util.ButtonUtil
|
||||||
|
@ -42,14 +43,14 @@ class RepeatButton : net.moonleay.botendo.buttons.Button("btn.music.repeat") {
|
||||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||||
if (voiceState == null) {
|
if (voiceState == null) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not connected to a VC"
|
||||||
"You are not connected to a VC",
|
this.description = "Please connect to a VC"
|
||||||
"Please connect to a VC",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -57,26 +58,26 @@ class RepeatButton : net.moonleay.botendo.buttons.Button("btn.music.repeat") {
|
||||||
val channelId = voiceState.channelId
|
val channelId = voiceState.channelId
|
||||||
if (link.state == Link.State.NOT_CONNECTED) {
|
if (link.state == Link.State.NOT_CONNECTED) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "Not connected"
|
||||||
"Not connected",
|
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||||
"I'm not in a VC and therefore, I am not playing anything.",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not in my VC"
|
||||||
"You are not in my VC",
|
this.description = "We are not in the same VC and therefore, you cannot control the music"
|
||||||
"We are not in the same VC and therefore, you cannot control the music",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -84,19 +85,19 @@ class RepeatButton : net.moonleay.botendo.buttons.Button("btn.music.repeat") {
|
||||||
val gts = MusicManager.getGuildTrackScheduler(guild, player)
|
val gts = MusicManager.getGuildTrackScheduler(guild, player)
|
||||||
gts.repeating = !gts.repeating
|
gts.repeating = !gts.repeating
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = if (gts.repeating) "Now Repeating" else "Now Continuing"
|
||||||
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",
|
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.footer {
|
||||||
)
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
|
|
||||||
|
|
||||||
this.actionRow {
|
|
||||||
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.actionRow(fun ActionRowBuilder.() {
|
||||||
|
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.buttons.music
|
package net.moonleay.botendo.buttons.music
|
||||||
|
@ -25,7 +24,9 @@ import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteract
|
||||||
import dev.kord.core.behavior.interaction.response.respond
|
import dev.kord.core.behavior.interaction.response.respond
|
||||||
import dev.kord.core.entity.Guild
|
import dev.kord.core.entity.Guild
|
||||||
import dev.kord.core.entity.User
|
import dev.kord.core.entity.User
|
||||||
import dev.kord.rest.builder.message.modify.actionRow
|
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.audio.Link
|
||||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||||
import net.moonleay.botendo.util.ButtonUtil
|
import net.moonleay.botendo.util.ButtonUtil
|
||||||
|
@ -45,14 +46,14 @@ class SkipButton : net.moonleay.botendo.buttons.Button("btn.music.skip") {
|
||||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||||
if (voiceState == null) {
|
if (voiceState == null) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not connected to a VC"
|
||||||
"You are not connected to a VC",
|
this.description = "Please connect to a VC"
|
||||||
"Please connect to a VC",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -60,61 +61,64 @@ class SkipButton : net.moonleay.botendo.buttons.Button("btn.music.skip") {
|
||||||
val channelId = voiceState.channelId
|
val channelId = voiceState.channelId
|
||||||
if (link.state == Link.State.NOT_CONNECTED) {
|
if (link.state == Link.State.NOT_CONNECTED) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "Not connected"
|
||||||
"Not connected",
|
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||||
"I'm not in a VC and therefore, I am not playing anything.",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not in my VC"
|
||||||
"You are not in my VC",
|
this.description = "We are not in the same VC and therefore, you cannot control the music"
|
||||||
"We are not in the same VC and therefore, you cannot control the music",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var track = player.playingTrack
|
if (player.playingTrack == null) {
|
||||||
if (track == null) {
|
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "Not Playing"
|
||||||
"Not playing",
|
this.description = "I'm not playing anything currently"
|
||||||
"I'm not playing anything currently", user.asUser().username + "#" + user.asUser().discriminator
|
this.footer {
|
||||||
)
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var track = player.playingTrack!!.info
|
||||||
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
|
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
|
||||||
if (!gts.isEmpty()) {
|
if (!gts.isEmpty()) {
|
||||||
track = gts.getHead().toTrack()
|
track = gts.getHead().info
|
||||||
gts.playNext(link)
|
gts.playNext(link)
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbedWithImage(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = "Skipped song; now playing"
|
||||||
"Skipped song; now playing",
|
this.description = "**${track.title}**\n*Now Playing*\nby ${track.author} :: ${
|
||||||
"**${track.title}**\n*Now Playing*\nby ${track.author} :: ${
|
TimeUtil.getTimeFormatedRaw(
|
||||||
TimeUtil.getTimeFormatedRaw(
|
track.length
|
||||||
track.length.inWholeMilliseconds
|
)
|
||||||
)
|
}\n" +
|
||||||
}\n" +
|
">>>${track.uri}"
|
||||||
">>>${track.uri}",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator,
|
this.text = MessageUtil.getFooter(user)
|
||||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
|
}
|
||||||
)
|
this.thumbnail {
|
||||||
)
|
this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.actionRow {
|
this.actionRow {
|
||||||
this.components.addAll(
|
this.components.addAll(
|
||||||
|
@ -130,17 +134,17 @@ class SkipButton : net.moonleay.botendo.buttons.Button("btn.music.skip") {
|
||||||
player.stopTrack()
|
player.stopTrack()
|
||||||
|
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = "Skipped song"
|
||||||
"Skipped song; now playing",
|
this.description = "Nothing"
|
||||||
"Nothing",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
|
||||||
this.actionRow {
|
|
||||||
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
|
||||||
}
|
}
|
||||||
|
this.actionRow(fun ActionRowBuilder.() {
|
||||||
|
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.buttons.music
|
package net.moonleay.botendo.buttons.music
|
||||||
|
@ -24,6 +23,7 @@ import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteract
|
||||||
import dev.kord.core.behavior.interaction.response.respond
|
import dev.kord.core.behavior.interaction.response.respond
|
||||||
import dev.kord.core.entity.Guild
|
import dev.kord.core.entity.Guild
|
||||||
import dev.kord.core.entity.User
|
import dev.kord.core.entity.User
|
||||||
|
import dev.kord.rest.builder.message.embed
|
||||||
import dev.schlaubi.lavakord.audio.Link
|
import dev.schlaubi.lavakord.audio.Link
|
||||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||||
import net.moonleay.botendo.util.MessageUtil
|
import net.moonleay.botendo.util.MessageUtil
|
||||||
|
@ -40,14 +40,14 @@ class StopButton : net.moonleay.botendo.buttons.Button("btn.music.stop") {
|
||||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||||
if (voiceState == null) {
|
if (voiceState == null) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not connected to a VC"
|
||||||
"You are not connected to a VC",
|
this.description = "Please connect to a VC"
|
||||||
"Please connect to a VC",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -55,26 +55,26 @@ class StopButton : net.moonleay.botendo.buttons.Button("btn.music.stop") {
|
||||||
val channelId = voiceState.channelId
|
val channelId = voiceState.channelId
|
||||||
if (link.state == Link.State.NOT_CONNECTED) {
|
if (link.state == Link.State.NOT_CONNECTED) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "Not connected"
|
||||||
"Not connected",
|
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||||
"I'm not in a VC and therefore, I am not playing anything.",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not in my VC"
|
||||||
"You are not in my VC",
|
this.description = "We are not in the same VC and therefore, you cannot control the music"
|
||||||
"We are not in the same VC and therefore, you cannot control the music",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -83,14 +83,14 @@ class StopButton : net.moonleay.botendo.buttons.Button("btn.music.stop") {
|
||||||
link.destroy()
|
link.destroy()
|
||||||
MusicManager.getGuildTrackScheduler(guild.asGuild(), player).clear()
|
MusicManager.getGuildTrackScheduler(guild.asGuild(), player).clear()
|
||||||
response.respond {
|
response.respond {
|
||||||
this.embeds = mutableListOf(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = "I stopped and left"
|
||||||
"I stopped and left",
|
this.description = "just like your girlfriend"
|
||||||
"just like your girlfriend",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(user)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.data
|
package net.moonleay.botendo.data
|
||||||
|
|
|
@ -14,16 +14,16 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.extensions.music
|
package net.moonleay.botendo.extensions.music
|
||||||
|
|
||||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||||
import com.kotlindiscord.kord.extensions.types.respond
|
|
||||||
import dev.kord.common.Color
|
import dev.kord.common.Color
|
||||||
import dev.kord.rest.builder.message.create.actionRow
|
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.audio.Link
|
||||||
import dev.schlaubi.lavakord.kord.getLink
|
import dev.schlaubi.lavakord.kord.getLink
|
||||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||||
|
@ -42,55 +42,68 @@ class NowPlayingExtension : Extension() {
|
||||||
val guildId = this.guild!!.id
|
val guildId = this.guild!!.id
|
||||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
|
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
|
||||||
val player = link.player
|
val player = link.player
|
||||||
|
val u = this.user
|
||||||
if (link.state == Link.State.NOT_CONNECTED) {
|
if (link.state == Link.State.NOT_CONNECTED) {
|
||||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
this.respond {
|
||||||
this,
|
this.embed {
|
||||||
Color(0xE0A81A),
|
this.color = Color(0xE0311A)
|
||||||
"Not connected",
|
this.title = "Not connected"
|
||||||
"I'm not in a VC and therefore, I am not playing anything."
|
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||||
)
|
this.footer {
|
||||||
|
this.text = MessageUtil.getFooter(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
val track = player.playingTrack
|
val track = player.playingTrack
|
||||||
if (track == null) {
|
if (track == null) {
|
||||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
this.respond {
|
||||||
this,
|
this.embed {
|
||||||
Color(0xE0A81A),
|
this.color = Color(0xE0311A)
|
||||||
"Not Playing",
|
this.title = "Not Playing"
|
||||||
"I'm not playing anything currently"
|
this.description = "I'm not playing anything currently"
|
||||||
)
|
this.footer {
|
||||||
|
this.text = MessageUtil.getFooter(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||||
|
|
||||||
this.respond {
|
this.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbedWithImage(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = "Currently playing"
|
||||||
"Currently playing",
|
this.description = "**${track.info.title}**\n*Now Playing*\nby ${track.info.author} ; ${
|
||||||
"**${track.title}**\n*Now Playing*\nby ${track.author} ; ${
|
TimeUtil.getTimeFormatedRaw(
|
||||||
TimeUtil.getTimeFormatedRaw(
|
player.position
|
||||||
player.position
|
)
|
||||||
)
|
}: ${
|
||||||
}: ${
|
TimeUtil.getTimeFormatedRaw(
|
||||||
TimeUtil.getTimeFormatedRaw(
|
track.info.length
|
||||||
track.length.inWholeMilliseconds
|
)
|
||||||
)
|
}\n" +
|
||||||
}\n" +
|
">>>${track.info.uri}"
|
||||||
">>>${track.uri}",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator,
|
this.text = MessageUtil.getFooter(u)
|
||||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri.toString()) + "/maxresdefault.jpg"
|
}
|
||||||
)
|
if(track.info.uri == null){
|
||||||
)
|
this.thumbnail {
|
||||||
|
this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.info.uri!!) + "/maxresdefault.jpg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.actionRow {
|
this.actionRow(fun ActionRowBuilder.() {
|
||||||
this.components.addAll(
|
components.addAll(
|
||||||
ButtonUtil.getMusicControllerButtons(
|
ButtonUtil.getMusicControllerButtons(
|
||||||
player.paused,
|
player.paused,
|
||||||
gts.repeating
|
gts.repeating
|
||||||
).components
|
).components
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,20 +14,21 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.extensions.music
|
package net.moonleay.botendo.extensions.music
|
||||||
|
|
||||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||||
import com.kotlindiscord.kord.extensions.types.respond
|
|
||||||
import dev.kord.common.Color
|
import dev.kord.common.Color
|
||||||
|
import dev.kord.rest.builder.message.embed
|
||||||
import dev.schlaubi.lavakord.audio.Link
|
import dev.schlaubi.lavakord.audio.Link
|
||||||
import dev.schlaubi.lavakord.kord.getLink
|
import dev.schlaubi.lavakord.kord.getLink
|
||||||
|
import net.moonleay.botendo.Bot
|
||||||
import net.moonleay.botendo.extensions.music.components.LinkArguments
|
import net.moonleay.botendo.extensions.music.components.LinkArguments
|
||||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||||
import net.moonleay.botendo.util.MessageUtil
|
import net.moonleay.botendo.util.MessageUtil
|
||||||
|
import net.moonleay.botendo.util.UserUtil
|
||||||
|
|
||||||
|
|
||||||
class PlayExtension : Extension() {
|
class PlayExtension : Extension() {
|
||||||
|
@ -40,19 +41,19 @@ class PlayExtension : Extension() {
|
||||||
description = "Play music"
|
description = "Play music"
|
||||||
this.action {
|
this.action {
|
||||||
val guildId = this.guild!!.id
|
val guildId = this.guild!!.id
|
||||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
|
val link = Bot.lava.getLink(guildId)
|
||||||
val u = this.user
|
val u = this.user
|
||||||
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
||||||
if (vcsUser == null) {
|
if (vcsUser == null) {
|
||||||
this.respond {
|
this.respond {
|
||||||
embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not connected to a VC"
|
||||||
"You are not connected to a VC",
|
this.description = "Please connect to a VC"
|
||||||
"Please connect to a VC",
|
this.footer {
|
||||||
u.asUser().username + "#" + u.asUser().discriminator
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
|
@ -63,14 +64,14 @@ class PlayExtension : Extension() {
|
||||||
link.connectAudio(channelId!!.value)
|
link.connectAudio(channelId!!.value)
|
||||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||||
this.respond {
|
this.respond {
|
||||||
embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not in my VC"
|
||||||
"You are not in my VC",
|
this.description = "We are not in the same VC and therefore, you cannot play any music"
|
||||||
"We are not in the same VC and therefore, you cannot play any music",
|
this.author {
|
||||||
u.asUser().username + "#" + u.asUser().discriminator
|
this.name = UserUtil.getCommandSrc(u)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
|
@ -82,14 +83,14 @@ class PlayExtension : Extension() {
|
||||||
"ytsearch:$query"
|
"ytsearch:$query"
|
||||||
}
|
}
|
||||||
this.respond {
|
this.respond {
|
||||||
embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0A81A)
|
||||||
Color(0xE0A81A),
|
this.title = "Searching..."
|
||||||
"Searching...",
|
this.description = "We are looking for $query"
|
||||||
"We are looking for $query",
|
this.footer {
|
||||||
u.asUser().username + "#" + u.asUser().discriminator
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
MusicManager.addToQueue(this, link, search)
|
MusicManager.addToQueue(this, link, search)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,16 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.extensions.music
|
package net.moonleay.botendo.extensions.music
|
||||||
|
|
||||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||||
import com.kotlindiscord.kord.extensions.types.respond
|
|
||||||
import dev.kord.common.Color
|
import dev.kord.common.Color
|
||||||
import dev.kord.rest.builder.message.create.actionRow
|
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.audio.Link
|
||||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||||
import net.moonleay.botendo.util.ButtonUtil
|
import net.moonleay.botendo.util.ButtonUtil
|
||||||
|
@ -40,52 +40,61 @@ class QueueExtension : Extension() {
|
||||||
val guildId = this.guild!!.id
|
val guildId = this.guild!!.id
|
||||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
|
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
|
||||||
val player = link.player
|
val player = link.player
|
||||||
|
val u = this.user
|
||||||
if (link.state == Link.State.NOT_CONNECTED) {
|
if (link.state == Link.State.NOT_CONNECTED) {
|
||||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
this.respond {
|
||||||
this,
|
this.embed {
|
||||||
Color(0xE0311A),
|
this.color = Color(0xE0311A)
|
||||||
"Not connected",
|
this.title = "Not connected"
|
||||||
"I'm not in a VC and therefore, I am not playing anything."
|
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||||
)
|
this.footer {
|
||||||
|
this.text = MessageUtil.getFooter(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
val track = player.playingTrack
|
val track = player.playingTrack
|
||||||
if (track == null) {
|
if (track == null) {
|
||||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
this.respond {
|
||||||
this,
|
this.embed {
|
||||||
Color(0xE0A81A),
|
this.color = Color(0xE0311A)
|
||||||
"Queue empty",
|
this.title = "Queue empty"
|
||||||
"I'm not playing anything currently"
|
this.description = "I'm not playing anything currently"
|
||||||
)
|
this.footer {
|
||||||
|
this.text = MessageUtil.getFooter(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||||
val q = gts.getQueue()
|
val q = gts.getQueue()
|
||||||
var desc =
|
var desc =
|
||||||
"""${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length.inWholeMilliseconds)} (${track.author})**""" + "\n"
|
"""${"**" + track.info.title + " - " + TimeUtil.getTimeFormatedShortend(track.info.length)} (${track.info.author})**""" + "\n"
|
||||||
for ((i, tr) in q.withIndex()) {
|
for ((i, tr) in q.withIndex()) {
|
||||||
if (i >= 14)
|
if (i >= 14)
|
||||||
continue
|
continue
|
||||||
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
|
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
|
||||||
}
|
}
|
||||||
this.respond {
|
this.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = "Queue"
|
||||||
"Queue",
|
this.description = desc
|
||||||
desc,
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
this.actionRow {
|
this.actionRow(fun ActionRowBuilder.() {
|
||||||
this.components.addAll(
|
components.addAll(
|
||||||
ButtonUtil.getMusicControllerButtons(
|
ButtonUtil.getMusicControllerButtons(
|
||||||
player.paused,
|
player.paused,
|
||||||
gts.repeating
|
gts.repeating
|
||||||
).components
|
).components
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.botendo.extensions.music
|
||||||
|
|
||||||
|
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||||
|
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||||
|
import 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
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,16 +14,16 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.extensions.music
|
package net.moonleay.botendo.extensions.music
|
||||||
|
|
||||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||||
import com.kotlindiscord.kord.extensions.types.respond
|
|
||||||
import dev.kord.common.Color
|
import dev.kord.common.Color
|
||||||
import dev.kord.rest.builder.message.create.actionRow
|
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.audio.Link
|
||||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||||
import net.moonleay.botendo.util.ButtonUtil
|
import net.moonleay.botendo.util.ButtonUtil
|
||||||
|
@ -44,46 +44,62 @@ class SkipExtension : Extension() {
|
||||||
val u = this.user
|
val u = this.user
|
||||||
val voiceState = u.asMember(guildId).getVoiceStateOrNull()
|
val voiceState = u.asMember(guildId).getVoiceStateOrNull()
|
||||||
if (voiceState == null) {
|
if (voiceState == null) {
|
||||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
this.respond {
|
||||||
this,
|
this.embed {
|
||||||
Color(0xE0311A),
|
this.color = Color(0xE0311A)
|
||||||
"You are not connected to a VC",
|
this.title = "You are not connected to a VC"
|
||||||
"Please connect to a VC"
|
this.description = "Please connect to a VC"
|
||||||
)
|
this.footer {
|
||||||
|
this.text = MessageUtil.getFooter(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
|
|
||||||
val channelId = voiceState.channelId
|
val channelId = voiceState.channelId
|
||||||
if (link.state == Link.State.NOT_CONNECTED) {
|
if (link.state == Link.State.NOT_CONNECTED) {
|
||||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
this.respond {
|
||||||
this,
|
this.embed {
|
||||||
Color(0xE0311A),
|
this.color = Color(0xE0311A)
|
||||||
"Not connected",
|
this.title = "Not connected"
|
||||||
"I'm not in a VC and therefore, I am not playing anything."
|
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||||
)
|
this.footer {
|
||||||
|
this.text = MessageUtil.getFooter(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return@action
|
return@action
|
||||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
this.respond {
|
||||||
this,
|
this.embed {
|
||||||
Color(0xE0311A),
|
this.color = Color(0xE0311A)
|
||||||
"You are not in my VC",
|
this.title = "You are not in my VC"
|
||||||
"We are not in the same VC and therefore, you cannot control the music"
|
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
|
return@action
|
||||||
}
|
}
|
||||||
var track = player.playingTrack
|
var track = player.playingTrack!!.info
|
||||||
if (track == null) {
|
if (track == null) {
|
||||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
this.respond {
|
||||||
this,
|
this.embed {
|
||||||
Color(0xE0311A),
|
this.color = Color(0xE0311A)
|
||||||
"Not playing",
|
this.title = "Not playing"
|
||||||
"I'm not playing anything currently"
|
this.description = "I'm not playing anything currently"
|
||||||
)
|
this.footer {
|
||||||
|
this.text = MessageUtil.getFooter(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||||
if (!gts.isEmpty()) {
|
if (!gts.isEmpty()) {
|
||||||
track = gts.getHead().toTrack()
|
track = gts.getHead().info
|
||||||
gts.playNext(link)
|
gts.playNext(link)
|
||||||
} else {
|
} else {
|
||||||
player.stopTrack()
|
player.stopTrack()
|
||||||
|
@ -91,29 +107,31 @@ class SkipExtension : Extension() {
|
||||||
|
|
||||||
|
|
||||||
this.respond {
|
this.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbedWithImage(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = "Skipped song; now playing"
|
||||||
"Skipped song; now playing",
|
this.description = "**${track.title}**\n*Now Playing*\nby ${track.author} ;: ${
|
||||||
"**${track.title}**\n*Now Playing*\nby ${track.author} :: ${
|
TimeUtil.getTimeFormatedRaw(
|
||||||
TimeUtil.getTimeFormatedRaw(
|
track.length
|
||||||
track.length.inWholeMilliseconds
|
)
|
||||||
)
|
}\n" +
|
||||||
}\n" +
|
">>>${track.uri}"
|
||||||
">>>${track.uri}",
|
this.footer {
|
||||||
user.asUser().username + "#" + user.asUser().discriminator,
|
this.text = MessageUtil.getFooter(u)
|
||||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
|
}
|
||||||
)
|
this.thumbnail {
|
||||||
)
|
this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.actionRow {
|
this.actionRow(fun ActionRowBuilder.() {
|
||||||
this.components.addAll(
|
components.addAll(
|
||||||
ButtonUtil.getMusicControllerButtons(
|
ButtonUtil.getMusicControllerButtons(
|
||||||
player.paused,
|
player.paused,
|
||||||
gts.repeating
|
gts.repeating
|
||||||
).components
|
).components
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,15 +14,14 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.extensions.music
|
package net.moonleay.botendo.extensions.music
|
||||||
|
|
||||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||||
import com.kotlindiscord.kord.extensions.types.respond
|
|
||||||
import dev.kord.common.Color
|
import dev.kord.common.Color
|
||||||
|
import dev.kord.rest.builder.message.embed
|
||||||
import dev.schlaubi.lavakord.audio.Link
|
import dev.schlaubi.lavakord.audio.Link
|
||||||
import dev.schlaubi.lavakord.kord.getLink
|
import dev.schlaubi.lavakord.kord.getLink
|
||||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||||
|
@ -42,38 +41,40 @@ class StopExtension : Extension() {
|
||||||
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
||||||
if (vcsUser == null) {
|
if (vcsUser == null) {
|
||||||
this.respond {
|
this.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not connected to a VC"
|
||||||
"You are not connected to a VC",
|
this.description = "Please connect to a VC"
|
||||||
"Please connect to my VC", u.asUser().username + "#" + u.asUser().discriminator
|
this.footer {
|
||||||
)
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
val channelId = vcsUser.channelId
|
val channelId = vcsUser.channelId
|
||||||
if (link.state == Link.State.NOT_CONNECTED) {
|
if (link.state == Link.State.NOT_CONNECTED) {
|
||||||
this.respond {
|
this.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "Not connected"
|
||||||
"Not connected",
|
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||||
"I'm not in a VC and therefore, I am not playing anything.",
|
this.footer {
|
||||||
u.asUser().username + "#" + u.asUser().discriminator
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return@action
|
return@action
|
||||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||||
this.respond {
|
this.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not in my VC"
|
||||||
"You are not in my VC",
|
this.description = "We are not in the same VC"
|
||||||
"We are not in the same VC", u.asUser().username + "#" + u.asUser().discriminator
|
this.footer {
|
||||||
)
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
|
@ -81,14 +82,14 @@ class StopExtension : Extension() {
|
||||||
link.destroy()
|
link.destroy()
|
||||||
MusicManager.getGuildTrackScheduler(this.getGuild()!!.asGuild(), player).clear()
|
MusicManager.getGuildTrackScheduler(this.getGuild()!!.asGuild(), player).clear()
|
||||||
this.respond {
|
this.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = "I stopped and left"
|
||||||
"I stopped and left",
|
this.description = "just like your girlfriend"
|
||||||
"just like your girlfriend",
|
this.footer {
|
||||||
u.asUser().username + "#" + u.asUser().discriminator
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,15 +14,14 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.extensions.music
|
package net.moonleay.botendo.extensions.music
|
||||||
|
|
||||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||||
import com.kotlindiscord.kord.extensions.types.respond
|
|
||||||
import dev.kord.common.Color
|
import dev.kord.common.Color
|
||||||
|
import dev.kord.rest.builder.message.embed
|
||||||
import dev.schlaubi.lavakord.audio.Link
|
import dev.schlaubi.lavakord.audio.Link
|
||||||
import dev.schlaubi.lavakord.kord.getLink
|
import dev.schlaubi.lavakord.kord.getLink
|
||||||
import net.moonleay.botendo.extensions.music.components.LinkArguments
|
import net.moonleay.botendo.extensions.music.components.LinkArguments
|
||||||
|
@ -45,14 +44,14 @@ class UpsertExtension : Extension() {
|
||||||
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
||||||
if (vcsUser == null) {
|
if (vcsUser == null) {
|
||||||
this.respond {
|
this.respond {
|
||||||
embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not connected to a VC"
|
||||||
"You are not connected to a VC",
|
this.description = "Please connect to a VC"
|
||||||
"Please connect to a VC",
|
this.footer {
|
||||||
u.asUser().username + "#" + u.asUser().discriminator
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
|
@ -63,14 +62,14 @@ class UpsertExtension : Extension() {
|
||||||
link.connectAudio(channelId!!.value)
|
link.connectAudio(channelId!!.value)
|
||||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||||
this.respond {
|
this.respond {
|
||||||
embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "You are not in my VC"
|
||||||
"You are not in my VC",
|
this.description = "We are not in the same VC and therefore, you cannot play any music"
|
||||||
"We are not in the same VC and therefore, you cannot play any music",
|
this.footer {
|
||||||
u.asUser().username + "#" + u.asUser().discriminator
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
return@action
|
return@action
|
||||||
}
|
}
|
||||||
|
@ -82,14 +81,14 @@ class UpsertExtension : Extension() {
|
||||||
"ytsearch:$query"
|
"ytsearch:$query"
|
||||||
}
|
}
|
||||||
this.respond {
|
this.respond {
|
||||||
embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0A81A)
|
||||||
Color(0xE0A81A),
|
this.title = "Searching..."
|
||||||
"Searching...",
|
this.description = "We are looking for $query"
|
||||||
"We are looking for $query",
|
this.footer {
|
||||||
u.asUser().username + "#" + u.asUser().discriminator
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
MusicManager.upsertIntoQueue(this, link, search)
|
MusicManager.upsertIntoQueue(this, link, search)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,26 +14,26 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.extensions.music.components
|
package net.moonleay.botendo.extensions.music.components
|
||||||
|
|
||||||
|
import dev.arbjerg.lavalink.protocol.v4.Track
|
||||||
import dev.schlaubi.lavakord.audio.*
|
import dev.schlaubi.lavakord.audio.*
|
||||||
import dev.schlaubi.lavakord.audio.player.Player
|
import dev.schlaubi.lavakord.audio.player.Player
|
||||||
import dev.schlaubi.lavakord.rest.models.PartialTrack
|
import net.moonleay.botendo.Bot
|
||||||
import net.moonleay.botendo.util.Logger
|
import net.moonleay.botendo.util.Logger
|
||||||
import java.util.concurrent.BlockingQueue
|
import java.util.concurrent.BlockingQueue
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
import java.util.concurrent.LinkedBlockingQueue
|
||||||
|
|
||||||
class GuildTrackScheduler(val pl: Player) {
|
class GuildTrackScheduler(val pl: Player) {
|
||||||
|
|
||||||
private var queue: BlockingQueue<PartialTrack> = LinkedBlockingQueue()
|
private var queue: BlockingQueue<Track> = LinkedBlockingQueue()
|
||||||
var repeating = false
|
var repeating = false
|
||||||
private var hasRegisteredEvents = false
|
private var hasRegisteredEvents = false
|
||||||
|
|
||||||
///Add a track to queue and start playing, if there is no song currently playing
|
///Add a track to queue and start playing, if there is no song currently playing
|
||||||
suspend fun queue(track: PartialTrack, type: MusicManager.AddType) {
|
suspend fun queue(track: Track, type: MusicManager.AddType) {
|
||||||
if (this.pl.playingTrack == null) {
|
if (this.pl.playingTrack == null) {
|
||||||
play(track)
|
play(track)
|
||||||
return
|
return
|
||||||
|
@ -44,7 +44,7 @@ class GuildTrackScheduler(val pl: Player) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MusicManager.AddType.UPSERT -> {
|
MusicManager.AddType.UPSERT -> {
|
||||||
val nq = LinkedBlockingQueue<PartialTrack>()
|
val nq = LinkedBlockingQueue<Track>()
|
||||||
nq.offer(track)
|
nq.offer(track)
|
||||||
for (t in queue.toList()) {
|
for (t in queue.toList()) {
|
||||||
nq.offer(t)
|
nq.offer(t)
|
||||||
|
@ -56,7 +56,7 @@ class GuildTrackScheduler(val pl: Player) {
|
||||||
|
|
||||||
suspend fun playNext(link: Link) {
|
suspend fun playNext(link: Link) {
|
||||||
if (!queue.isEmpty())
|
if (!queue.isEmpty())
|
||||||
this.pl.playTrack(queue.poll())
|
this.pl.playTrack(track = queue.poll())
|
||||||
else {
|
else {
|
||||||
this.pl.stopTrack()
|
this.pl.stopTrack()
|
||||||
link.destroy()
|
link.destroy()
|
||||||
|
@ -64,8 +64,8 @@ class GuildTrackScheduler(val pl: Player) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun play(tr: PartialTrack) {
|
private suspend fun play(track: Track) {
|
||||||
this.pl.playTrack(tr)
|
this.pl.playTrack(track)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addEvents() {
|
fun addEvents() {
|
||||||
|
@ -92,22 +92,22 @@ class GuildTrackScheduler(val pl: Player) {
|
||||||
if (e.reason.mayStartNext) {
|
if (e.reason.mayStartNext) {
|
||||||
if (repeating) {
|
if (repeating) {
|
||||||
Logger.out("Repeating track...")
|
Logger.out("Repeating track...")
|
||||||
this.pl.playTrack(e.getTrack().copy())
|
this.pl.playTrack(e.track.copy())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Logger.out("Track has ended; Playing next...")
|
Logger.out("Track has ended; Playing next...")
|
||||||
playNext(net.moonleay.botendo.Bot.lava.getLink(e.guildId))
|
playNext(Bot.lava.getLink(e.guildId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun onTrackStuck(e: TrackStuckEvent) {
|
private suspend fun onTrackStuck(e: TrackStuckEvent) {
|
||||||
Logger.out("Track is stuck, retrying...")
|
Logger.out("Track is stuck, retrying...")
|
||||||
this.pl.playTrack(e.getTrack().copy())
|
this.pl.playTrack(e.track.copy())
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun onTrackExc(e: TrackExceptionEvent) {
|
private suspend fun onTrackExc(e: TrackExceptionEvent) {
|
||||||
Logger.out("Track had an exception, retrying...")
|
Logger.out("Track had an exception, retrying...")
|
||||||
this.pl.playTrack(e.getTrack().copy())
|
this.pl.playTrack(e.track.copy())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
|
@ -116,11 +116,11 @@ class GuildTrackScheduler(val pl: Player) {
|
||||||
queue.clear()
|
queue.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getQueue(): List<PartialTrack> {
|
fun getQueue(): List<Track> {
|
||||||
return queue.toList()
|
return queue.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getHead(): PartialTrack {
|
fun getHead(): Track {
|
||||||
return queue.first()
|
return queue.first()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.extensions.music.components
|
package net.moonleay.botendo.extensions.music.components
|
||||||
|
|
|
@ -14,22 +14,22 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.extensions.music.components
|
package net.moonleay.botendo.extensions.music.components
|
||||||
|
|
||||||
import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext
|
import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext
|
||||||
import com.kotlindiscord.kord.extensions.components.forms.ModalForm
|
import com.kotlindiscord.kord.extensions.components.forms.ModalForm
|
||||||
import com.kotlindiscord.kord.extensions.types.respond
|
import dev.arbjerg.lavalink.protocol.v4.LoadResult
|
||||||
import dev.kord.common.Color
|
import dev.kord.common.Color
|
||||||
import dev.kord.common.entity.Snowflake
|
import dev.kord.common.entity.Snowflake
|
||||||
import dev.kord.core.entity.Guild
|
import dev.kord.core.entity.Guild
|
||||||
import dev.kord.rest.builder.message.create.actionRow
|
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.audio.Link
|
||||||
import dev.schlaubi.lavakord.audio.player.Player
|
import dev.schlaubi.lavakord.audio.player.Player
|
||||||
import dev.schlaubi.lavakord.rest.loadItem
|
import dev.schlaubi.lavakord.rest.loadItem
|
||||||
import dev.schlaubi.lavakord.rest.models.TrackResponse
|
|
||||||
import net.moonleay.botendo.util.ButtonUtil
|
import net.moonleay.botendo.util.ButtonUtil
|
||||||
import net.moonleay.botendo.util.MessageUtil
|
import net.moonleay.botendo.util.MessageUtil
|
||||||
import net.moonleay.botendo.util.TimeUtil
|
import net.moonleay.botendo.util.TimeUtil
|
||||||
|
@ -38,6 +38,10 @@ import net.moonleay.botendo.util.UrlUtil
|
||||||
object MusicManager {
|
object MusicManager {
|
||||||
private var musicManagerMap: MutableMap<Snowflake, GuildTrackScheduler> = mutableMapOf()
|
private var musicManagerMap: MutableMap<Snowflake, GuildTrackScheduler> = mutableMapOf()
|
||||||
|
|
||||||
|
fun getMusicManager(guild: Guild): GuildTrackScheduler? {
|
||||||
|
return musicManagerMap[guild.id]
|
||||||
|
}
|
||||||
|
|
||||||
fun getGuildTrackScheduler(guild: Guild, player: Player): GuildTrackScheduler {
|
fun getGuildTrackScheduler(guild: Guild, player: Player): GuildTrackScheduler {
|
||||||
return musicManagerMap.computeIfAbsent(guild.id) {
|
return musicManagerMap.computeIfAbsent(guild.id) {
|
||||||
GuildTrackScheduler(player)
|
GuildTrackScheduler(player)
|
||||||
|
@ -69,61 +73,72 @@ object MusicManager {
|
||||||
silent: Boolean
|
silent: Boolean
|
||||||
) {
|
) {
|
||||||
val player = link.player
|
val player = link.player
|
||||||
val item = link.loadItem(search)
|
|
||||||
val gts = getGuildTrackScheduler(ctx.guild!!.asGuild(), player)
|
val gts = getGuildTrackScheduler(ctx.guild!!.asGuild(), player)
|
||||||
val u = ctx.user.asUser()
|
val u = ctx.user.asUser()
|
||||||
|
|
||||||
gts.addEvents()
|
gts.addEvents()
|
||||||
|
|
||||||
when (item.loadType) {
|
when (val itm = link.loadItem(search)) {
|
||||||
TrackResponse.LoadType.TRACK_LOADED -> {
|
is LoadResult.TrackLoaded -> {
|
||||||
gts.queue(item.track, type)
|
gts.queue(itm.data, type)
|
||||||
if (!silent)
|
if (!silent)
|
||||||
ctx.respond {
|
ctx.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbedWithImage(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = "${type.s} track from link"
|
||||||
"${type.s} track from link",
|
this.description = "**${itm.data.info.title}**\n*Queue*\nby ${itm.data.info.author} ;: ${
|
||||||
"**${item.track.info.title}**\n*Queue*\nby ${item.track.info.author} ;: ${
|
TimeUtil.getTimeFormatedRaw(
|
||||||
TimeUtil.getTimeFormatedRaw(
|
itm.data.info.length
|
||||||
item.track.info.length
|
)
|
||||||
)
|
}\n" +
|
||||||
}\n" +
|
">>>${itm.data.info.uri}"
|
||||||
">>>${item.track.info.uri}", u.username + "#" + u.discriminator,
|
this.footer {
|
||||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg"
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
if (itm.data.info.uri != null) {
|
||||||
|
this.thumbnail {
|
||||||
|
this.url =
|
||||||
|
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(itm.data.info.uri!!) + "/maxresdefault.jpg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.actionRow {
|
this.actionRow(fun ActionRowBuilder.() {
|
||||||
this.components.addAll(
|
components.addAll(
|
||||||
ButtonUtil.getMusicControllerButtons(
|
ButtonUtil.getMusicControllerButtons(
|
||||||
player.paused,
|
player.paused,
|
||||||
gts.repeating
|
gts.repeating
|
||||||
).components
|
).components
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is LoadResult.PlaylistLoaded -> {
|
||||||
TrackResponse.LoadType.PLAYLIST_LOADED -> {
|
player.playTrack(track = itm.data.tracks.first())
|
||||||
val l = item.tracks.reversed()
|
val l= itm.data.tracks.toList().reversed()
|
||||||
for (partialTrack in l) {
|
for (partialTrack in l) {
|
||||||
gts.queue(partialTrack, type)
|
gts.queue(partialTrack, type)
|
||||||
}
|
}
|
||||||
if (!silent)
|
if (!silent)
|
||||||
ctx.respond {
|
ctx.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = "${type.s} playlist from link"
|
||||||
"${type.s} playlist from link",
|
this.description = "**${itm.data.tracks.first().info.title}**\n*${itm.data.info.name}*\nby ${itm.data.tracks.first().info.author} ;: ${
|
||||||
"**${item.tracks.first().info.title}**\n*${item.playlistInfo.name}*\nby ${item.tracks.first().info.author} ;: ${
|
TimeUtil.getTimeFormatedRaw(
|
||||||
TimeUtil.getTimeFormatedRaw(
|
itm.data.tracks.first().info.length
|
||||||
item.tracks.first().info.length
|
)
|
||||||
)
|
}\n" +
|
||||||
}\n" +
|
">>>${itm.data.tracks.first().info.uri}"
|
||||||
">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator
|
this.footer {
|
||||||
)
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
|
if (itm.data.tracks.first().info.uri != null) {
|
||||||
|
this.thumbnail {
|
||||||
|
this.url =
|
||||||
|
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(itm.data.tracks.first().info.uri!!) + "/maxresdefault.jpg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.actionRow {
|
this.actionRow {
|
||||||
this.components.addAll(
|
this.components.addAll(
|
||||||
|
@ -134,25 +149,31 @@ object MusicManager {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
TrackResponse.LoadType.SEARCH_RESULT -> {
|
}
|
||||||
gts.queue(item.tracks.first(), type)
|
is LoadResult.SearchResult -> {
|
||||||
|
gts.queue(itm.data.tracks.first(), type)
|
||||||
if (!silent)
|
if (!silent)
|
||||||
ctx.respond {
|
ctx.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbedWithImage(
|
this.color = Color(0x52E01A)
|
||||||
Color(0x52E01A),
|
this.title = "${type.s} track from query"
|
||||||
"${type.s} track from query",
|
this.description = "**${itm.data.tracks.first().info.title}**\n*Queue*\nby ${itm.data.tracks.first().info.author} ;: ${
|
||||||
"**${item.tracks.first().info.title}**\n*Queue*\nby ${item.tracks.first().info.author} ;: ${
|
TimeUtil.getTimeFormatedRaw(
|
||||||
TimeUtil.getTimeFormatedRaw(
|
itm.data.tracks.first().info.length
|
||||||
item.tracks.first().info.length
|
)
|
||||||
)
|
}\n" +
|
||||||
}\n" +
|
">>>${itm.data.tracks.first().info.uri}"
|
||||||
">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator,
|
this.footer {
|
||||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.tracks.first().info.uri) + "/maxresdefault.jpg"
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
if (itm.data.tracks.first().info.uri != null) {
|
||||||
|
this.thumbnail {
|
||||||
|
this.url =
|
||||||
|
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(itm.data.tracks.first().info.uri!!) + "/maxresdefault.jpg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.actionRow {
|
this.actionRow {
|
||||||
this.components.addAll(
|
this.components.addAll(
|
||||||
|
@ -163,39 +184,47 @@ object MusicManager {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
TrackResponse.LoadType.NO_MATCHES -> {
|
}
|
||||||
|
is LoadResult.NoMatches -> {
|
||||||
|
if (gts.isEmpty() && player.playingTrack == null) {
|
||||||
|
player.stopTrack()
|
||||||
|
link.destroy()
|
||||||
|
}
|
||||||
if (!silent)
|
if (!silent)
|
||||||
ctx.respond {
|
ctx.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "Not found"
|
||||||
"Not found",
|
this.description = "There were no matches."
|
||||||
"There were no matches.",
|
this.footer {
|
||||||
u.username + "#" + u.discriminator
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is LoadResult.LoadFailed -> {
|
||||||
TrackResponse.LoadType.LOAD_FAILED -> {
|
if (gts.isEmpty() && player.playingTrack == null) {
|
||||||
|
player.stopTrack()
|
||||||
|
link.destroy()
|
||||||
|
}
|
||||||
if (!silent)
|
if (!silent)
|
||||||
ctx.respond {
|
ctx.respond {
|
||||||
this.embeds.add(
|
this.embed {
|
||||||
MessageUtil.getEmbed(
|
this.color = Color(0xE0311A)
|
||||||
Color(0xE0311A),
|
this.title = "Load failed"
|
||||||
"Load failed",
|
this.description = "There was an error while loading."
|
||||||
"There was an error while loading.", u.username + "#" + u.discriminator
|
this.footer {
|
||||||
)
|
this.text = MessageUtil.getFooter(u)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class AddType(val s: String) {
|
enum class AddType(val s: String) {
|
||||||
QUEUE("Added"),
|
QUEUE("Added"),
|
||||||
UPSERT("Upserted")
|
UPSERT("Upserted")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Botendo
|
||||||
|
* Copyright (C) 2023 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.botendo.extensions.music.components
|
||||||
|
|
||||||
|
import com.kotlindiscord.kord.extensions.commands.Arguments
|
||||||
|
import com.kotlindiscord.kord.extensions.commands.converters.impl.string
|
||||||
|
|
||||||
|
class SeekArguments : Arguments() {
|
||||||
|
val position by string {
|
||||||
|
name = "position"
|
||||||
|
description = "The target postion to seek to. FORMAT: \"XXh XXm XXs\""
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.extensions.util
|
package net.moonleay.botendo.extensions.util
|
||||||
|
@ -22,6 +21,7 @@ package net.moonleay.botendo.extensions.util
|
||||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||||
import dev.kord.common.Color
|
import dev.kord.common.Color
|
||||||
|
import dev.kord.rest.builder.message.embed
|
||||||
import net.moonleay.botendo.util.MessageUtil
|
import net.moonleay.botendo.util.MessageUtil
|
||||||
|
|
||||||
class InfoExtension : Extension() {
|
class InfoExtension : Extension() {
|
||||||
|
@ -31,15 +31,23 @@ class InfoExtension : Extension() {
|
||||||
name = "info"
|
name = "info"
|
||||||
description = "Show infos about the bot"
|
description = "Show infos about the bot"
|
||||||
this.action {
|
this.action {
|
||||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
val u = this.user
|
||||||
this, Color(0x52E01A), "Botendo",
|
this.respond {
|
||||||
"Botendo ***v." + net.moonleay.botendo.build.BuildConstants.version + "***\n" +
|
this.embed {
|
||||||
|
this.color = Color(0x52E01A)
|
||||||
|
this.title = "Botendo"
|
||||||
|
this.description = "Botendo ***v." + net.moonleay.botendo.build.BuildConstants.version + "***\n" +
|
||||||
"Kord-Extensions ***v." + net.moonleay.botendo.build.BuildConstants.kordVersion + "***\n" +
|
"Kord-Extensions ***v." + net.moonleay.botendo.build.BuildConstants.kordVersion + "***\n" +
|
||||||
"lavalink.kt ***v." + net.moonleay.botendo.build.BuildConstants.lavaVersion + "***\n" +
|
"lavalink.kt ***v." + net.moonleay.botendo.build.BuildConstants.lavaVersion + "***\n" +
|
||||||
"Coroutines ***v." + net.moonleay.botendo.build.BuildConstants.coroutinesVersion + "***\n\n\n" +
|
"Coroutines ***v." + net.moonleay.botendo.build.BuildConstants.coroutinesVersion + "***\n\n\n" +
|
||||||
"***Bot made by moonleay#0069***\n" +
|
"***Bot made by moonleay***\n" +
|
||||||
"(c) 2023, licensed under GPL-3.0"
|
"(c) 2023, licensed under GPL-3.0\n" +
|
||||||
)
|
"More infos: https://moonleay.net/projects/botendo\n"
|
||||||
|
this.footer {
|
||||||
|
this.text = MessageUtil.getFooter(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.util
|
package net.moonleay.botendo.util
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.util
|
package net.moonleay.botendo.util
|
||||||
|
|
|
@ -14,91 +14,19 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.util
|
package net.moonleay.botendo.util
|
||||||
|
|
||||||
import com.kotlindiscord.kord.extensions.commands.Arguments
|
import dev.kord.core.behavior.UserBehavior
|
||||||
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.LocalDateTime
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
object MessageUtil {
|
object MessageUtil {
|
||||||
private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss")
|
private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss")
|
||||||
|
|
||||||
///Send an embedded message as a reply
|
suspend fun getFooter(u: UserBehavior? = null): String{
|
||||||
suspend fun sendEmbedForPublicSlashCommand(
|
|
||||||
ctx: PublicSlashCommandContext<Arguments, ModalForm>,
|
|
||||||
color: Color,
|
|
||||||
title: String,
|
|
||||||
description: String
|
|
||||||
) {
|
|
||||||
ctx.respond {
|
|
||||||
embeds.add(
|
|
||||||
getEmbed(
|
|
||||||
color,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///Send an embedded message with an image as a reply
|
|
||||||
suspend fun sendEmbedForPublicSlashCommandWithImage(
|
|
||||||
ctx: PublicSlashCommandContext<Arguments, ModalForm>,
|
|
||||||
color: Color,
|
|
||||||
title: String,
|
|
||||||
description: String,
|
|
||||||
thumbnailUrl: String
|
|
||||||
) {
|
|
||||||
ctx.respond {
|
|
||||||
embeds.add(
|
|
||||||
getEmbedWithImage(
|
|
||||||
color,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator,
|
|
||||||
thumbnailUrl
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///Get an embedded msg with title, description and a src
|
|
||||||
fun getEmbed(
|
|
||||||
color: Color,
|
|
||||||
title: String,
|
|
||||||
description: String,
|
|
||||||
source: String
|
|
||||||
): EmbedBuilder {
|
|
||||||
val now: LocalDateTime = LocalDateTime.now()
|
val now: LocalDateTime = LocalDateTime.now()
|
||||||
val ebb = EmbedBuilder()
|
return ">" + dtf.format(now) + " - ${u?.asUser()?.username?:"Automatic Message"}"
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.util
|
package net.moonleay.botendo.util
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.util
|
package net.moonleay.botendo.util
|
||||||
|
|
||||||
|
import java.time.Duration
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
object TimeUtil {
|
object TimeUtil {
|
||||||
|
@ -87,4 +87,28 @@ object TimeUtil {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//This 100000%ly can be improved, I wrote this at 2am
|
||||||
|
fun getTimeUnformated(timeStr: String): Long {
|
||||||
|
var days: Long = 0
|
||||||
|
var hours: Long = 0
|
||||||
|
var minutes: Long = 0
|
||||||
|
var seconds: Long = 0
|
||||||
|
val timeArr = timeStr.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||||
|
for (s in timeArr) {
|
||||||
|
Logger.out(s)
|
||||||
|
if (s.endsWith("d")) {
|
||||||
|
days = s.split("d".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].toLong()
|
||||||
|
} else if (s.endsWith("h")) {
|
||||||
|
hours = s.split("h".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].toLong()
|
||||||
|
} else if (s.endsWith("m")) {
|
||||||
|
minutes = s.split("m".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].toLong()
|
||||||
|
} else if (s.endsWith("s")) {
|
||||||
|
seconds = s.split("s".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].toLong()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val value = Duration.ofSeconds(seconds).plus(Duration.ofMinutes(minutes)).plus(Duration.ofHours(hours))
|
||||||
|
.plus(Duration.ofDays(days)).toMillis()
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.moonleay.botendo.util
|
package net.moonleay.botendo.util
|
||||||
|
|
27
src/main/kotlin/net/moonleay/botendo/util/UserUtil.kt
Normal file
27
src/main/kotlin/net/moonleay/botendo/util/UserUtil.kt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Botendo
|
||||||
|
* Copyright (C) 2023 moonleay
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.moonleay.botendo.util
|
||||||
|
|
||||||
|
import dev.kord.core.behavior.UserBehavior
|
||||||
|
|
||||||
|
object UserUtil {
|
||||||
|
suspend fun getCommandSrc(u: UserBehavior): String {
|
||||||
|
return "${u.asUser().username}}"
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,4 +15,3 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
#
|
|
||||||
|
|
Loading…
Reference in a new issue