Compare commits
54 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 | |||
9e42893123 | |||
612d7b58cc | |||
1c00f856ab | |||
861cd4b697 | |||
fe4e47744c | |||
e7001f9946 | |||
1654d24378 | |||
23e5abbca9 | |||
8737d3921b | |||
ef130a1510 | |||
f1454af395 | |||
7237095636 | |||
27aee06681 | |||
47b3674b6e | |||
098634ee3f | |||
0d8001b951 | |||
997b25e659 | |||
7a20ad8088 | |||
5abfad091d | |||
e5af032be8 |
64 changed files with 2550 additions and 2144 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,5 +1,7 @@
|
|||
### CUSTOM ###
|
||||
/run/
|
||||
/data/
|
||||
data/
|
||||
/.idea/
|
||||
|
||||
|
||||
|
|
37
README.md
37
README.md
|
@ -3,33 +3,32 @@
|
|||
"6th times the charm" ~ me
|
||||
|
||||
A Discord music bot, written in Kotlin using the kord library.
|
||||
<div class="aside">
|
||||
<img src="https://img.shields.io/badge/100%25-Selfmade-success" alt="100% Selfmade"/>
|
||||
<img src="https://img.shields.io/badge/0%25-optimized-orange" alt="0% optimized"/>
|
||||
<img src="https://img.shields.io/badge/fuck%20it-ship%20it-orange" alt="fuck it, ship it"/>
|
||||
</div>
|
||||
|
||||
## Contributors
|
||||
|
||||
<div class="aside">
|
||||
<img src="https://img.shields.io/badge/limited__dev-Owner%20%26%20Developer-blue" alt="limited_dev: Owner & Developer"/>
|
||||
</div>
|
||||
[](https://gitlab.com/moonleay)
|
||||
|
||||
## Special Thanks to
|
||||
|
||||
- HopeBaron for helping me a lot
|
||||
|
||||
## Known issues
|
||||
## Issues
|
||||
|
||||
- The Repeat feature does not function
|
||||
- The Queue does not show the current song, if there is no song next up
|
||||
- Not all comments are listed below
|
||||
- Report issues to issues@moonleay.net or message @moonleay on Discord
|
||||
|
||||
## Commands
|
||||
## Commands & Features
|
||||
|
||||
- info -- Show basic infos about the bot
|
||||
- play -- Play a song
|
||||
- stop -- Stop playing a song and leave the vc
|
||||
- Commands
|
||||
- info -- Show basic infos about the bot
|
||||
- play -- Play a song and or add it to queue
|
||||
- upsert -- Play a song next up
|
||||
- stop -- Stop playing a song and leave the vc
|
||||
- skip -- Skip to the next song
|
||||
- queue -- Show what songs are next up
|
||||
- nowplaying -- Show what is currently playing
|
||||
- seek -- Seek to a specific time in the song
|
||||
- Features
|
||||
- Button Controller -- You can control the currently playing music using buttons.
|
||||
|
||||
## How to self-host (using the Docker container)
|
||||
|
||||
|
@ -61,9 +60,3 @@ A Discord music bot, written in Kotlin using the kord library.
|
|||
|
||||
Install IntellJ and import the project from git.
|
||||
Done.
|
||||
|
||||
## Docker commands 4 me
|
||||
|
||||
- docker run -it -m 2g -v/home/limited_dev/Documents/Code/Botendo/run/data/:/data/:rw limiteddev/botendo:x.x.x
|
||||
- docker build -t limiteddev/botendo:x.x.x .
|
||||
- docker push limiteddev/botendo:x.x.x
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import org.jetbrains.gradle.ext.ProjectSettings
|
||||
|
@ -30,15 +29,15 @@ plugins {
|
|||
|
||||
//Botendo version 6
|
||||
val ownerID = 372703841151614976L
|
||||
group = "de.limited_dev.botendo"
|
||||
group = "net.moonleay.botendo"
|
||||
version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_SHORT_SHA")}-prod" }
|
||||
?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" }
|
||||
?: "6.3.0"
|
||||
?: "6.5.5"
|
||||
|
||||
val kordver = "1.5.6"
|
||||
val lavaver = "4.0.0"
|
||||
val coroutinesver = "1.1.0"
|
||||
//val ffmpegver = "5.1.2-1.5.8"
|
||||
val kordext_ver = "1.7.1-SNAPSHOT"
|
||||
val lavakord_ver = "6.0.0"
|
||||
val coroutines_ver = "1.7.3"
|
||||
val slf4j_ver = "2.0.9"
|
||||
|
||||
val mavenArtifact = "Botendo"
|
||||
project.base.archivesName.set(mavenArtifact)
|
||||
|
@ -71,6 +70,14 @@ repositories {
|
|||
}
|
||||
}
|
||||
}
|
||||
maven {
|
||||
name = "sonatype"
|
||||
url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots")
|
||||
}
|
||||
maven {
|
||||
name = "sonatype 2"
|
||||
url = uri("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
}
|
||||
}
|
||||
|
||||
val shadow by configurations.getting
|
||||
|
@ -79,18 +86,15 @@ implementation.extendsFrom(shadow)
|
|||
|
||||
dependencies {
|
||||
//Discord
|
||||
shadow("com.kotlindiscord.kord.extensions:kord-extensions:$kordver")
|
||||
shadow("dev.schlaubi.lavakord:kord:$lavaver")
|
||||
shadow("com.kotlindiscord.kord.extensions:kord-extensions:$kordext_ver")
|
||||
shadow("dev.schlaubi.lavakord:kord:$lavakord_ver")
|
||||
|
||||
//Util
|
||||
shadow("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesver")
|
||||
shadow("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_ver")
|
||||
|
||||
//Logging
|
||||
shadow("org.slf4j:slf4j-api:2.0.3")
|
||||
shadow("org.slf4j:slf4j-simple:2.0.3")
|
||||
|
||||
//ffmpeg
|
||||
//shadow("org.bytedeco:ffmpeg:$ffmpegver")
|
||||
shadow("org.slf4j:slf4j-api:$slf4j_ver")
|
||||
shadow("org.slf4j:slf4j-simple:$slf4j_ver")
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,9 +104,9 @@ val templateDest = project.buildDir.resolve("generated/templates")
|
|||
val templateProps = mapOf(
|
||||
"version" to project.version as String,
|
||||
"ownerID" to ownerID,
|
||||
"kordversion" to kordver,
|
||||
"lavaversion" to lavaver,
|
||||
"coroutinesversion" to coroutinesver
|
||||
"kordversion" to kordext_ver,
|
||||
"lavaversion" to lavakord_ver,
|
||||
"coroutinesversion" to coroutines_ver
|
||||
)
|
||||
|
||||
|
||||
|
@ -119,7 +123,7 @@ tasks {
|
|||
|
||||
withType<Jar> {
|
||||
manifest {
|
||||
attributes["Main-Class"] = "de.limited_dev.botendo.MainKt"
|
||||
attributes["Main-Class"] = "net.moonleay.botendo.MainKt"
|
||||
}
|
||||
// To add all of the dependencies
|
||||
from(sourceSets.main.get().output)
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
#
|
||||
# Botendo
|
||||
# Copyright (C) 2023 limited_dev
|
||||
# Botendo
|
||||
# Copyright (C) 2023 moonleay
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# 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/>.
|
||||
#
|
||||
kotlin.code.style=official
|
||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
30
gradle/wrapper/gradle-wrapper.properties
vendored
30
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,23 +1,25 @@
|
|||
#
|
||||
# Botendo
|
||||
# Copyright (C) 2023 limited_dev
|
||||
# Botendo
|
||||
# Copyright (C) 2023 moonleay
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
66
gradlew
vendored
66
gradlew
vendored
|
@ -1,22 +1,21 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Botendo
|
||||
# Copyright (C) 2023 limited_dev
|
||||
# Botendo
|
||||
# Copyright (C) 2023 moonleay
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
|
@ -58,7 +57,7 @@
|
|||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
|
@ -83,13 +82,11 @@ do
|
|||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
@ -136,22 +133,29 @@ location of your Java installation."
|
|||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
|
@ -196,11 +200,15 @@ if "$cygwin" || "$msys" ; then
|
|||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
|
@ -208,6 +216,12 @@ set -- \
|
|||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
|
15
gradlew.bat
vendored
15
gradlew.bat
vendored
|
@ -14,7 +14,7 @@
|
|||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
|
@ -25,7 +25,8 @@
|
|||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
|
@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
rootProject.name = "Botendo"
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo
|
||||
|
||||
import com.kotlindiscord.kord.extensions.ExtensibleBot
|
||||
import de.limited_dev.botendo.buttons.ButtonManager
|
||||
import de.limited_dev.botendo.data.CredentialManager
|
||||
import de.limited_dev.botendo.extensions.music.*
|
||||
import de.limited_dev.botendo.extensions.util.InfoExtension
|
||||
import de.limited_dev.botendo.extensions.util.PotatoExtension
|
||||
import de.limited_dev.botendo.util.Logger
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.event.interaction.ButtonInteractionCreateEvent
|
||||
import dev.kord.core.on
|
||||
import dev.schlaubi.lavakord.LavaKord
|
||||
import dev.schlaubi.lavakord.kord.lavakord
|
||||
|
||||
object Bot {
|
||||
//The kord object gets set at app launch
|
||||
private lateinit var bot: ExtensibleBot
|
||||
lateinit var lava: LavaKord
|
||||
suspend fun start() {
|
||||
Logger.out("Starting Bot...")
|
||||
|
||||
//Load config
|
||||
CredentialManager.load()
|
||||
|
||||
//Don't run the bot when there is no bot token in config
|
||||
if (CredentialManager.token == "empty") {
|
||||
Logger.out("The config does not contain a bot token")
|
||||
return
|
||||
}
|
||||
|
||||
//Add Bot token to kord
|
||||
//kord = Kord(CredentialManager.token)
|
||||
bot = ExtensibleBot(CredentialManager.token) {
|
||||
applicationCommands {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
extensions {
|
||||
add(::InfoExtension)
|
||||
add(::PlayExtension)
|
||||
add(::StopExtension)
|
||||
add(::SkipExtension)
|
||||
add(::NowPlayingExtension)
|
||||
add(::QueueExtension)
|
||||
add(::PotatoExtension)
|
||||
}
|
||||
|
||||
this.presence {
|
||||
this.streaming("music", "https://twitch.tv/limited_dev")
|
||||
}
|
||||
}
|
||||
|
||||
//Add LavaLink
|
||||
lava = bot.kordRef.lavakord()
|
||||
|
||||
//Add the LavaLink node from config
|
||||
lava.addNode(CredentialManager.linkip, CredentialManager.linkpw)
|
||||
|
||||
//Register Button presses
|
||||
bot.kordRef.on<ButtonInteractionCreateEvent> {
|
||||
val inter = this.interaction
|
||||
val response = inter.deferPublicResponse()
|
||||
val u = inter.user
|
||||
val g = this.interaction.getOriginalInteractionResponse().getGuild()
|
||||
for (b in ButtonManager.buttons) {
|
||||
if (b.id != inter.componentId)
|
||||
continue
|
||||
b.onInteraction(response, g, u)
|
||||
return@on
|
||||
}
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Error",
|
||||
"Could not find button with id \"${inter.componentId}\".\nPlease report this.",
|
||||
u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//Start the bot
|
||||
bot.start()
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo
|
||||
|
||||
import de.limited_dev.botendo.build.BuildConstants
|
||||
|
||||
|
||||
///Show the splash and launch the Bot
|
||||
suspend fun main() {
|
||||
println(
|
||||
"M#\"\"\"\"\"\"\"'M dP dP \n" +
|
||||
"## mmmm. `M 88 88 \n" +
|
||||
"#' .M .d8888b. d8888P .d8888b. 88d888b. .d888b88 .d8888b. \n" +
|
||||
"M# MMMb.'YM 88' `88 88 88ooood8 88' `88 88' `88 88' `88 \n" +
|
||||
"M# MMMM' M 88. .88 88 88. ... 88 88 88. .88 88. .88 \n" +
|
||||
"M# .;M `88888P' dP `88888P' dP dP `88888P8 `88888P' \n" +
|
||||
"M#########M \n" +
|
||||
" "
|
||||
)
|
||||
println("Bot v.${BuildConstants.version}, Kord Extensions v.${BuildConstants.kordVersion}, LavaKord v.${BuildConstants.lavaVersion}, Coroutines v.${BuildConstants.coroutinesVersion}")
|
||||
Bot.start()
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.buttons
|
||||
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
|
||||
open class Button(val id: String) {
|
||||
|
||||
open suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.buttons
|
||||
|
||||
import de.limited_dev.botendo.buttons.music.*
|
||||
|
||||
object ButtonManager {
|
||||
val buttons = listOf(RepeatButton(), PauseButton(), SkipButton(), QueueButton(), StopButton())
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.buttons.music
|
||||
|
||||
import de.limited_dev.botendo.Bot
|
||||
import de.limited_dev.botendo.buttons.Button
|
||||
import de.limited_dev.botendo.extensions.music.components.MusicManager
|
||||
import de.limited_dev.botendo.util.ButtonUtil
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
import dev.kord.rest.builder.message.modify.actionRow
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
|
||||
class PauseButton : Button("btn.music.pause") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||
if (voiceState == null) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not connected to a VC",
|
||||
"Please connect to a VC",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val channelId = voiceState.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything.",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not in my VC",
|
||||
"We are not in the same VC and therefore, you cannot control the music",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
player.pause(!player.paused)
|
||||
|
||||
val gts = MusicManager.getGuildTrackScheduler(guild, player)
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0x52E01A),
|
||||
if (player.paused) "I paused" else "I'm continuing",
|
||||
if (player.paused) "I paused the song" else "I'm continuing to play the song.",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.buttons.music
|
||||
|
||||
import de.limited_dev.botendo.Bot
|
||||
import de.limited_dev.botendo.buttons.Button
|
||||
import de.limited_dev.botendo.extensions.music.components.MusicManager
|
||||
import de.limited_dev.botendo.util.ButtonUtil
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import de.limited_dev.botendo.util.TimeUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
import dev.kord.rest.builder.message.modify.actionRow
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
|
||||
class QueueButton : Button("btn.music.queue") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything.",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val track = player.playingTrack
|
||||
if (track == null) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Not playing",
|
||||
"I'm not playing anything currently", user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
|
||||
val q = gts.getQueue()
|
||||
var desc =
|
||||
"""${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length.inWholeMilliseconds)} (${track.author})**""" + "\n"
|
||||
for ((i, tr) in q.withIndex()) {
|
||||
if (i >= 14)
|
||||
continue
|
||||
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
|
||||
}
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0x52E01A),
|
||||
"Queue",
|
||||
desc,
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.buttons.music
|
||||
|
||||
import de.limited_dev.botendo.Bot
|
||||
import de.limited_dev.botendo.buttons.Button
|
||||
import de.limited_dev.botendo.extensions.music.components.MusicManager
|
||||
import de.limited_dev.botendo.util.ButtonUtil
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
import dev.kord.rest.builder.message.modify.actionRow
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
|
||||
class RepeatButton : Button("btn.music.repeat") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||
if (voiceState == null) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not connected to a VC",
|
||||
"Please connect to a VC",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val channelId = voiceState.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything.",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not in my VC",
|
||||
"We are not in the same VC and therefore, you cannot control the music",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val gts = MusicManager.getGuildTrackScheduler(guild, player)
|
||||
gts.repeating = !gts.repeating
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0x52E01A),
|
||||
if (gts.repeating) "Now Repeating" else "Now Continuing",
|
||||
if (gts.repeating) "The current track will now loop" else "The next track will play when this song finishes",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.buttons.music
|
||||
|
||||
import de.limited_dev.botendo.Bot
|
||||
import de.limited_dev.botendo.buttons.Button
|
||||
import de.limited_dev.botendo.extensions.music.components.MusicManager
|
||||
import de.limited_dev.botendo.util.ButtonUtil
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import de.limited_dev.botendo.util.TimeUtil
|
||||
import de.limited_dev.botendo.util.UrlUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
import dev.kord.rest.builder.message.modify.actionRow
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
|
||||
class SkipButton : Button("btn.music.skip") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||
if (voiceState == null) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not connected to a VC",
|
||||
"Please connect to a VC",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val channelId = voiceState.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything.",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not in my VC",
|
||||
"We are not in the same VC and therefore, you cannot control the music",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
var track = player.playingTrack
|
||||
if (track == null) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Not playing",
|
||||
"I'm not playing anything currently", user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
|
||||
if (!gts.isEmpty()) {
|
||||
track = gts.getHead().toTrack()
|
||||
gts.playNext()
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbedWithImage(
|
||||
Color(0x52E01A),
|
||||
"Skipped song; now playing",
|
||||
"**${track.title}**\n*Now Playing*\nby ${track.author} :: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
track.length.inWholeMilliseconds
|
||||
)
|
||||
}\n" +
|
||||
">>>${track.uri}",
|
||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
player.stopTrack()
|
||||
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0x52E01A),
|
||||
"Skipped song; now playing",
|
||||
"Nothing",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
this.actionRow {
|
||||
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.buttons.music
|
||||
|
||||
import de.limited_dev.botendo.Bot
|
||||
import de.limited_dev.botendo.buttons.Button
|
||||
import de.limited_dev.botendo.extensions.music.components.MusicManager
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
|
||||
class StopButton : Button("btn.music.stop") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||
if (voiceState == null) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not connected to a VC",
|
||||
"Please connect to a VC",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val channelId = voiceState.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything.",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not in my VC",
|
||||
"We are not in the same VC and therefore, you cannot control the music",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
player.stopTrack()
|
||||
link.destroy()
|
||||
MusicManager.getGuildTrackScheduler(guild.asGuild(), player).clear()
|
||||
response.respond {
|
||||
this.embeds = mutableListOf(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0x52E01A),
|
||||
"I stopped and left",
|
||||
"just like your girlfriend",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.extensions.music
|
||||
|
||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||
import com.kotlindiscord.kord.extensions.types.respond
|
||||
import de.limited_dev.botendo.Bot
|
||||
import de.limited_dev.botendo.extensions.music.components.MusicManager
|
||||
import de.limited_dev.botendo.util.ButtonUtil
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import de.limited_dev.botendo.util.TimeUtil
|
||||
import de.limited_dev.botendo.util.UrlUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.rest.builder.message.create.actionRow
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import dev.schlaubi.lavakord.kord.getLink
|
||||
|
||||
class NowPlayingExtension : Extension() {
|
||||
override val name = "nowplaying"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "nowplaying"
|
||||
description = "Show what's currently playing"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = Bot.lava.getLink(guildId)
|
||||
val player = link.player
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0A81A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything."
|
||||
)
|
||||
return@action
|
||||
}
|
||||
val track = player.playingTrack
|
||||
if (track == null) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0A81A),
|
||||
"Not Playing",
|
||||
"I'm not playing anything currently"
|
||||
)
|
||||
return@action
|
||||
}
|
||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbedWithImage(
|
||||
Color(0x52E01A),
|
||||
"Currently playing",
|
||||
"**${track.title}**\n*Now Playing*\nby ${track.author} :${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
track.position.inWholeMilliseconds
|
||||
)
|
||||
}: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
track.length.inWholeMilliseconds
|
||||
)
|
||||
}\n" +
|
||||
">>>${track.uri}",
|
||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.extensions.music
|
||||
|
||||
import com.kotlindiscord.kord.extensions.commands.Arguments
|
||||
import com.kotlindiscord.kord.extensions.commands.converters.impl.string
|
||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||
import com.kotlindiscord.kord.extensions.types.respond
|
||||
import de.limited_dev.botendo.Bot
|
||||
import de.limited_dev.botendo.extensions.music.components.MusicManager
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import dev.schlaubi.lavakord.kord.getLink
|
||||
|
||||
|
||||
class PlayExtension : Extension() {
|
||||
|
||||
override val name = "play"
|
||||
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand(::PlayArgs) {
|
||||
name = "play"
|
||||
description = "Play music"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = Bot.lava.getLink(guildId)
|
||||
val u = this.user
|
||||
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
||||
if (vcsUser == null) {
|
||||
this.respond {
|
||||
embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not connected to a VC",
|
||||
"Please connect to a VC",
|
||||
u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return@action
|
||||
}
|
||||
|
||||
val channelId = vcsUser.channelId
|
||||
|
||||
if (link.state != Link.State.CONNECTED) {
|
||||
link.connectAudio(channelId!!.value)
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
this.respond {
|
||||
embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not in my VC",
|
||||
"We are not in the same VC and therefore, you cannot play any music",
|
||||
u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return@action
|
||||
}
|
||||
|
||||
val query = arguments.linkquery
|
||||
val search = if (query.startsWith("http")) {
|
||||
query
|
||||
} else {
|
||||
"ytsearch:$query"
|
||||
}
|
||||
this.respond {
|
||||
embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0A81A),
|
||||
"Searching...",
|
||||
"We are looking for $query",
|
||||
u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
MusicManager.addToQueue(this, link, search)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class PlayArgs : Arguments() {
|
||||
val linkquery by string {
|
||||
name = "linkqery"
|
||||
description = "Song link or search query"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.extensions.music
|
||||
|
||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||
import com.kotlindiscord.kord.extensions.types.respond
|
||||
import de.limited_dev.botendo.Bot
|
||||
import de.limited_dev.botendo.extensions.music.components.MusicManager
|
||||
import de.limited_dev.botendo.util.ButtonUtil
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import de.limited_dev.botendo.util.TimeUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.rest.builder.message.create.actionRow
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
|
||||
class QueueExtension : Extension() {
|
||||
override val name = "queue"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "queue"
|
||||
description = "Show whats up next"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0311A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything."
|
||||
)
|
||||
return@action
|
||||
}
|
||||
val track = player.playingTrack
|
||||
if (track == null) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0A81A),
|
||||
"Queue empty",
|
||||
"I'm not playing anything currently"
|
||||
)
|
||||
return@action
|
||||
}
|
||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||
val q = gts.getQueue()
|
||||
var desc =
|
||||
"""${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length.inWholeMilliseconds)} (${track.author})**""" + "\n"
|
||||
for ((i, tr) in q.withIndex()) {
|
||||
if (i >= 14)
|
||||
continue
|
||||
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
|
||||
}
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0x52E01A),
|
||||
"Queue",
|
||||
desc,
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.extensions.music
|
||||
|
||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||
import com.kotlindiscord.kord.extensions.types.respond
|
||||
import de.limited_dev.botendo.Bot
|
||||
import de.limited_dev.botendo.extensions.music.components.MusicManager
|
||||
import de.limited_dev.botendo.util.ButtonUtil
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import de.limited_dev.botendo.util.TimeUtil
|
||||
import de.limited_dev.botendo.util.UrlUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.rest.builder.message.create.actionRow
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
|
||||
class SkipExtension : Extension() {
|
||||
override val name = "skip"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "skip"
|
||||
description = "Skip to the next song in queue"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val u = this.user
|
||||
val voiceState = u.asMember(guildId).getVoiceStateOrNull()
|
||||
if (voiceState == null) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0311A),
|
||||
"You are not connected to a VC",
|
||||
"Please connect to a VC"
|
||||
)
|
||||
return@action
|
||||
}
|
||||
|
||||
val channelId = voiceState.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0311A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything."
|
||||
)
|
||||
return@action
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0311A),
|
||||
"You are not in my VC",
|
||||
"We are not in the same VC and therefore, you cannot control the music"
|
||||
)
|
||||
return@action
|
||||
}
|
||||
var track = player.playingTrack
|
||||
if (track == null) {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this,
|
||||
Color(0xE0311A),
|
||||
"Not playing",
|
||||
"I'm not playing anything currently"
|
||||
)
|
||||
return@action
|
||||
}
|
||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||
if (!gts.isEmpty()) {
|
||||
track = gts.getHead().toTrack()
|
||||
gts.playNext()
|
||||
} else {
|
||||
player.stopTrack()
|
||||
}
|
||||
|
||||
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbedWithImage(
|
||||
Color(0x52E01A),
|
||||
"Skipped song; now playing",
|
||||
"**${track.title}**\n*Now Playing*\nby ${track.author} :: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
track.length.inWholeMilliseconds
|
||||
)
|
||||
}\n" +
|
||||
">>>${track.uri}",
|
||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg",
|
||||
user.asUser().username + "#" + user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.extensions.music
|
||||
|
||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||
import com.kotlindiscord.kord.extensions.types.respond
|
||||
import de.limited_dev.botendo.Bot
|
||||
import de.limited_dev.botendo.extensions.music.components.MusicManager
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import dev.schlaubi.lavakord.kord.getLink
|
||||
|
||||
class StopExtension : Extension() {
|
||||
override val name = "stop"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "stop"
|
||||
description = "Stop playing and start leavin'"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = Bot.lava.getLink(guildId)
|
||||
val player = link.player
|
||||
val u = this.user
|
||||
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
||||
if (vcsUser == null) {
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not connected to a VC",
|
||||
"Please connect to my VC", u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return@action
|
||||
}
|
||||
val channelId = vcsUser.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Not connected",
|
||||
"I'm not in a VC and therefore, I am not playing anything.",
|
||||
u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return@action
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"You are not in my VC",
|
||||
"We are not in the same VC", u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
return@action
|
||||
}
|
||||
player.stopTrack()
|
||||
link.destroy()
|
||||
MusicManager.getGuildTrackScheduler(this.getGuild()!!.asGuild(), player).clear()
|
||||
this.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0x52E01A),
|
||||
"I stopped and left",
|
||||
"just like your girlfriend",
|
||||
u.asUser().username + "#" + u.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.extensions.music.components
|
||||
|
||||
import de.limited_dev.botendo.util.Logger
|
||||
import dev.schlaubi.lavakord.audio.*
|
||||
import dev.schlaubi.lavakord.audio.player.Player
|
||||
import dev.schlaubi.lavakord.rest.models.PartialTrack
|
||||
import java.util.concurrent.BlockingQueue
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
|
||||
class GuildTrackScheduler(val pl: Player) {
|
||||
|
||||
private var queue: BlockingQueue<PartialTrack> = LinkedBlockingQueue()
|
||||
var repeating = false
|
||||
private var hasRegisteredEvents = false
|
||||
|
||||
///Add a track to queue and start playing, if there is no song currently playing
|
||||
suspend fun queue(track: PartialTrack) {
|
||||
if (this.pl.playingTrack == null) {
|
||||
play(track)
|
||||
} else {
|
||||
queue.offer(track)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun playNext() {
|
||||
if (!queue.isEmpty())
|
||||
this.pl.playTrack(queue.poll())
|
||||
else
|
||||
this.pl.stopTrack()
|
||||
}
|
||||
|
||||
private suspend fun play(tr: PartialTrack) {
|
||||
this.pl.playTrack(tr)
|
||||
}
|
||||
|
||||
fun addEvents() {
|
||||
if (hasRegisteredEvents)
|
||||
return
|
||||
hasRegisteredEvents = true
|
||||
|
||||
Logger.out("Adding track events to GuildTrackScheduler...")
|
||||
|
||||
pl.on<Event, TrackEndEvent> {
|
||||
onTrackEnd(this)
|
||||
}
|
||||
|
||||
pl.on<Event, TrackStuckEvent> {
|
||||
onTrackStuck(this)
|
||||
}
|
||||
|
||||
pl.on<Event, TrackExceptionEvent> {
|
||||
onTrackExc(this)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onTrackEnd(e: TrackEndEvent) {
|
||||
if (e.reason.mayStartNext) {
|
||||
if (repeating) {
|
||||
Logger.out("Repeating track....")
|
||||
this.pl.playTrack(e.getTrack().copy())
|
||||
return
|
||||
}
|
||||
Logger.out("Track has ended; Playing next...")
|
||||
playNext()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onTrackStuck(e: TrackStuckEvent) {
|
||||
Logger.out("Track is stuck, retrying...")
|
||||
this.pl.playTrack(e.getTrack().copy())
|
||||
}
|
||||
|
||||
private suspend fun onTrackExc(e: TrackExceptionEvent) {
|
||||
Logger.out("Track had an exception, retrying...")
|
||||
this.pl.playTrack(e.getTrack().copy())
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
Logger.out("Clearing queue...")
|
||||
repeating = false
|
||||
queue.clear()
|
||||
}
|
||||
|
||||
fun getQueue(): List<PartialTrack> {
|
||||
return queue.toList()
|
||||
}
|
||||
|
||||
fun getHead(): PartialTrack {
|
||||
return queue.first()
|
||||
}
|
||||
|
||||
fun isEmpty(): Boolean {
|
||||
return queue.isEmpty()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.extensions.music.components
|
||||
|
||||
import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext
|
||||
import com.kotlindiscord.kord.extensions.components.forms.ModalForm
|
||||
import com.kotlindiscord.kord.extensions.types.respond
|
||||
import de.limited_dev.botendo.extensions.music.PlayExtension
|
||||
import de.limited_dev.botendo.util.ButtonUtil
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import de.limited_dev.botendo.util.TimeUtil
|
||||
import de.limited_dev.botendo.util.UrlUtil
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.common.entity.Snowflake
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.rest.builder.message.create.actionRow
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import dev.schlaubi.lavakord.audio.player.Player
|
||||
import dev.schlaubi.lavakord.rest.loadItem
|
||||
import dev.schlaubi.lavakord.rest.models.TrackResponse
|
||||
|
||||
object MusicManager {
|
||||
private var musicManagerMap: MutableMap<Snowflake, GuildTrackScheduler> = mutableMapOf()
|
||||
|
||||
fun getGuildTrackScheduler(guild: Guild, player: Player): GuildTrackScheduler {
|
||||
return musicManagerMap.computeIfAbsent(guild.id) {
|
||||
GuildTrackScheduler(player)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
suspend fun addToQueue(
|
||||
ctx: PublicSlashCommandContext<PlayExtension.PlayArgs, ModalForm>,
|
||||
link: Link,
|
||||
search: String
|
||||
) {
|
||||
addToQueue(ctx, link, search, false)
|
||||
}
|
||||
|
||||
suspend fun addToQueue(
|
||||
ctx: PublicSlashCommandContext<PlayExtension.PlayArgs, ModalForm>,
|
||||
link: Link,
|
||||
search: String,
|
||||
silent: Boolean
|
||||
) {
|
||||
val player = link.player
|
||||
val item = link.loadItem(search)
|
||||
val gts = getGuildTrackScheduler(ctx.guild!!.asGuild(), player)
|
||||
val u = ctx.user.asUser()
|
||||
|
||||
gts.addEvents()
|
||||
|
||||
when (item.loadType) {
|
||||
TrackResponse.LoadType.TRACK_LOADED -> {
|
||||
gts.queue(item.track)
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbedWithImage(
|
||||
Color(0x52E01A),
|
||||
"Queuing track from link",
|
||||
"**${item.track.info.title}**\n*Queue*\nby ${item.track.info.author} :: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
item.track.info.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${item.track.info.uri}", u.username + "#" + u.discriminator,
|
||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg"
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TrackResponse.LoadType.PLAYLIST_LOADED -> {
|
||||
val l = item.tracks.reversed()
|
||||
for (partialTrack in l) {
|
||||
gts.queue(partialTrack)
|
||||
}
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbedWithImage(
|
||||
Color(0x52E01A),
|
||||
"Queuing playlist from link",
|
||||
"**${item.tracks.first().info.title}**\n*${item.playlistInfo.name}*\nby ${item.tracks.first().info.author} :: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
item.tracks.first().info.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator,
|
||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg"
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TrackResponse.LoadType.SEARCH_RESULT -> {
|
||||
gts.queue(item.tracks.first())
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbedWithImage(
|
||||
Color(0x52E01A),
|
||||
"Queuing track from query",
|
||||
"**${item.tracks.first().info.title}**\n*Queue*\nby ${item.tracks.first().info.author} :: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
item.tracks.first().info.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator,
|
||||
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.tracks.first().info.uri) + "/maxresdefault.jpg"
|
||||
)
|
||||
)
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TrackResponse.LoadType.NO_MATCHES -> {
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Not found",
|
||||
"There were no matches.",
|
||||
u.username + "#" + u.discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
TrackResponse.LoadType.LOAD_FAILED -> {
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embeds.add(
|
||||
MessageUtil.getEmbed(
|
||||
Color(0xE0311A),
|
||||
"Load failed",
|
||||
"There was an error while loading.", u.username + "#" + u.discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.extensions.util
|
||||
|
||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||
import de.limited_dev.botendo.build.BuildConstants
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import dev.kord.common.Color
|
||||
|
||||
class InfoExtension : Extension() {
|
||||
override val name = "info"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "info"
|
||||
description = "Show infos about the bot"
|
||||
this.action {
|
||||
MessageUtil.sendEmbedForPublicSlashCommand(
|
||||
this, Color(0x52E01A), "Botendo",
|
||||
"Botendo ***v." + BuildConstants.version + "***\n" +
|
||||
"Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" +
|
||||
"lavalink.kt ***v." + BuildConstants.lavaVersion + "***\n" +
|
||||
"Coroutines ***v." + BuildConstants.coroutinesVersion + "***\n\n\n" +
|
||||
"***Bot made by moonleay#7441***\n" +
|
||||
"(c) 2023, licensed under GPL-3.0"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.extensions.util
|
||||
|
||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||
import de.limited_dev.botendo.util.MessageUtil
|
||||
import dev.kord.common.Color
|
||||
|
||||
class PotatoExtension : Extension() {
|
||||
override val name = "potato"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "potato"
|
||||
description = "Potato"
|
||||
this.action {
|
||||
MessageUtil.sendEmbedForPublicSlashCommandWithImage(
|
||||
this, Color(0xE0311A), "Potato",
|
||||
"Potato",
|
||||
"https://static.tumblr.com/c06d8e0928395746a63b9c5d3cb1ce66/sl9iajp/gxFmqk38z/tumblr_static_potato-equality.jpg"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.util
|
||||
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
object Logger {
|
||||
private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("yy/MM/dd HH:mm:ss")
|
||||
|
||||
fun out(msg: String) {
|
||||
val caller = Thread.currentThread().stackTrace[2]
|
||||
val now: LocalDateTime = LocalDateTime.now()
|
||||
try {
|
||||
println(
|
||||
("[" + Class.forName(caller.className).simpleName + "." +
|
||||
caller.methodName + ":" + caller.lineNumber + "] [" + dtf.format(now)).toString() + "] <" + msg + ">"
|
||||
)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// Ich kann nicht mehr
|
||||
// [Klasse.Funktion] [T/M HH:MM] <NACHRICHT>
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.util
|
||||
|
||||
import com.kotlindiscord.kord.extensions.commands.Arguments
|
||||
import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext
|
||||
import com.kotlindiscord.kord.extensions.components.forms.ModalForm
|
||||
import com.kotlindiscord.kord.extensions.types.respond
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.rest.builder.message.EmbedBuilder
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
object MessageUtil {
|
||||
private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss")
|
||||
|
||||
///Send an embedded message as a reply
|
||||
suspend fun sendEmbedForPublicSlashCommand(
|
||||
ctx: PublicSlashCommandContext<Arguments, ModalForm>,
|
||||
color: Color,
|
||||
title: String,
|
||||
description: String
|
||||
) {
|
||||
ctx.respond {
|
||||
embeds.add(
|
||||
getEmbed(
|
||||
color,
|
||||
title,
|
||||
description,
|
||||
ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
///Send an embedded message with an image as a reply
|
||||
suspend fun sendEmbedForPublicSlashCommandWithImage(
|
||||
ctx: PublicSlashCommandContext<Arguments, ModalForm>,
|
||||
color: Color,
|
||||
title: String,
|
||||
description: String,
|
||||
thumbnailUrl: String
|
||||
) {
|
||||
ctx.respond {
|
||||
embeds.add(
|
||||
getEmbedWithImage(
|
||||
color,
|
||||
title,
|
||||
description,
|
||||
ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator,
|
||||
thumbnailUrl
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
///Get an embedded msg with title, description and a src
|
||||
fun getEmbed(
|
||||
color: Color,
|
||||
title: String,
|
||||
description: String,
|
||||
source: String
|
||||
): EmbedBuilder {
|
||||
val now: LocalDateTime = LocalDateTime.now()
|
||||
val ebb = EmbedBuilder()
|
||||
ebb.title = title
|
||||
ebb.description = description
|
||||
ebb.footer = EmbedBuilder.Footer()
|
||||
ebb.footer!!.text = ">" + dtf.format(now) + " - $source"
|
||||
ebb.color = color
|
||||
return ebb
|
||||
}
|
||||
|
||||
///Get an embedded msg with image, title, description and a src
|
||||
fun getEmbedWithImage(
|
||||
color: Color,
|
||||
title: String,
|
||||
description: String,
|
||||
source: String,
|
||||
thumbnailUrl: String
|
||||
): EmbedBuilder {
|
||||
val ebb = getEmbed(color, title, description, source)
|
||||
ebb.thumbnail = EmbedBuilder.Thumbnail()
|
||||
ebb.thumbnail!!.url = thumbnailUrl
|
||||
return ebb
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.util
|
||||
|
||||
object Status {
|
||||
//TODO: impl.
|
||||
suspend fun updateStatus() {
|
||||
/* Bot.kord.editPresence {
|
||||
this.playing("")
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.util
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object TimeUtil {
|
||||
///Convert Miliseconds to xdays xhours xmins xsecs
|
||||
fun getTimeFormatedShortend(time: Long): String {
|
||||
var time = time
|
||||
val days = TimeUnit.MILLISECONDS
|
||||
.toDays(time)
|
||||
time -= TimeUnit.DAYS.toMillis(days)
|
||||
val hours = TimeUnit.MILLISECONDS
|
||||
.toHours(time)
|
||||
time -= TimeUnit.HOURS.toMillis(hours)
|
||||
val minutes = TimeUnit.MILLISECONDS
|
||||
.toMinutes(time)
|
||||
time -= TimeUnit.MINUTES.toMillis(minutes)
|
||||
val seconds = TimeUnit.MILLISECONDS
|
||||
.toSeconds(time)
|
||||
var s = ""
|
||||
if (days >= 1) {
|
||||
s += days.toString() + "d "
|
||||
}
|
||||
if (hours >= 1) {
|
||||
s += hours.toString() + "h "
|
||||
}
|
||||
if (minutes >= 1) {
|
||||
s += minutes.toString() + "m "
|
||||
}
|
||||
if (seconds >= 1 && hours < 1) {
|
||||
s += seconds.toString() + "s"
|
||||
}
|
||||
if (s.isEmpty() || s.isBlank()) {
|
||||
s = "0s"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
fun getTimeFormatedRaw(time: Long): String {
|
||||
var time = time
|
||||
val days = TimeUnit.MILLISECONDS
|
||||
.toDays(time)
|
||||
time -= TimeUnit.DAYS.toMillis(days)
|
||||
val hours = TimeUnit.MILLISECONDS
|
||||
.toHours(time)
|
||||
time -= TimeUnit.HOURS.toMillis(hours)
|
||||
val minutes = TimeUnit.MILLISECONDS
|
||||
.toMinutes(time)
|
||||
time -= TimeUnit.MINUTES.toMillis(minutes)
|
||||
val seconds = TimeUnit.MILLISECONDS
|
||||
.toSeconds(time)
|
||||
var s = ""
|
||||
if (days >= 1) {
|
||||
s += days.toString() + "d "
|
||||
}
|
||||
if (hours >= 1) {
|
||||
s += hours.toString() + "h "
|
||||
}
|
||||
if (minutes >= 1) {
|
||||
s += minutes.toString() + "m "
|
||||
}
|
||||
if (seconds >= 1) {
|
||||
s += seconds.toString() + "s"
|
||||
}
|
||||
if (s.isEmpty() || s.isBlank()) {
|
||||
s = "0s"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.util
|
||||
|
||||
object UrlUtil {
|
||||
///Strip the video ID from a YouTube link
|
||||
fun getYtThumbnailUrl(uri: String): String {
|
||||
return uri.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
|
||||
}
|
||||
}
|
144
src/main/kotlin/net/moonleay/botendo/Bot.kt
Normal file
144
src/main/kotlin/net/moonleay/botendo/Bot.kt
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo
|
||||
|
||||
import com.kotlindiscord.kord.extensions.ExtensibleBot
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.common.entity.Snowflake
|
||||
import dev.kord.core.behavior.getChannelOf
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.channel.VoiceChannel
|
||||
import dev.kord.core.event.interaction.ButtonInteractionCreateEvent
|
||||
import dev.kord.core.event.user.VoiceStateUpdateEvent
|
||||
import dev.kord.core.on
|
||||
import dev.kord.rest.builder.message.embed
|
||||
import dev.schlaubi.lavakord.LavaKord
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import dev.schlaubi.lavakord.kord.getLink
|
||||
import dev.schlaubi.lavakord.kord.lavakord
|
||||
import kotlinx.coroutines.flow.count
|
||||
import net.moonleay.botendo.data.CredentialManager
|
||||
import net.moonleay.botendo.extensions.music.*
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.extensions.util.InfoExtension
|
||||
import net.moonleay.botendo.util.Logger
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
object Bot {
|
||||
//The kord object gets set at app launch
|
||||
private lateinit var bot: ExtensibleBot
|
||||
lateinit var lava: LavaKord
|
||||
suspend fun start() {
|
||||
Logger.out("Starting Bot...")
|
||||
|
||||
//Load config
|
||||
CredentialManager.load()
|
||||
|
||||
//Don't run the bot when there is no bot token in config
|
||||
if (CredentialManager.token == "empty") {
|
||||
Logger.out("The config does not contain a bot token")
|
||||
return
|
||||
}
|
||||
|
||||
//Add Bot token to kord
|
||||
//kord = Kord(CredentialManager.token)
|
||||
bot = ExtensibleBot(CredentialManager.token) {
|
||||
applicationCommands {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
extensions {
|
||||
add(::InfoExtension)
|
||||
add(::PlayExtension)
|
||||
add(::StopExtension)
|
||||
add(::SkipExtension)
|
||||
add(::NowPlayingExtension)
|
||||
add(::QueueExtension)
|
||||
add(::UpsertExtension)
|
||||
add(::SeekExtension)
|
||||
}
|
||||
|
||||
this.presence {
|
||||
this.streaming("music", "https://twitch.tv/moonleaytv")
|
||||
}
|
||||
}
|
||||
|
||||
//Add LavaLink
|
||||
lava = bot.kordRef.lavakord()
|
||||
|
||||
//Add the LavaLink node from config
|
||||
lava.addNode(CredentialManager.linkip, CredentialManager.linkpw)
|
||||
|
||||
//Register Button presses
|
||||
bot.kordRef.on<ButtonInteractionCreateEvent> {
|
||||
val inter = this.interaction
|
||||
val response = inter.deferPublicResponse()
|
||||
val u = inter.user
|
||||
val g = this.interaction.getOriginalInteractionResponse().getGuild()
|
||||
for (b in net.moonleay.botendo.buttons.ButtonManager.buttons) {
|
||||
if (b.id != inter.componentId)
|
||||
continue
|
||||
b.onInteraction(response, g, u)
|
||||
return@on
|
||||
}
|
||||
// Button not found
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Error"
|
||||
this.description = "Could not find button with id \"${inter.componentId}\".\nPlease report this."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the bot to leave the VC if there are no users in the VC
|
||||
bot.kordRef.on<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
|
||||
bot.start()
|
||||
}
|
||||
}
|
42
src/main/kotlin/net/moonleay/botendo/Main.kt
Normal file
42
src/main/kotlin/net/moonleay/botendo/Main.kt
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo
|
||||
|
||||
import net.moonleay.botendo.util.Logger
|
||||
|
||||
|
||||
///Show the splash and launch the Bot
|
||||
suspend fun main(args: Array<String>) {
|
||||
println(
|
||||
"M#\"\"\"\"\"\"\"'M dP dP \n" +
|
||||
"## mmmm. `M 88 88 \n" +
|
||||
"#' .M .d8888b. d8888P .d8888b. 88d888b. .d888b88 .d8888b. \n" +
|
||||
"M# MMMb.'YM 88' `88 88 88ooood8 88' `88 88' `88 88' `88 \n" +
|
||||
"M# MMMM' M 88. .88 88 88. ... 88 88 88. .88 88. .88 \n" +
|
||||
"M# .;M `88888P' dP `88888P' dP dP `88888P8 `88888P' \n" +
|
||||
"M#########M \n" +
|
||||
" "
|
||||
)
|
||||
println("Bot v.${net.moonleay.botendo.build.BuildConstants.version}, Kord Extensions v.${net.moonleay.botendo.build.BuildConstants.kordVersion}, LavaKord v.${net.moonleay.botendo.build.BuildConstants.lavaVersion}, Coroutines v.${net.moonleay.botendo.build.BuildConstants.coroutinesVersion}")
|
||||
if(args.isEmpty() || args[0] != "--debug") {
|
||||
Logger.out("Waiting 10 seconds for Lavalink to start...")
|
||||
Thread.sleep(10000)
|
||||
}
|
||||
Bot.start()
|
||||
}
|
34
src/main/kotlin/net/moonleay/botendo/buttons/Button.kt
Normal file
34
src/main/kotlin/net/moonleay/botendo/buttons/Button.kt
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.buttons
|
||||
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
|
||||
open class Button(val id: String) {
|
||||
|
||||
open suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.buttons
|
||||
|
||||
import net.moonleay.botendo.buttons.music.*
|
||||
|
||||
object ButtonManager {
|
||||
val buttons = listOf(
|
||||
RepeatButton(),
|
||||
PauseButton(),
|
||||
SkipButton(),
|
||||
QueueButton(),
|
||||
StopButton()
|
||||
)
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.buttons.music
|
||||
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
import dev.kord.rest.builder.component.ActionRowBuilder
|
||||
import dev.kord.rest.builder.message.actionRow
|
||||
import dev.kord.rest.builder.message.embed
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
class PauseButton : net.moonleay.botendo.buttons.Button("btn.music.pause") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||
if (voiceState == null) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not connected to a VC"
|
||||
this.description = "Please connect to a VC"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val channelId = voiceState.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not connected"
|
||||
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not in my VC"
|
||||
this.description = "We are not in the same VC and therefore, you cannot control the music"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
player.pause(!player.paused)
|
||||
|
||||
val gts = MusicManager.getGuildTrackScheduler(guild, player)
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = if (player.paused) "I paused" else "I'm continuing"
|
||||
this.description = if (player.paused) "I paused the song" else "I'm continuing to play the song."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
|
||||
this.actionRow(fun ActionRowBuilder.() {
|
||||
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.buttons.music
|
||||
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
import dev.kord.rest.builder.component.ActionRowBuilder
|
||||
import dev.kord.rest.builder.message.actionRow
|
||||
import dev.kord.rest.builder.message.embed
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
import net.moonleay.botendo.util.TimeUtil
|
||||
|
||||
class QueueButton : net.moonleay.botendo.buttons.Button("btn.music.queue") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not connected"
|
||||
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (player.playingTrack == null) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not playing"
|
||||
this.description = "I'm not playing anything currently"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
val track = player.playingTrack!!.info
|
||||
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
|
||||
val q = gts.getQueue()
|
||||
var desc =
|
||||
"""${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length)} (${track.author})**""" + "\n"
|
||||
for ((i, tr) in q.withIndex()) {
|
||||
if (i >= 14)
|
||||
continue
|
||||
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
|
||||
}
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = "Queue"
|
||||
this.description = desc
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
|
||||
this.actionRow(fun ActionRowBuilder.() {
|
||||
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.buttons.music
|
||||
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
import dev.kord.rest.builder.component.ActionRowBuilder
|
||||
import dev.kord.rest.builder.message.actionRow
|
||||
import dev.kord.rest.builder.message.embed
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
class RepeatButton : net.moonleay.botendo.buttons.Button("btn.music.repeat") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||
if (voiceState == null) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not connected to a VC"
|
||||
this.description = "Please connect to a VC"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val channelId = voiceState.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not connected"
|
||||
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not in my VC"
|
||||
this.description = "We are not in the same VC and therefore, you cannot control the music"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val gts = MusicManager.getGuildTrackScheduler(guild, player)
|
||||
gts.repeating = !gts.repeating
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = if (gts.repeating) "Now Repeating" else "Now Continuing"
|
||||
this.description =
|
||||
if (gts.repeating) "The current track will now loop" else "The next track will play when this song finishes"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
|
||||
this.actionRow(fun ActionRowBuilder.() {
|
||||
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
150
src/main/kotlin/net/moonleay/botendo/buttons/music/SkipButton.kt
Normal file
150
src/main/kotlin/net/moonleay/botendo/buttons/music/SkipButton.kt
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.buttons.music
|
||||
|
||||
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
import dev.kord.rest.builder.component.ActionRowBuilder
|
||||
import dev.kord.rest.builder.message.actionRow
|
||||
import dev.kord.rest.builder.message.embed
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
import net.moonleay.botendo.util.TimeUtil
|
||||
import net.moonleay.botendo.util.UrlUtil
|
||||
|
||||
class SkipButton : net.moonleay.botendo.buttons.Button("btn.music.skip") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||
if (voiceState == null) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not connected to a VC"
|
||||
this.description = "Please connect to a VC"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val channelId = voiceState.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not connected"
|
||||
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not in my VC"
|
||||
this.description = "We are not in the same VC and therefore, you cannot control the music"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (player.playingTrack == null) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not Playing"
|
||||
this.description = "I'm not playing anything currently"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
var track = player.playingTrack!!.info
|
||||
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
|
||||
if (!gts.isEmpty()) {
|
||||
track = gts.getHead().info
|
||||
gts.playNext(link)
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = "Skipped song; now playing"
|
||||
this.description = "**${track.title}**\n*Now Playing*\nby ${track.author} :: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
track.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${track.uri}"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
this.thumbnail {
|
||||
this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
|
||||
}
|
||||
}
|
||||
|
||||
this.actionRow {
|
||||
this.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
player.stopTrack()
|
||||
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = "Skipped song"
|
||||
this.description = "Nothing"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
this.actionRow(fun ActionRowBuilder.() {
|
||||
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.buttons.music
|
||||
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteractionResponseBehavior
|
||||
import dev.kord.core.behavior.interaction.response.respond
|
||||
import dev.kord.core.entity.Guild
|
||||
import dev.kord.core.entity.User
|
||||
import dev.kord.rest.builder.message.embed
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
class StopButton : net.moonleay.botendo.buttons.Button("btn.music.stop") {
|
||||
override suspend fun onInteraction(
|
||||
response: DeferredPublicMessageInteractionResponseBehavior,
|
||||
guild: Guild,
|
||||
user: User
|
||||
) {
|
||||
val guildId = guild.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val voiceState = user.asMember(guildId).getVoiceStateOrNull()
|
||||
if (voiceState == null) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not connected to a VC"
|
||||
this.description = "Please connect to a VC"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val channelId = voiceState.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not connected"
|
||||
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not in my VC"
|
||||
this.description = "We are not in the same VC and therefore, you cannot control the music"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
player.stopTrack()
|
||||
link.destroy()
|
||||
MusicManager.getGuildTrackScheduler(guild.asGuild(), player).clear()
|
||||
response.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = "I stopped and left"
|
||||
this.description = "just like your girlfriend"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +1,22 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.data
|
||||
package net.moonleay.botendo.data
|
||||
|
||||
import java.io.*
|
||||
import java.util.*
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <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 dev.schlaubi.lavakord.kord.getLink
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
import net.moonleay.botendo.util.TimeUtil
|
||||
import net.moonleay.botendo.util.UrlUtil
|
||||
|
||||
class NowPlayingExtension : Extension() {
|
||||
override val name = "nowplaying"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "nowplaying"
|
||||
description = "Show what's currently playing"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
|
||||
val player = link.player
|
||||
val u = this.user
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not connected"
|
||||
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
val track = player.playingTrack
|
||||
if (track == null) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not Playing"
|
||||
this.description = "I'm not playing anything currently"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = "Currently playing"
|
||||
this.description = "**${track.info.title}**\n*Now Playing*\nby ${track.info.author} ; ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
player.position
|
||||
)
|
||||
}: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
track.info.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${track.info.uri}"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
if(track.info.uri == null){
|
||||
this.thumbnail {
|
||||
this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.info.uri!!) + "/maxresdefault.jpg"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.actionRow(fun ActionRowBuilder.() {
|
||||
components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <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.message.embed
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import dev.schlaubi.lavakord.kord.getLink
|
||||
import net.moonleay.botendo.Bot
|
||||
import net.moonleay.botendo.extensions.music.components.LinkArguments
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
import net.moonleay.botendo.util.UserUtil
|
||||
|
||||
|
||||
class PlayExtension : Extension() {
|
||||
|
||||
override val name = "play"
|
||||
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand(::LinkArguments) {
|
||||
name = "play"
|
||||
description = "Play music"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = Bot.lava.getLink(guildId)
|
||||
val u = this.user
|
||||
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
||||
if (vcsUser == null) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not connected to a VC"
|
||||
this.description = "Please connect to a VC"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
|
||||
val channelId = vcsUser.channelId
|
||||
|
||||
if (link.state != Link.State.CONNECTED) {
|
||||
link.connectAudio(channelId!!.value)
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not in my VC"
|
||||
this.description = "We are not in the same VC and therefore, you cannot play any music"
|
||||
this.author {
|
||||
this.name = UserUtil.getCommandSrc(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
|
||||
val query = arguments.linkquery
|
||||
val search = if (query.startsWith("http")) {
|
||||
query
|
||||
} else {
|
||||
"ytsearch:$query"
|
||||
}
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0A81A)
|
||||
this.title = "Searching..."
|
||||
this.description = "We are looking for $query"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
MusicManager.addToQueue(this, link, search)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.extensions.music
|
||||
|
||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.rest.builder.component.ActionRowBuilder
|
||||
import dev.kord.rest.builder.message.actionRow
|
||||
import dev.kord.rest.builder.message.embed
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
import net.moonleay.botendo.util.TimeUtil
|
||||
|
||||
class QueueExtension : Extension() {
|
||||
override val name = "queue"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "queue"
|
||||
description = "Show whats up next"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val u = this.user
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not connected"
|
||||
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
val track = player.playingTrack
|
||||
if (track == null) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Queue empty"
|
||||
this.description = "I'm not playing anything currently"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||
val q = gts.getQueue()
|
||||
var desc =
|
||||
"""${"**" + track.info.title + " - " + TimeUtil.getTimeFormatedShortend(track.info.length)} (${track.info.author})**""" + "\n"
|
||||
for ((i, tr) in q.withIndex()) {
|
||||
if (i >= 14)
|
||||
continue
|
||||
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
|
||||
}
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = "Queue"
|
||||
this.description = desc
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
|
||||
this.actionRow(fun ActionRowBuilder.() {
|
||||
components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <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.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
import net.moonleay.botendo.util.TimeUtil
|
||||
import net.moonleay.botendo.util.UrlUtil
|
||||
|
||||
class SkipExtension : Extension() {
|
||||
override val name = "skip"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "skip"
|
||||
description = "Skip to the next song in queue"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
|
||||
val player = link.player
|
||||
val u = this.user
|
||||
val voiceState = u.asMember(guildId).getVoiceStateOrNull()
|
||||
if (voiceState == null) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not connected to a VC"
|
||||
this.description = "Please connect to a VC"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
|
||||
val channelId = voiceState.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not connected"
|
||||
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not in my VC"
|
||||
this.description = "We are not in the same VC and therefore, you cannot control the music"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
var track = player.playingTrack!!.info
|
||||
if (track == null) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not playing"
|
||||
this.description = "I'm not playing anything currently"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
|
||||
if (!gts.isEmpty()) {
|
||||
track = gts.getHead().info
|
||||
gts.playNext(link)
|
||||
} else {
|
||||
player.stopTrack()
|
||||
}
|
||||
|
||||
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = "Skipped song; now playing"
|
||||
this.description = "**${track.title}**\n*Now Playing*\nby ${track.author} ;: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
track.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${track.uri}"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
this.thumbnail {
|
||||
this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
|
||||
}
|
||||
}
|
||||
|
||||
this.actionRow(fun ActionRowBuilder.() {
|
||||
components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <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.message.embed
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import dev.schlaubi.lavakord.kord.getLink
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
class StopExtension : Extension() {
|
||||
override val name = "stop"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "stop"
|
||||
description = "Stop playing and start leavin'"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
|
||||
val player = link.player
|
||||
val u = this.user
|
||||
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
||||
if (vcsUser == null) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not connected to a VC"
|
||||
this.description = "Please connect to a VC"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
val channelId = vcsUser.channelId
|
||||
if (link.state == Link.State.NOT_CONNECTED) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not connected"
|
||||
this.description = "I'm not in a VC and therefore, I am not playing anything."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not in my VC"
|
||||
this.description = "We are not in the same VC"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
player.stopTrack()
|
||||
link.destroy()
|
||||
MusicManager.getGuildTrackScheduler(this.getGuild()!!.asGuild(), player).clear()
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = "I stopped and left"
|
||||
this.description = "just like your girlfriend"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.extensions.music
|
||||
|
||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.rest.builder.message.embed
|
||||
import dev.schlaubi.lavakord.audio.Link
|
||||
import dev.schlaubi.lavakord.kord.getLink
|
||||
import net.moonleay.botendo.extensions.music.components.LinkArguments
|
||||
import net.moonleay.botendo.extensions.music.components.MusicManager
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
|
||||
class UpsertExtension : Extension() {
|
||||
|
||||
override val name = "upsert"
|
||||
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand(::LinkArguments) {
|
||||
name = "upsert"
|
||||
description = "Upsert music"
|
||||
this.action {
|
||||
val guildId = this.guild!!.id
|
||||
val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
|
||||
val u = this.user
|
||||
val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
|
||||
if (vcsUser == null) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not connected to a VC"
|
||||
this.description = "Please connect to a VC"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
|
||||
val channelId = vcsUser.channelId
|
||||
|
||||
if (link.state != Link.State.CONNECTED) {
|
||||
link.connectAudio(channelId!!.value)
|
||||
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "You are not in my VC"
|
||||
this.description = "We are not in the same VC and therefore, you cannot play any music"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@action
|
||||
}
|
||||
|
||||
val query = arguments.linkquery
|
||||
val search = if (query.startsWith("http")) {
|
||||
query
|
||||
} else {
|
||||
"ytsearch:$query"
|
||||
}
|
||||
this.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0A81A)
|
||||
this.title = "Searching..."
|
||||
this.description = "We are looking for $query"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
MusicManager.upsertIntoQueue(this, link, search)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.extensions.music.components
|
||||
|
||||
import dev.arbjerg.lavalink.protocol.v4.Track
|
||||
import dev.schlaubi.lavakord.audio.*
|
||||
import dev.schlaubi.lavakord.audio.player.Player
|
||||
import net.moonleay.botendo.Bot
|
||||
import net.moonleay.botendo.util.Logger
|
||||
import java.util.concurrent.BlockingQueue
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
|
||||
class GuildTrackScheduler(val pl: Player) {
|
||||
|
||||
private var queue: BlockingQueue<Track> = LinkedBlockingQueue()
|
||||
var repeating = false
|
||||
private var hasRegisteredEvents = false
|
||||
|
||||
///Add a track to queue and start playing, if there is no song currently playing
|
||||
suspend fun queue(track: Track, type: MusicManager.AddType) {
|
||||
if (this.pl.playingTrack == null) {
|
||||
play(track)
|
||||
return
|
||||
}
|
||||
when (type) {
|
||||
MusicManager.AddType.QUEUE -> {
|
||||
queue.offer(track)
|
||||
}
|
||||
|
||||
MusicManager.AddType.UPSERT -> {
|
||||
val nq = LinkedBlockingQueue<Track>()
|
||||
nq.offer(track)
|
||||
for (t in queue.toList()) {
|
||||
nq.offer(t)
|
||||
}
|
||||
queue = nq
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun playNext(link: Link) {
|
||||
if (!queue.isEmpty())
|
||||
this.pl.playTrack(track = queue.poll())
|
||||
else {
|
||||
this.pl.stopTrack()
|
||||
link.destroy()
|
||||
clear()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun play(track: Track) {
|
||||
this.pl.playTrack(track)
|
||||
}
|
||||
|
||||
fun addEvents() {
|
||||
if (hasRegisteredEvents)
|
||||
return
|
||||
hasRegisteredEvents = true
|
||||
|
||||
Logger.out("Adding track events to GuildTrackScheduler...")
|
||||
|
||||
pl.on<Event, TrackEndEvent> {
|
||||
onTrackEnd(this)
|
||||
}
|
||||
|
||||
pl.on<Event, TrackStuckEvent> {
|
||||
onTrackStuck(this)
|
||||
}
|
||||
|
||||
pl.on<Event, TrackExceptionEvent> {
|
||||
onTrackExc(this)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onTrackEnd(e: TrackEndEvent) {
|
||||
if (e.reason.mayStartNext) {
|
||||
if (repeating) {
|
||||
Logger.out("Repeating track...")
|
||||
this.pl.playTrack(e.track.copy())
|
||||
return
|
||||
}
|
||||
Logger.out("Track has ended; Playing next...")
|
||||
playNext(Bot.lava.getLink(e.guildId))
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onTrackStuck(e: TrackStuckEvent) {
|
||||
Logger.out("Track is stuck, retrying...")
|
||||
this.pl.playTrack(e.track.copy())
|
||||
}
|
||||
|
||||
private suspend fun onTrackExc(e: TrackExceptionEvent) {
|
||||
Logger.out("Track had an exception, retrying...")
|
||||
this.pl.playTrack(e.track.copy())
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
Logger.out("Clearing queue...")
|
||||
repeating = false
|
||||
queue.clear()
|
||||
}
|
||||
|
||||
fun getQueue(): List<Track> {
|
||||
return queue.toList()
|
||||
}
|
||||
|
||||
fun getHead(): Track {
|
||||
return queue.first()
|
||||
}
|
||||
|
||||
fun isEmpty(): Boolean {
|
||||
return queue.isEmpty()
|
||||
}
|
||||
}
|
||||
|
|
@ -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 LinkArguments : Arguments() {
|
||||
val linkquery by string {
|
||||
name = "linkqery"
|
||||
description = "Song link or search query"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.extensions.music.components
|
||||
|
||||
import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext
|
||||
import com.kotlindiscord.kord.extensions.components.forms.ModalForm
|
||||
import dev.arbjerg.lavalink.protocol.v4.LoadResult
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.common.entity.Snowflake
|
||||
import dev.kord.core.entity.Guild
|
||||
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.player.Player
|
||||
import dev.schlaubi.lavakord.rest.loadItem
|
||||
import net.moonleay.botendo.util.ButtonUtil
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
import net.moonleay.botendo.util.TimeUtil
|
||||
import net.moonleay.botendo.util.UrlUtil
|
||||
|
||||
object MusicManager {
|
||||
private var musicManagerMap: MutableMap<Snowflake, GuildTrackScheduler> = mutableMapOf()
|
||||
|
||||
fun getMusicManager(guild: Guild): GuildTrackScheduler? {
|
||||
return musicManagerMap[guild.id]
|
||||
}
|
||||
|
||||
fun getGuildTrackScheduler(guild: Guild, player: Player): GuildTrackScheduler {
|
||||
return musicManagerMap.computeIfAbsent(guild.id) {
|
||||
GuildTrackScheduler(player)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
suspend fun addToQueue(
|
||||
ctx: PublicSlashCommandContext<LinkArguments, ModalForm>,
|
||||
link: Link,
|
||||
search: String
|
||||
) {
|
||||
addToQueue(ctx, link, search, AddType.QUEUE, false)
|
||||
}
|
||||
|
||||
suspend fun upsertIntoQueue(
|
||||
ctx: PublicSlashCommandContext<LinkArguments, ModalForm>,
|
||||
link: Link,
|
||||
search: String
|
||||
) {
|
||||
addToQueue(ctx, link, search, AddType.UPSERT, false)
|
||||
}
|
||||
|
||||
suspend fun addToQueue(
|
||||
ctx: PublicSlashCommandContext<LinkArguments, ModalForm>,
|
||||
link: Link,
|
||||
search: String,
|
||||
type: AddType,
|
||||
silent: Boolean
|
||||
) {
|
||||
val player = link.player
|
||||
val gts = getGuildTrackScheduler(ctx.guild!!.asGuild(), player)
|
||||
val u = ctx.user.asUser()
|
||||
gts.addEvents()
|
||||
|
||||
when (val itm = link.loadItem(search)) {
|
||||
is LoadResult.TrackLoaded -> {
|
||||
gts.queue(itm.data, type)
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = "${type.s} track from link"
|
||||
this.description = "**${itm.data.info.title}**\n*Queue*\nby ${itm.data.info.author} ;: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
itm.data.info.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${itm.data.info.uri}"
|
||||
this.footer {
|
||||
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(fun ActionRowBuilder.() {
|
||||
components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
is LoadResult.PlaylistLoaded -> {
|
||||
player.playTrack(track = itm.data.tracks.first())
|
||||
val l= itm.data.tracks.toList().reversed()
|
||||
for (partialTrack in l) {
|
||||
gts.queue(partialTrack, type)
|
||||
}
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = "${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} ;: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
itm.data.tracks.first().info.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${itm.data.tracks.first().info.uri}"
|
||||
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.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
is LoadResult.SearchResult -> {
|
||||
gts.queue(itm.data.tracks.first(), type)
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embed {
|
||||
this.color = Color(0x52E01A)
|
||||
this.title = "${type.s} track from query"
|
||||
this.description = "**${itm.data.tracks.first().info.title}**\n*Queue*\nby ${itm.data.tracks.first().info.author} ;: ${
|
||||
TimeUtil.getTimeFormatedRaw(
|
||||
itm.data.tracks.first().info.length
|
||||
)
|
||||
}\n" +
|
||||
">>>${itm.data.tracks.first().info.uri}"
|
||||
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.components.addAll(
|
||||
ButtonUtil.getMusicControllerButtons(
|
||||
player.paused,
|
||||
gts.repeating
|
||||
).components
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
is LoadResult.NoMatches -> {
|
||||
if (gts.isEmpty() && player.playingTrack == null) {
|
||||
player.stopTrack()
|
||||
link.destroy()
|
||||
}
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Not found"
|
||||
this.description = "There were no matches."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is LoadResult.LoadFailed -> {
|
||||
if (gts.isEmpty() && player.playingTrack == null) {
|
||||
player.stopTrack()
|
||||
link.destroy()
|
||||
}
|
||||
if (!silent)
|
||||
ctx.respond {
|
||||
this.embed {
|
||||
this.color = Color(0xE0311A)
|
||||
this.title = "Load failed"
|
||||
this.description = "There was an error while loading."
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
enum class AddType(val s: String) {
|
||||
QUEUE("Added"),
|
||||
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\""
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.extensions.util
|
||||
|
||||
import com.kotlindiscord.kord.extensions.extensions.Extension
|
||||
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
|
||||
import dev.kord.common.Color
|
||||
import dev.kord.rest.builder.message.embed
|
||||
import net.moonleay.botendo.util.MessageUtil
|
||||
|
||||
class InfoExtension : Extension() {
|
||||
override val name = "info"
|
||||
override suspend fun setup() {
|
||||
publicSlashCommand {
|
||||
name = "info"
|
||||
description = "Show infos about the bot"
|
||||
this.action {
|
||||
val u = this.user
|
||||
this.respond {
|
||||
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" +
|
||||
"lavalink.kt ***v." + net.moonleay.botendo.build.BuildConstants.lavaVersion + "***\n" +
|
||||
"Coroutines ***v." + net.moonleay.botendo.build.BuildConstants.coroutinesVersion + "***\n\n\n" +
|
||||
"***Bot made by moonleay***\n" +
|
||||
"(c) 2023, licensed under GPL-3.0\n" +
|
||||
"More infos: https://moonleay.net/projects/botendo\n"
|
||||
this.footer {
|
||||
this.text = MessageUtil.getFooter(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +1,22 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.util
|
||||
package net.moonleay.botendo.util
|
||||
|
||||
import dev.kord.common.entity.ButtonStyle
|
||||
import dev.kord.rest.builder.component.ActionRowBuilder
|
41
src/main/kotlin/net/moonleay/botendo/util/Logger.kt
Normal file
41
src/main/kotlin/net/moonleay/botendo/util/Logger.kt
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.util
|
||||
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
object Logger {
|
||||
private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("yy/MM/dd HH:mm:ss")
|
||||
|
||||
fun out(msg: String) {
|
||||
val caller = Thread.currentThread().stackTrace[2]
|
||||
val now: LocalDateTime = LocalDateTime.now()
|
||||
try {
|
||||
println(
|
||||
("[" + Class.forName(caller.className).simpleName + "." +
|
||||
caller.methodName + ":" + caller.lineNumber + "] [" + dtf.format(now)) + "] <" + msg + ">"
|
||||
)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// Ich kann nicht mehr
|
||||
// [Class.function] [T/M HH:MM] <MESSAGE>
|
||||
}
|
||||
}
|
32
src/main/kotlin/net/moonleay/botendo/util/MessageUtil.kt
Normal file
32
src/main/kotlin/net/moonleay/botendo/util/MessageUtil.kt
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.util
|
||||
|
||||
import dev.kord.core.behavior.UserBehavior
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
object MessageUtil {
|
||||
private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss")
|
||||
|
||||
suspend fun getFooter(u: UserBehavior? = null): String{
|
||||
val now: LocalDateTime = LocalDateTime.now()
|
||||
return ">" + dtf.format(now) + " - ${u?.asUser()?.username?:"Automatic Message"}"
|
||||
}
|
||||
}
|
29
src/main/kotlin/net/moonleay/botendo/util/Status.kt
Normal file
29
src/main/kotlin/net/moonleay/botendo/util/Status.kt
Normal file
|
@ -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.util
|
||||
|
||||
object Status {
|
||||
//TODO: impl.
|
||||
suspend fun updateStatus() {
|
||||
/* Bot.kord.editPresence {
|
||||
this.playing("")
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
114
src/main/kotlin/net/moonleay/botendo/util/TimeUtil.kt
Normal file
114
src/main/kotlin/net/moonleay/botendo/util/TimeUtil.kt
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.util
|
||||
|
||||
import java.time.Duration
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object TimeUtil {
|
||||
///Convert Miliseconds to xdays xhours xmins xsecs
|
||||
fun getTimeFormatedShortend(timeIn: Long): String {
|
||||
var time = timeIn
|
||||
val days = TimeUnit.MILLISECONDS
|
||||
.toDays(time)
|
||||
time -= TimeUnit.DAYS.toMillis(days)
|
||||
val hours = TimeUnit.MILLISECONDS
|
||||
.toHours(time)
|
||||
time -= TimeUnit.HOURS.toMillis(hours)
|
||||
val minutes = TimeUnit.MILLISECONDS
|
||||
.toMinutes(time)
|
||||
time -= TimeUnit.MINUTES.toMillis(minutes)
|
||||
val seconds = TimeUnit.MILLISECONDS
|
||||
.toSeconds(time)
|
||||
var s = ""
|
||||
if (days >= 1) {
|
||||
s += days.toString() + "d "
|
||||
}
|
||||
if (hours >= 1) {
|
||||
s += hours.toString() + "h "
|
||||
}
|
||||
if (minutes >= 1) {
|
||||
s += minutes.toString() + "m "
|
||||
}
|
||||
if (seconds >= 1 && hours < 1) {
|
||||
s += seconds.toString() + "s"
|
||||
}
|
||||
if (s.isEmpty() || s.isBlank()) {
|
||||
s = "0s"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
fun getTimeFormatedRaw(timeIn: Long): String {
|
||||
var time = timeIn
|
||||
val days = TimeUnit.MILLISECONDS
|
||||
.toDays(time)
|
||||
time -= TimeUnit.DAYS.toMillis(days)
|
||||
val hours = TimeUnit.MILLISECONDS
|
||||
.toHours(time)
|
||||
time -= TimeUnit.HOURS.toMillis(hours)
|
||||
val minutes = TimeUnit.MILLISECONDS
|
||||
.toMinutes(time)
|
||||
time -= TimeUnit.MINUTES.toMillis(minutes)
|
||||
val seconds = TimeUnit.MILLISECONDS
|
||||
.toSeconds(time)
|
||||
var s = ""
|
||||
if (days >= 1) {
|
||||
s += days.toString() + "d "
|
||||
}
|
||||
if (hours >= 1) {
|
||||
s += hours.toString() + "h "
|
||||
}
|
||||
if (minutes >= 1) {
|
||||
s += minutes.toString() + "m "
|
||||
}
|
||||
if (seconds >= 1) {
|
||||
s += seconds.toString() + "s"
|
||||
}
|
||||
if (s.isEmpty() || s.isBlank()) {
|
||||
s = "0s"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
//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
|
||||
}
|
||||
|
||||
}
|
26
src/main/kotlin/net/moonleay/botendo/util/UrlUtil.kt
Normal file
26
src/main/kotlin/net/moonleay/botendo/util/UrlUtil.kt
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.util
|
||||
|
||||
object UrlUtil {
|
||||
///Strip the video ID from a YouTube link
|
||||
fun getYtThumbnailUrl(uri: String): String {
|
||||
return uri.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
|
||||
}
|
||||
}
|
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}}"
|
||||
}
|
||||
}
|
|
@ -1,18 +1,17 @@
|
|||
#
|
||||
# Botendo
|
||||
# Copyright (C) 2023 limited_dev
|
||||
# Botendo
|
||||
# Copyright (C) 2023 moonleay
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# 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/>.
|
||||
#
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 limited_dev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.limited_dev.botendo.build
|
||||
|
||||
internal object BuildConstants {
|
||||
const val version = "${version}"
|
||||
const val ownerID = "${ownerID}"
|
||||
const val kordVersion = "${kordversion}"
|
||||
const val lavaVersion = "${lavaversion}"
|
||||
const val coroutinesVersion = "${coroutinesversion}"
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Botendo
|
||||
* Copyright (C) 2023 moonleay
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.moonleay.botendo.build
|
||||
|
||||
internal object BuildConstants {
|
||||
const val version = "${version}"
|
||||
const val ownerID = "${ownerID}"
|
||||
const val kordVersion = "${kordversion}"
|
||||
const val lavaVersion = "${lavaversion}"
|
||||
const val coroutinesVersion = "${coroutinesversion}"
|
||||
}
|
Loading…
Add table
Reference in a new issue