Compare commits

...

34 commits

Author SHA1 Message Date
8cc3e70f24
chore: improved readability
Signed-off-by: moonleay <contact@moonleay.net>
2023-12-14 09:05:27 +01:00
1dec02f40f
chore: upgrade gradle to 8.5
Signed-off-by: moonleay <contact@moonleay.net>
2023-12-13 19:11:28 +01:00
e3d107199e
chore: update Copyright
Signed-off-by: moonleay <contact@moonleay.net>
2023-12-13 19:08:08 +01:00
425c9bf1cd
chore: bump version
Signed-off-by: moonleay <contact@moonleay.net>
2023-12-13 19:02:38 +01:00
3d66548a3d
fix: bot now doesn't leave when failing to find a song with no song in queue and one playing
Signed-off-by: moonleay <contact@moonleay.net>
2023-12-13 19:02:12 +01:00
9b51693a75
feat: make the bot leave, if they are the last one in the vc
Signed-off-by: moonleay <contact@moonleay.net>
2023-12-13 18:52:46 +01:00
8b6b7dc5d5
feat: leave vc, if there is no song next up and the current one failed to load 2023-12-13 18:50:38 +01:00
ae507dc4aa
feat: added time delay to allow for lavalink to start in docker container, added debug flag to skip the wait, if in dev env 2023-12-13 18:19:32 +01:00
232a854863
chore: add new command to README 2023-12-13 18:06:14 +01:00
a7bafe5a7e
fix: bumped version to fit docker releases 2023-12-13 18:03:41 +01:00
aa81261dd9
chore: bump version 2023-12-13 16:50:00 +01:00
acefe1b712 Merge pull request 'chore/upgrade-lavakord' (#7) from chore/upgrade-lavakord into master
Reviewed-on: #7
2023-12-13 16:48:39 +01:00
fab645d945
chore: improved build.gradle.kts dependency version naming 2023-12-13 16:47:26 +01:00
6cc91f0cfe
chore: bump slf4j version 2023-12-13 16:43:52 +01:00
6c83ea6b4c
fix: fixed errors caused by upgrading lavalink 2023-12-13 16:41:52 +01:00
e1fdc954ce
WIP: started working on fixing errors 2023-12-13 15:15:29 +01:00
a2ce58010a
chore: bump lavakord version 2023-12-13 15:15:13 +01:00
589997c29e
chore: updated .gitignore, updated README.md 2023-12-13 14:39:19 +01:00
55ccb175e1
chore: upgrade kord-extensions, rewrote all embeds
fix: fixed issues caused due to upgrade
2023-12-13 14:39:01 +01:00
3a9795794c chore: bump version
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-07-24 00:29:48 +02:00
5a65aad3e2 fix: fixed InfoExtension
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-07-24 00:29:30 +02:00
1cbf631f27 chore: updated command source system
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-07-24 00:18:41 +02:00
f94d6c6ae7 feat: added UserUtil
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-07-24 00:18:18 +02:00
b59b72b3b8 fix: fixed typo in SkipExtension
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-07-23 23:49:19 +02:00
266da050d2 chore: bump version
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-07-23 23:48:20 +02:00
cccd602a94 chore: updated InfoExtension output
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-07-23 23:45:37 +02:00
26137e8806 feat: added SeekExtension to extensions
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-07-23 23:44:01 +02:00
aabab047f7 feat: added SeekExtension
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-07-23 23:43:47 +02:00
d8f8231028 feat: added SeekArguments
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-07-23 23:43:40 +02:00
47f92a0765 feat: added getTimeUnformated function to TimeUtil
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-07-23 23:43:25 +02:00
ee6b31a868 Merge remote-tracking branch 'origin/master' 2023-05-21 15:25:13 +02:00
c087a484a4 chore: update README.md
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-05-21 15:25:00 +02:00
142f60ec71 chore: update README.md
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-05-21 15:24:07 +02:00
2e309dfc52 chore: updated owner tag to 0001
Signed-off-by: limited_dev <loginakkisativ@gmail.com>
2023-05-19 15:46:02 +02:00
39 changed files with 950 additions and 652 deletions

2
.gitignore vendored
View file

@ -1,5 +1,7 @@
### CUSTOM ### ### CUSTOM ###
/run/ /run/
/data/
data/
/.idea/ /.idea/

View file

@ -4,23 +4,17 @@
A Discord music bot, written in Kotlin using the kord library. A Discord music bot, written in Kotlin using the kord library.
[![Latest Release](https://gitlab.com/moonleay/botendo/-/badges/release.svg)](https://gitlab.com/moonleay/botendo/-/releases)
[![pipeline status](https://gitlab.com/moonleay/botendo/badges/master/pipeline.svg)](https://gitlab.com/moonleay/botendo/-/commits/master)
[![coverage report](https://gitlab.com/moonleay/botendo/badges/master/coverage.svg)](https://gitlab.com/moonleay/botendo/-/commits/master)
## Contributors ## Contributors
<div class="aside"> [![Developer](https://img.shields.io/badge/moonleay-Developer-red)](https://gitlab.com/moonleay)
<img src="https://img.shields.io/badge/moonleay-Head%20Developer-red" alt="moonleay: Head Developer"/>
</div>
## Special Thanks to ## Special Thanks to
- HopeBaron for helping me a lot - HopeBaron for helping me a lot
## Known issues ## Issues
- None (currently). Report issues to issues@moonleay.net or moonleay#0069 - Report issues to issues@moonleay.net or message @moonleay on Discord
## Commands & Features ## Commands & Features
@ -32,6 +26,7 @@ A Discord music bot, written in Kotlin using the kord library.
- skip -- Skip to the next song - skip -- Skip to the next song
- queue -- Show what songs are next up - queue -- Show what songs are next up
- nowplaying -- Show what is currently playing - nowplaying -- Show what is currently playing
- seek -- Seek to a specific time in the song
- Features - Features
- Button Controller -- You can control the currently playing music using buttons. - Button Controller -- You can control the currently playing music using buttons.
@ -65,9 +60,3 @@ A Discord music bot, written in Kotlin using the kord library.
Install IntellJ and import the project from git. Install IntellJ and import the project from git.
Done. Done.
## Docker commands 4 me
- docker run -it -m 2g -v/home/limited_dev/Documents/Code/Botendo/run/data/:/data/:rw limiteddev/botendo:x.x.x
- docker build -t limiteddev/botendo:x.x.x .
- docker push limiteddev/botendo:x.x.x

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
import org.jetbrains.gradle.ext.ProjectSettings import org.jetbrains.gradle.ext.ProjectSettings
@ -33,11 +32,12 @@ val ownerID = 372703841151614976L
group = "net.moonleay.botendo" group = "net.moonleay.botendo"
version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_SHORT_SHA")}-prod" } version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_SHORT_SHA")}-prod" }
?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" } ?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" }
?: "6.4.0" ?: "6.5.5"
val kordver = "1.5.6" val kordext_ver = "1.7.1-SNAPSHOT"
val lavaver = "4.0.0" val lavakord_ver = "6.0.0"
val coroutinesver = "1.1.0" val coroutines_ver = "1.7.3"
val slf4j_ver = "2.0.9"
val mavenArtifact = "Botendo" val mavenArtifact = "Botendo"
project.base.archivesName.set(mavenArtifact) project.base.archivesName.set(mavenArtifact)
@ -70,6 +70,14 @@ repositories {
} }
} }
} }
maven {
name = "sonatype"
url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots")
}
maven {
name = "sonatype 2"
url = uri("https://oss.sonatype.org/content/repositories/snapshots")
}
} }
val shadow by configurations.getting val shadow by configurations.getting
@ -78,15 +86,15 @@ implementation.extendsFrom(shadow)
dependencies { dependencies {
//Discord //Discord
shadow("com.kotlindiscord.kord.extensions:kord-extensions:$kordver") shadow("com.kotlindiscord.kord.extensions:kord-extensions:$kordext_ver")
shadow("dev.schlaubi.lavakord:kord:$lavaver") shadow("dev.schlaubi.lavakord:kord:$lavakord_ver")
//Util //Util
shadow("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesver") shadow("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_ver")
//Logging //Logging
shadow("org.slf4j:slf4j-api:2.0.3") shadow("org.slf4j:slf4j-api:$slf4j_ver")
shadow("org.slf4j:slf4j-simple:2.0.3") shadow("org.slf4j:slf4j-simple:$slf4j_ver")
} }
@ -96,9 +104,9 @@ val templateDest = project.buildDir.resolve("generated/templates")
val templateProps = mapOf( val templateProps = mapOf(
"version" to project.version as String, "version" to project.version as String,
"ownerID" to ownerID, "ownerID" to ownerID,
"kordversion" to kordver, "kordversion" to kordext_ver,
"lavaversion" to lavaver, "lavaversion" to lavakord_ver,
"coroutinesversion" to coroutinesver "coroutinesversion" to coroutines_ver
) )

View file

@ -15,5 +15,4 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# #
#
kotlin.code.style=official kotlin.code.style=official

Binary file not shown.

View file

@ -15,9 +15,11 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# #
#
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

42
gradlew vendored
View file

@ -17,7 +17,6 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# #
#
############################################################################## ##############################################################################
# #
@ -58,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -83,13 +82,11 @@ do
esac esac
done done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # This is normally unused
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -136,22 +133,29 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -196,11 +200,15 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
# shell script including quotes and variable substitutions, so put them in DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded. # Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
@ -208,6 +216,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \ org.gradle.wrapper.GradleWrapperMain \
"$@" "$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args. # Use "xargs" to parse quoted args.
# #
# With -n1 it outputs one arg per line, with the quotes and backslashes removed. # With -n1 it outputs one arg per line, with the quotes and backslashes removed.

15
gradlew.bat vendored
View file

@ -14,7 +14,7 @@
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if %ERRORLEVEL% equ 0 goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 set EXIT_CODE=%ERRORLEVEL%
exit /b 1 if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal

View file

@ -1,20 +1,19 @@
/* /*
* Botendo * Botendo
* Copyright (C) 2023 limited_dev * Copyright (C) 2023 moonleay
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
rootProject.name = "Botendo" rootProject.name = "Botendo"

View file

@ -14,20 +14,28 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo package net.moonleay.botendo
import com.kotlindiscord.kord.extensions.ExtensibleBot import com.kotlindiscord.kord.extensions.ExtensibleBot
import dev.kord.common.Color import dev.kord.common.Color
import dev.kord.common.entity.Snowflake
import dev.kord.core.behavior.getChannelOf
import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.channel.VoiceChannel
import dev.kord.core.event.interaction.ButtonInteractionCreateEvent import dev.kord.core.event.interaction.ButtonInteractionCreateEvent
import dev.kord.core.event.user.VoiceStateUpdateEvent
import dev.kord.core.on import dev.kord.core.on
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.LavaKord import dev.schlaubi.lavakord.LavaKord
import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.kord.getLink
import dev.schlaubi.lavakord.kord.lavakord import dev.schlaubi.lavakord.kord.lavakord
import kotlinx.coroutines.flow.count
import net.moonleay.botendo.data.CredentialManager import net.moonleay.botendo.data.CredentialManager
import net.moonleay.botendo.extensions.music.* import net.moonleay.botendo.extensions.music.*
import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.extensions.util.InfoExtension import net.moonleay.botendo.extensions.util.InfoExtension
import net.moonleay.botendo.util.Logger import net.moonleay.botendo.util.Logger
import net.moonleay.botendo.util.MessageUtil import net.moonleay.botendo.util.MessageUtil
@ -63,10 +71,11 @@ object Bot {
add(::NowPlayingExtension) add(::NowPlayingExtension)
add(::QueueExtension) add(::QueueExtension)
add(::UpsertExtension) add(::UpsertExtension)
add(::SeekExtension)
} }
this.presence { this.presence {
this.streaming("music", "https://twitch.tv/limited_dev") this.streaming("music", "https://twitch.tv/moonleaytv")
} }
} }
@ -88,18 +97,47 @@ object Bot {
b.onInteraction(response, g, u) b.onInteraction(response, g, u)
return@on return@on
} }
// Button not found
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "Error"
"Error", this.description = "Could not find button with id \"${inter.componentId}\".\nPlease report this."
"Could not find button with id \"${inter.componentId}\".\nPlease report this.", this.footer {
u.asUser().username + "#" + u.asUser().discriminator this.text = MessageUtil.getFooter(u)
) }
) }
} }
} }
// Allow the bot to leave the VC if there are no users in the VC
bot.kordRef.on<VoiceStateUpdateEvent> {
if (this.state.userId == bot.kordRef.selfId) {
// Ignore self
return@on
}
val g = this.state.getGuild().asGuild()
val link = lava.getLink(g.id)
if (link.state != Link.State.CONNECTED) {
// Ignore if not connected
return@on
}
val myChannel = link.lastChannelId!!
if (g.getChannelOrNull(Snowflake(myChannel)) == null) {
// Ignore if channel cannot be found
return@on
}
val ch = g.getChannelOf<VoiceChannel>(Snowflake(myChannel))
if (ch.voiceStates.count() > 1) {
// Ignore if there are other users in the channel
return@on
}
// Stop playing if there are no users in the channel
val pl = MusicManager.getMusicManager(g)!!.pl
pl.stopTrack()
link.destroy()
}
//Start the bot //Start the bot
bot.start() bot.start()
} }

View file

@ -14,14 +14,15 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo package net.moonleay.botendo
import net.moonleay.botendo.util.Logger
///Show the splash and launch the Bot ///Show the splash and launch the Bot
suspend fun main() { suspend fun main(args: Array<String>) {
println( println(
"M#\"\"\"\"\"\"\"'M dP dP \n" + "M#\"\"\"\"\"\"\"'M dP dP \n" +
"## mmmm. `M 88 88 \n" + "## mmmm. `M 88 88 \n" +
@ -33,5 +34,9 @@ suspend fun main() {
" " " "
) )
println("Bot v.${net.moonleay.botendo.build.BuildConstants.version}, Kord Extensions v.${net.moonleay.botendo.build.BuildConstants.kordVersion}, LavaKord v.${net.moonleay.botendo.build.BuildConstants.lavaVersion}, Coroutines v.${net.moonleay.botendo.build.BuildConstants.coroutinesVersion}") println("Bot v.${net.moonleay.botendo.build.BuildConstants.version}, Kord Extensions v.${net.moonleay.botendo.build.BuildConstants.kordVersion}, LavaKord v.${net.moonleay.botendo.build.BuildConstants.lavaVersion}, Coroutines v.${net.moonleay.botendo.build.BuildConstants.coroutinesVersion}")
if(args.isEmpty() || args[0] != "--debug") {
Logger.out("Waiting 10 seconds for Lavalink to start...")
Thread.sleep(10000)
}
Bot.start() Bot.start()
} }

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.buttons package net.moonleay.botendo.buttons

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.buttons package net.moonleay.botendo.buttons

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.buttons.music package net.moonleay.botendo.buttons.music
@ -24,7 +23,9 @@ import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteract
import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.Guild import dev.kord.core.entity.Guild
import dev.kord.core.entity.User import dev.kord.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow import dev.kord.rest.builder.component.ActionRowBuilder
import dev.kord.rest.builder.message.actionRow
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import net.moonleay.botendo.extensions.music.components.MusicManager import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil import net.moonleay.botendo.util.ButtonUtil
@ -42,14 +43,14 @@ class PauseButton : net.moonleay.botendo.buttons.Button("btn.music.pause") {
val voiceState = user.asMember(guildId).getVoiceStateOrNull() val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) { if (voiceState == null) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not connected to a VC"
"You are not connected to a VC", this.description = "Please connect to a VC"
"Please connect to a VC", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} }
@ -57,26 +58,26 @@ class PauseButton : net.moonleay.botendo.buttons.Button("btn.music.pause") {
val channelId = voiceState.channelId val channelId = voiceState.channelId
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "Not connected"
"Not connected", this.description = "I'm not in a VC and therefore, I am not playing anything."
"I'm not in a VC and therefore, I am not playing anything.", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not in my VC"
"You are not in my VC", this.description = "We are not in the same VC and therefore, you cannot control the music"
"We are not in the same VC and therefore, you cannot control the music", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} }
@ -85,19 +86,18 @@ class PauseButton : net.moonleay.botendo.buttons.Button("btn.music.pause") {
val gts = MusicManager.getGuildTrackScheduler(guild, player) val gts = MusicManager.getGuildTrackScheduler(guild, player)
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = if (player.paused) "I paused" else "I'm continuing"
if (player.paused) "I paused" else "I'm continuing", this.description = if (player.paused) "I paused the song" else "I'm continuing to play the song."
if (player.paused) "I paused the song" else "I'm continuing to play the song.", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
)
this.actionRow {
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
} }
this.actionRow(fun ActionRowBuilder.() {
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
})
} }
} }
} }

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.buttons.music package net.moonleay.botendo.buttons.music
@ -24,7 +23,9 @@ import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteract
import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.Guild import dev.kord.core.entity.Guild
import dev.kord.core.entity.User import dev.kord.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow import dev.kord.rest.builder.component.ActionRowBuilder
import dev.kord.rest.builder.message.actionRow
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import net.moonleay.botendo.extensions.music.components.MusicManager import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil import net.moonleay.botendo.util.ButtonUtil
@ -42,53 +43,54 @@ class QueueButton : net.moonleay.botendo.buttons.Button("btn.music.queue") {
val player = link.player val player = link.player
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "Not connected"
"Not connected", this.description = "I'm not in a VC and therefore, I am not playing anything."
"I'm not in a VC and therefore, I am not playing anything.", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} }
val track = player.playingTrack if (player.playingTrack == null) {
if (track == null) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "Not playing"
"Not playing", this.description = "I'm not playing anything currently"
"I'm not playing anything currently", user.asUser().username + "#" + user.asUser().discriminator this.footer {
) this.text = MessageUtil.getFooter(user)
) }
}
} }
return return
} }
val track = player.playingTrack!!.info
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player) val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
val q = gts.getQueue() val q = gts.getQueue()
var desc = var desc =
"""${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length.inWholeMilliseconds)} (${track.author})**""" + "\n" """${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length)} (${track.author})**""" + "\n"
for ((i, tr) in q.withIndex()) { for ((i, tr) in q.withIndex()) {
if (i >= 14) if (i >= 14)
continue continue
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n" desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
} }
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = "Queue"
"Queue", this.description = desc
desc, this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
)
this.actionRow {
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
} }
this.actionRow(fun ActionRowBuilder.() {
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
})
} }
} }
} }

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.buttons.music package net.moonleay.botendo.buttons.music
@ -24,7 +23,9 @@ import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteract
import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.Guild import dev.kord.core.entity.Guild
import dev.kord.core.entity.User import dev.kord.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow import dev.kord.rest.builder.component.ActionRowBuilder
import dev.kord.rest.builder.message.actionRow
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import net.moonleay.botendo.extensions.music.components.MusicManager import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil import net.moonleay.botendo.util.ButtonUtil
@ -42,14 +43,14 @@ class RepeatButton : net.moonleay.botendo.buttons.Button("btn.music.repeat") {
val voiceState = user.asMember(guildId).getVoiceStateOrNull() val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) { if (voiceState == null) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not connected to a VC"
"You are not connected to a VC", this.description = "Please connect to a VC"
"Please connect to a VC", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} }
@ -57,26 +58,26 @@ class RepeatButton : net.moonleay.botendo.buttons.Button("btn.music.repeat") {
val channelId = voiceState.channelId val channelId = voiceState.channelId
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "Not connected"
"Not connected", this.description = "I'm not in a VC and therefore, I am not playing anything."
"I'm not in a VC and therefore, I am not playing anything.", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not in my VC"
"You are not in my VC", this.description = "We are not in the same VC and therefore, you cannot control the music"
"We are not in the same VC and therefore, you cannot control the music", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} }
@ -84,19 +85,19 @@ class RepeatButton : net.moonleay.botendo.buttons.Button("btn.music.repeat") {
val gts = MusicManager.getGuildTrackScheduler(guild, player) val gts = MusicManager.getGuildTrackScheduler(guild, player)
gts.repeating = !gts.repeating gts.repeating = !gts.repeating
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = if (gts.repeating) "Now Repeating" else "Now Continuing"
if (gts.repeating) "Now Repeating" else "Now Continuing", this.description =
if (gts.repeating) "The current track will now loop" else "The next track will play when this song finishes", if (gts.repeating) "The current track will now loop" else "The next track will play when this song finishes"
user.asUser().username + "#" + user.asUser().discriminator this.footer {
) this.text = MessageUtil.getFooter(user)
) }
this.actionRow {
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
} }
this.actionRow(fun ActionRowBuilder.() {
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
})
} }
} }
} }

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.buttons.music package net.moonleay.botendo.buttons.music
@ -25,7 +24,9 @@ import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteract
import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.Guild import dev.kord.core.entity.Guild
import dev.kord.core.entity.User import dev.kord.core.entity.User
import dev.kord.rest.builder.message.modify.actionRow import dev.kord.rest.builder.component.ActionRowBuilder
import dev.kord.rest.builder.message.actionRow
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import net.moonleay.botendo.extensions.music.components.MusicManager import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil import net.moonleay.botendo.util.ButtonUtil
@ -45,14 +46,14 @@ class SkipButton : net.moonleay.botendo.buttons.Button("btn.music.skip") {
val voiceState = user.asMember(guildId).getVoiceStateOrNull() val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) { if (voiceState == null) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not connected to a VC"
"You are not connected to a VC", this.description = "Please connect to a VC"
"Please connect to a VC", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} }
@ -60,61 +61,64 @@ class SkipButton : net.moonleay.botendo.buttons.Button("btn.music.skip") {
val channelId = voiceState.channelId val channelId = voiceState.channelId
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "Not connected"
"Not connected", this.description = "I'm not in a VC and therefore, I am not playing anything."
"I'm not in a VC and therefore, I am not playing anything.", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not in my VC"
"You are not in my VC", this.description = "We are not in the same VC and therefore, you cannot control the music"
"We are not in the same VC and therefore, you cannot control the music", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} }
var track = player.playingTrack if (player.playingTrack == null) {
if (track == null) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "Not Playing"
"Not playing", this.description = "I'm not playing anything currently"
"I'm not playing anything currently", user.asUser().username + "#" + user.asUser().discriminator this.footer {
) this.text = MessageUtil.getFooter(user)
) }
}
} }
return return
} }
var track = player.playingTrack!!.info
val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player) val gts = MusicManager.getGuildTrackScheduler(guild.asGuild(), player)
if (!gts.isEmpty()) { if (!gts.isEmpty()) {
track = gts.getHead().toTrack() track = gts.getHead().info
gts.playNext(link) gts.playNext(link)
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbedWithImage( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = "Skipped song; now playing"
"Skipped song; now playing", this.description = "**${track.title}**\n*Now Playing*\nby ${track.author} :: ${
"**${track.title}**\n*Now Playing*\nby ${track.author} :: ${ TimeUtil.getTimeFormatedRaw(
TimeUtil.getTimeFormatedRaw( track.length
track.length.inWholeMilliseconds )
) }\n" +
}\n" + ">>>${track.uri}"
">>>${track.uri}", this.footer {
user.asUser().username + "#" + user.asUser().discriminator, this.text = MessageUtil.getFooter(user)
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg" }
) this.thumbnail {
) this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
}
}
this.actionRow { this.actionRow {
this.components.addAll( this.components.addAll(
@ -130,17 +134,17 @@ class SkipButton : net.moonleay.botendo.buttons.Button("btn.music.skip") {
player.stopTrack() player.stopTrack()
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = "Skipped song"
"Skipped song; now playing", this.description = "Nothing"
"Nothing", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
)
this.actionRow {
this.components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
} }
this.actionRow(fun ActionRowBuilder.() {
components.addAll(ButtonUtil.getMusicControllerButtons(player.paused, gts.repeating).components)
})
} }
} }
} }

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.buttons.music package net.moonleay.botendo.buttons.music
@ -24,6 +23,7 @@ import dev.kord.core.behavior.interaction.response.DeferredPublicMessageInteract
import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.behavior.interaction.response.respond
import dev.kord.core.entity.Guild import dev.kord.core.entity.Guild
import dev.kord.core.entity.User import dev.kord.core.entity.User
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import net.moonleay.botendo.extensions.music.components.MusicManager import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.MessageUtil import net.moonleay.botendo.util.MessageUtil
@ -40,14 +40,14 @@ class StopButton : net.moonleay.botendo.buttons.Button("btn.music.stop") {
val voiceState = user.asMember(guildId).getVoiceStateOrNull() val voiceState = user.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) { if (voiceState == null) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not connected to a VC"
"You are not connected to a VC", this.description = "Please connect to a VC"
"Please connect to a VC", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} }
@ -55,26 +55,26 @@ class StopButton : net.moonleay.botendo.buttons.Button("btn.music.stop") {
val channelId = voiceState.channelId val channelId = voiceState.channelId
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "Not connected"
"Not connected", this.description = "I'm not in a VC and therefore, I am not playing anything."
"I'm not in a VC and therefore, I am not playing anything.", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not in my VC"
"You are not in my VC", this.description = "We are not in the same VC and therefore, you cannot control the music"
"We are not in the same VC and therefore, you cannot control the music", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
return return
} }
@ -83,14 +83,14 @@ class StopButton : net.moonleay.botendo.buttons.Button("btn.music.stop") {
link.destroy() link.destroy()
MusicManager.getGuildTrackScheduler(guild.asGuild(), player).clear() MusicManager.getGuildTrackScheduler(guild.asGuild(), player).clear()
response.respond { response.respond {
this.embeds = mutableListOf( this.embed {
MessageUtil.getEmbed( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = "I stopped and left"
"I stopped and left", this.description = "just like your girlfriend"
"just like your girlfriend", this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(user)
) }
) }
} }
} }
} }

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.data package net.moonleay.botendo.data

View file

@ -14,16 +14,16 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.extensions.music package net.moonleay.botendo.extensions.music
import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond
import dev.kord.common.Color import dev.kord.common.Color
import dev.kord.rest.builder.message.create.actionRow import dev.kord.rest.builder.component.ActionRowBuilder
import dev.kord.rest.builder.message.actionRow
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.kord.getLink import dev.schlaubi.lavakord.kord.getLink
import net.moonleay.botendo.extensions.music.components.MusicManager import net.moonleay.botendo.extensions.music.components.MusicManager
@ -42,55 +42,68 @@ class NowPlayingExtension : Extension() {
val guildId = this.guild!!.id val guildId = this.guild!!.id
val link = net.moonleay.botendo.Bot.lava.getLink(guildId) val link = net.moonleay.botendo.Bot.lava.getLink(guildId)
val player = link.player val player = link.player
val u = this.user
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
MessageUtil.sendEmbedForPublicSlashCommand( this.respond {
this, this.embed {
Color(0xE0A81A), this.color = Color(0xE0311A)
"Not connected", this.title = "Not connected"
"I'm not in a VC and therefore, I am not playing anything." this.description = "I'm not in a VC and therefore, I am not playing anything."
) this.footer {
this.text = MessageUtil.getFooter(u)
}
}
}
return@action return@action
} }
val track = player.playingTrack val track = player.playingTrack
if (track == null) { if (track == null) {
MessageUtil.sendEmbedForPublicSlashCommand( this.respond {
this, this.embed {
Color(0xE0A81A), this.color = Color(0xE0311A)
"Not Playing", this.title = "Not Playing"
"I'm not playing anything currently" this.description = "I'm not playing anything currently"
) this.footer {
this.text = MessageUtil.getFooter(u)
}
}
}
return@action return@action
} }
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player) val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
this.respond { this.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbedWithImage( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = "Currently playing"
"Currently playing", this.description = "**${track.info.title}**\n*Now Playing*\nby ${track.info.author} ; ${
"**${track.title}**\n*Now Playing*\nby ${track.author} ; ${ TimeUtil.getTimeFormatedRaw(
TimeUtil.getTimeFormatedRaw( player.position
player.position )
) }: ${
}: ${ TimeUtil.getTimeFormatedRaw(
TimeUtil.getTimeFormatedRaw( track.info.length
track.length.inWholeMilliseconds )
) }\n" +
}\n" + ">>>${track.info.uri}"
">>>${track.uri}", this.footer {
user.asUser().username + "#" + user.asUser().discriminator, this.text = MessageUtil.getFooter(u)
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri.toString()) + "/maxresdefault.jpg" }
) if(track.info.uri == null){
) this.thumbnail {
this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.info.uri!!) + "/maxresdefault.jpg"
}
}
}
this.actionRow { this.actionRow(fun ActionRowBuilder.() {
this.components.addAll( components.addAll(
ButtonUtil.getMusicControllerButtons( ButtonUtil.getMusicControllerButtons(
player.paused, player.paused,
gts.repeating gts.repeating
).components ).components
) )
} })
} }
} }
} }

View file

@ -14,20 +14,21 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.extensions.music package net.moonleay.botendo.extensions.music
import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond
import dev.kord.common.Color import dev.kord.common.Color
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.kord.getLink import dev.schlaubi.lavakord.kord.getLink
import net.moonleay.botendo.Bot
import net.moonleay.botendo.extensions.music.components.LinkArguments import net.moonleay.botendo.extensions.music.components.LinkArguments
import net.moonleay.botendo.extensions.music.components.MusicManager import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.MessageUtil import net.moonleay.botendo.util.MessageUtil
import net.moonleay.botendo.util.UserUtil
class PlayExtension : Extension() { class PlayExtension : Extension() {
@ -40,19 +41,19 @@ class PlayExtension : Extension() {
description = "Play music" description = "Play music"
this.action { this.action {
val guildId = this.guild!!.id val guildId = this.guild!!.id
val link = net.moonleay.botendo.Bot.lava.getLink(guildId) val link = Bot.lava.getLink(guildId)
val u = this.user val u = this.user
val vcsUser = u.asMember(guildId).getVoiceStateOrNull() val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
if (vcsUser == null) { if (vcsUser == null) {
this.respond { this.respond {
embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not connected to a VC"
"You are not connected to a VC", this.description = "Please connect to a VC"
"Please connect to a VC", this.footer {
u.asUser().username + "#" + u.asUser().discriminator this.text = MessageUtil.getFooter(u)
) }
) }
} }
return@action return@action
} }
@ -63,14 +64,14 @@ class PlayExtension : Extension() {
link.connectAudio(channelId!!.value) link.connectAudio(channelId!!.value)
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
this.respond { this.respond {
embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not in my VC"
"You are not in my VC", this.description = "We are not in the same VC and therefore, you cannot play any music"
"We are not in the same VC and therefore, you cannot play any music", this.author {
u.asUser().username + "#" + u.asUser().discriminator this.name = UserUtil.getCommandSrc(u)
) }
) }
} }
return@action return@action
} }
@ -82,14 +83,14 @@ class PlayExtension : Extension() {
"ytsearch:$query" "ytsearch:$query"
} }
this.respond { this.respond {
embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0A81A)
Color(0xE0A81A), this.title = "Searching..."
"Searching...", this.description = "We are looking for $query"
"We are looking for $query", this.footer {
u.asUser().username + "#" + u.asUser().discriminator this.text = MessageUtil.getFooter(u)
) }
) }
} }
MusicManager.addToQueue(this, link, search) MusicManager.addToQueue(this, link, search)
} }

View file

@ -14,16 +14,16 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.extensions.music package net.moonleay.botendo.extensions.music
import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond
import dev.kord.common.Color import dev.kord.common.Color
import dev.kord.rest.builder.message.create.actionRow import dev.kord.rest.builder.component.ActionRowBuilder
import dev.kord.rest.builder.message.actionRow
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import net.moonleay.botendo.extensions.music.components.MusicManager import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil import net.moonleay.botendo.util.ButtonUtil
@ -40,52 +40,61 @@ class QueueExtension : Extension() {
val guildId = this.guild!!.id val guildId = this.guild!!.id
val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString()) val link = net.moonleay.botendo.Bot.lava.getLink(guildId.toString())
val player = link.player val player = link.player
val u = this.user
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
MessageUtil.sendEmbedForPublicSlashCommand( this.respond {
this, this.embed {
Color(0xE0311A), this.color = Color(0xE0311A)
"Not connected", this.title = "Not connected"
"I'm not in a VC and therefore, I am not playing anything." this.description = "I'm not in a VC and therefore, I am not playing anything."
) this.footer {
this.text = MessageUtil.getFooter(u)
}
}
}
return@action return@action
} }
val track = player.playingTrack val track = player.playingTrack
if (track == null) { if (track == null) {
MessageUtil.sendEmbedForPublicSlashCommand( this.respond {
this, this.embed {
Color(0xE0A81A), this.color = Color(0xE0311A)
"Queue empty", this.title = "Queue empty"
"I'm not playing anything currently" this.description = "I'm not playing anything currently"
) this.footer {
this.text = MessageUtil.getFooter(u)
}
}
}
return@action return@action
} }
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player) val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
val q = gts.getQueue() val q = gts.getQueue()
var desc = var desc =
"""${"**" + track.title + " - " + TimeUtil.getTimeFormatedShortend(track.length.inWholeMilliseconds)} (${track.author})**""" + "\n" """${"**" + track.info.title + " - " + TimeUtil.getTimeFormatedShortend(track.info.length)} (${track.info.author})**""" + "\n"
for ((i, tr) in q.withIndex()) { for ((i, tr) in q.withIndex()) {
if (i >= 14) if (i >= 14)
continue continue
desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n" desc += tr.info.title + " - " + TimeUtil.getTimeFormatedShortend(tr.info.length) + " (" + tr.info.author + ")\n"
} }
this.respond { this.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = "Queue"
"Queue", this.description = desc
desc, this.footer {
user.asUser().username + "#" + user.asUser().discriminator this.text = MessageUtil.getFooter(u)
) }
) }
this.actionRow { this.actionRow(fun ActionRowBuilder.() {
this.components.addAll( components.addAll(
ButtonUtil.getMusicControllerButtons( ButtonUtil.getMusicControllerButtons(
player.paused, player.paused,
gts.repeating gts.repeating
).components ).components
) )
} })
} }
} }
} }

View file

@ -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
)
})
}
}
}
}
}

View file

@ -14,16 +14,16 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.extensions.music package net.moonleay.botendo.extensions.music
import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond
import dev.kord.common.Color import dev.kord.common.Color
import dev.kord.rest.builder.message.create.actionRow import dev.kord.rest.builder.component.ActionRowBuilder
import dev.kord.rest.builder.message.actionRow
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import net.moonleay.botendo.extensions.music.components.MusicManager import net.moonleay.botendo.extensions.music.components.MusicManager
import net.moonleay.botendo.util.ButtonUtil import net.moonleay.botendo.util.ButtonUtil
@ -44,46 +44,62 @@ class SkipExtension : Extension() {
val u = this.user val u = this.user
val voiceState = u.asMember(guildId).getVoiceStateOrNull() val voiceState = u.asMember(guildId).getVoiceStateOrNull()
if (voiceState == null) { if (voiceState == null) {
MessageUtil.sendEmbedForPublicSlashCommand( this.respond {
this, this.embed {
Color(0xE0311A), this.color = Color(0xE0311A)
"You are not connected to a VC", this.title = "You are not connected to a VC"
"Please connect to a VC" this.description = "Please connect to a VC"
) this.footer {
this.text = MessageUtil.getFooter(u)
}
}
}
return@action return@action
} }
val channelId = voiceState.channelId val channelId = voiceState.channelId
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
MessageUtil.sendEmbedForPublicSlashCommand( this.respond {
this, this.embed {
Color(0xE0311A), this.color = Color(0xE0311A)
"Not connected", this.title = "Not connected"
"I'm not in a VC and therefore, I am not playing anything." this.description = "I'm not in a VC and therefore, I am not playing anything."
) this.footer {
this.text = MessageUtil.getFooter(u)
}
}
}
return@action return@action
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
MessageUtil.sendEmbedForPublicSlashCommand( this.respond {
this, this.embed {
Color(0xE0311A), this.color = Color(0xE0311A)
"You are not in my VC", this.title = "You are not in my VC"
"We are not in the same VC and therefore, you cannot control the music" this.description = "We are not in the same VC and therefore, you cannot control the music"
) this.footer {
this.text = MessageUtil.getFooter(u)
}
}
}
return@action return@action
} }
var track = player.playingTrack var track = player.playingTrack!!.info
if (track == null) { if (track == null) {
MessageUtil.sendEmbedForPublicSlashCommand( this.respond {
this, this.embed {
Color(0xE0311A), this.color = Color(0xE0311A)
"Not playing", this.title = "Not playing"
"I'm not playing anything currently" this.description = "I'm not playing anything currently"
) this.footer {
this.text = MessageUtil.getFooter(u)
}
}
}
return@action return@action
} }
val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player) val gts = MusicManager.getGuildTrackScheduler(this.guild!!.asGuild(), player)
if (!gts.isEmpty()) { if (!gts.isEmpty()) {
track = gts.getHead().toTrack() track = gts.getHead().info
gts.playNext(link) gts.playNext(link)
} else { } else {
player.stopTrack() player.stopTrack()
@ -91,29 +107,31 @@ class SkipExtension : Extension() {
this.respond { this.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbedWithImage( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = "Skipped song; now playing"
"Skipped song; now playing", this.description = "**${track.title}**\n*Now Playing*\nby ${track.author} ;: ${
"**${track.title}**\n*Now Playing*\nby ${track.author} :: ${ TimeUtil.getTimeFormatedRaw(
TimeUtil.getTimeFormatedRaw( track.length
track.length.inWholeMilliseconds )
) }\n" +
}\n" + ">>>${track.uri}"
">>>${track.uri}", this.footer {
user.asUser().username + "#" + user.asUser().discriminator, this.text = MessageUtil.getFooter(u)
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg" }
) this.thumbnail {
) this.url = "https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(track.uri!!) + "/maxresdefault.jpg"
}
}
this.actionRow { this.actionRow(fun ActionRowBuilder.() {
this.components.addAll( components.addAll(
ButtonUtil.getMusicControllerButtons( ButtonUtil.getMusicControllerButtons(
player.paused, player.paused,
gts.repeating gts.repeating
).components ).components
) )
} })
} }
} }
} }

View file

@ -14,15 +14,14 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.extensions.music package net.moonleay.botendo.extensions.music
import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond
import dev.kord.common.Color import dev.kord.common.Color
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.kord.getLink import dev.schlaubi.lavakord.kord.getLink
import net.moonleay.botendo.extensions.music.components.MusicManager import net.moonleay.botendo.extensions.music.components.MusicManager
@ -42,38 +41,40 @@ class StopExtension : Extension() {
val vcsUser = u.asMember(guildId).getVoiceStateOrNull() val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
if (vcsUser == null) { if (vcsUser == null) {
this.respond { this.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not connected to a VC"
"You are not connected to a VC", this.description = "Please connect to a VC"
"Please connect to my VC", u.asUser().username + "#" + u.asUser().discriminator this.footer {
) this.text = MessageUtil.getFooter(u)
) }
}
} }
return@action return@action
} }
val channelId = vcsUser.channelId val channelId = vcsUser.channelId
if (link.state == Link.State.NOT_CONNECTED) { if (link.state == Link.State.NOT_CONNECTED) {
this.respond { this.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "Not connected"
"Not connected", this.description = "I'm not in a VC and therefore, I am not playing anything."
"I'm not in a VC and therefore, I am not playing anything.", this.footer {
u.asUser().username + "#" + u.asUser().discriminator this.text = MessageUtil.getFooter(u)
) }
) }
} }
return@action return@action
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
this.respond { this.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not in my VC"
"You are not in my VC", this.description = "We are not in the same VC"
"We are not in the same VC", u.asUser().username + "#" + u.asUser().discriminator this.footer {
) this.text = MessageUtil.getFooter(u)
) }
}
} }
return@action return@action
} }
@ -81,14 +82,14 @@ class StopExtension : Extension() {
link.destroy() link.destroy()
MusicManager.getGuildTrackScheduler(this.getGuild()!!.asGuild(), player).clear() MusicManager.getGuildTrackScheduler(this.getGuild()!!.asGuild(), player).clear()
this.respond { this.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = "I stopped and left"
"I stopped and left", this.description = "just like your girlfriend"
"just like your girlfriend", this.footer {
u.asUser().username + "#" + u.asUser().discriminator this.text = MessageUtil.getFooter(u)
) }
) }
} }
} }
} }

View file

@ -14,15 +14,14 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.extensions.music package net.moonleay.botendo.extensions.music
import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond
import dev.kord.common.Color import dev.kord.common.Color
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.kord.getLink import dev.schlaubi.lavakord.kord.getLink
import net.moonleay.botendo.extensions.music.components.LinkArguments import net.moonleay.botendo.extensions.music.components.LinkArguments
@ -45,14 +44,14 @@ class UpsertExtension : Extension() {
val vcsUser = u.asMember(guildId).getVoiceStateOrNull() val vcsUser = u.asMember(guildId).getVoiceStateOrNull()
if (vcsUser == null) { if (vcsUser == null) {
this.respond { this.respond {
embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not connected to a VC"
"You are not connected to a VC", this.description = "Please connect to a VC"
"Please connect to a VC", this.footer {
u.asUser().username + "#" + u.asUser().discriminator this.text = MessageUtil.getFooter(u)
) }
) }
} }
return@action return@action
} }
@ -63,14 +62,14 @@ class UpsertExtension : Extension() {
link.connectAudio(channelId!!.value) link.connectAudio(channelId!!.value)
} else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) { } else if (link.state == Link.State.CONNECTED && link.lastChannelId != channelId!!.value) {
this.respond { this.respond {
embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "You are not in my VC"
"You are not in my VC", this.description = "We are not in the same VC and therefore, you cannot play any music"
"We are not in the same VC and therefore, you cannot play any music", this.footer {
u.asUser().username + "#" + u.asUser().discriminator this.text = MessageUtil.getFooter(u)
) }
) }
} }
return@action return@action
} }
@ -82,14 +81,14 @@ class UpsertExtension : Extension() {
"ytsearch:$query" "ytsearch:$query"
} }
this.respond { this.respond {
embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0A81A)
Color(0xE0A81A), this.title = "Searching..."
"Searching...", this.description = "We are looking for $query"
"We are looking for $query", this.footer {
u.asUser().username + "#" + u.asUser().discriminator this.text = MessageUtil.getFooter(u)
) }
) }
} }
MusicManager.upsertIntoQueue(this, link, search) MusicManager.upsertIntoQueue(this, link, search)
} }

View file

@ -14,26 +14,26 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.extensions.music.components package net.moonleay.botendo.extensions.music.components
import dev.arbjerg.lavalink.protocol.v4.Track
import dev.schlaubi.lavakord.audio.* import dev.schlaubi.lavakord.audio.*
import dev.schlaubi.lavakord.audio.player.Player import dev.schlaubi.lavakord.audio.player.Player
import dev.schlaubi.lavakord.rest.models.PartialTrack import net.moonleay.botendo.Bot
import net.moonleay.botendo.util.Logger import net.moonleay.botendo.util.Logger
import java.util.concurrent.BlockingQueue import java.util.concurrent.BlockingQueue
import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.LinkedBlockingQueue
class GuildTrackScheduler(val pl: Player) { class GuildTrackScheduler(val pl: Player) {
private var queue: BlockingQueue<PartialTrack> = LinkedBlockingQueue() private var queue: BlockingQueue<Track> = LinkedBlockingQueue()
var repeating = false var repeating = false
private var hasRegisteredEvents = false private var hasRegisteredEvents = false
///Add a track to queue and start playing, if there is no song currently playing ///Add a track to queue and start playing, if there is no song currently playing
suspend fun queue(track: PartialTrack, type: MusicManager.AddType) { suspend fun queue(track: Track, type: MusicManager.AddType) {
if (this.pl.playingTrack == null) { if (this.pl.playingTrack == null) {
play(track) play(track)
return return
@ -44,7 +44,7 @@ class GuildTrackScheduler(val pl: Player) {
} }
MusicManager.AddType.UPSERT -> { MusicManager.AddType.UPSERT -> {
val nq = LinkedBlockingQueue<PartialTrack>() val nq = LinkedBlockingQueue<Track>()
nq.offer(track) nq.offer(track)
for (t in queue.toList()) { for (t in queue.toList()) {
nq.offer(t) nq.offer(t)
@ -56,7 +56,7 @@ class GuildTrackScheduler(val pl: Player) {
suspend fun playNext(link: Link) { suspend fun playNext(link: Link) {
if (!queue.isEmpty()) if (!queue.isEmpty())
this.pl.playTrack(queue.poll()) this.pl.playTrack(track = queue.poll())
else { else {
this.pl.stopTrack() this.pl.stopTrack()
link.destroy() link.destroy()
@ -64,8 +64,8 @@ class GuildTrackScheduler(val pl: Player) {
} }
} }
private suspend fun play(tr: PartialTrack) { private suspend fun play(track: Track) {
this.pl.playTrack(tr) this.pl.playTrack(track)
} }
fun addEvents() { fun addEvents() {
@ -92,22 +92,22 @@ class GuildTrackScheduler(val pl: Player) {
if (e.reason.mayStartNext) { if (e.reason.mayStartNext) {
if (repeating) { if (repeating) {
Logger.out("Repeating track...") Logger.out("Repeating track...")
this.pl.playTrack(e.getTrack().copy()) this.pl.playTrack(e.track.copy())
return return
} }
Logger.out("Track has ended; Playing next...") Logger.out("Track has ended; Playing next...")
playNext(net.moonleay.botendo.Bot.lava.getLink(e.guildId)) playNext(Bot.lava.getLink(e.guildId))
} }
} }
private suspend fun onTrackStuck(e: TrackStuckEvent) { private suspend fun onTrackStuck(e: TrackStuckEvent) {
Logger.out("Track is stuck, retrying...") Logger.out("Track is stuck, retrying...")
this.pl.playTrack(e.getTrack().copy()) this.pl.playTrack(e.track.copy())
} }
private suspend fun onTrackExc(e: TrackExceptionEvent) { private suspend fun onTrackExc(e: TrackExceptionEvent) {
Logger.out("Track had an exception, retrying...") Logger.out("Track had an exception, retrying...")
this.pl.playTrack(e.getTrack().copy()) this.pl.playTrack(e.track.copy())
} }
fun clear() { fun clear() {
@ -116,11 +116,11 @@ class GuildTrackScheduler(val pl: Player) {
queue.clear() queue.clear()
} }
fun getQueue(): List<PartialTrack> { fun getQueue(): List<Track> {
return queue.toList() return queue.toList()
} }
fun getHead(): PartialTrack { fun getHead(): Track {
return queue.first() return queue.first()
} }

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.extensions.music.components package net.moonleay.botendo.extensions.music.components

View file

@ -14,22 +14,22 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.extensions.music.components package net.moonleay.botendo.extensions.music.components
import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext
import com.kotlindiscord.kord.extensions.components.forms.ModalForm import com.kotlindiscord.kord.extensions.components.forms.ModalForm
import com.kotlindiscord.kord.extensions.types.respond import dev.arbjerg.lavalink.protocol.v4.LoadResult
import dev.kord.common.Color import dev.kord.common.Color
import dev.kord.common.entity.Snowflake import dev.kord.common.entity.Snowflake
import dev.kord.core.entity.Guild import dev.kord.core.entity.Guild
import dev.kord.rest.builder.message.create.actionRow import dev.kord.rest.builder.component.ActionRowBuilder
import dev.kord.rest.builder.message.actionRow
import dev.kord.rest.builder.message.embed
import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.audio.player.Player import dev.schlaubi.lavakord.audio.player.Player
import dev.schlaubi.lavakord.rest.loadItem import dev.schlaubi.lavakord.rest.loadItem
import dev.schlaubi.lavakord.rest.models.TrackResponse
import net.moonleay.botendo.util.ButtonUtil import net.moonleay.botendo.util.ButtonUtil
import net.moonleay.botendo.util.MessageUtil import net.moonleay.botendo.util.MessageUtil
import net.moonleay.botendo.util.TimeUtil import net.moonleay.botendo.util.TimeUtil
@ -38,6 +38,10 @@ import net.moonleay.botendo.util.UrlUtil
object MusicManager { object MusicManager {
private var musicManagerMap: MutableMap<Snowflake, GuildTrackScheduler> = mutableMapOf() private var musicManagerMap: MutableMap<Snowflake, GuildTrackScheduler> = mutableMapOf()
fun getMusicManager(guild: Guild): GuildTrackScheduler? {
return musicManagerMap[guild.id]
}
fun getGuildTrackScheduler(guild: Guild, player: Player): GuildTrackScheduler { fun getGuildTrackScheduler(guild: Guild, player: Player): GuildTrackScheduler {
return musicManagerMap.computeIfAbsent(guild.id) { return musicManagerMap.computeIfAbsent(guild.id) {
GuildTrackScheduler(player) GuildTrackScheduler(player)
@ -69,61 +73,72 @@ object MusicManager {
silent: Boolean silent: Boolean
) { ) {
val player = link.player val player = link.player
val item = link.loadItem(search)
val gts = getGuildTrackScheduler(ctx.guild!!.asGuild(), player) val gts = getGuildTrackScheduler(ctx.guild!!.asGuild(), player)
val u = ctx.user.asUser() val u = ctx.user.asUser()
gts.addEvents() gts.addEvents()
when (item.loadType) { when (val itm = link.loadItem(search)) {
TrackResponse.LoadType.TRACK_LOADED -> { is LoadResult.TrackLoaded -> {
gts.queue(item.track, type) gts.queue(itm.data, type)
if (!silent) if (!silent)
ctx.respond { ctx.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbedWithImage( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = "${type.s} track from link"
"${type.s} track from link", this.description = "**${itm.data.info.title}**\n*Queue*\nby ${itm.data.info.author} ;: ${
"**${item.track.info.title}**\n*Queue*\nby ${item.track.info.author} ;: ${ TimeUtil.getTimeFormatedRaw(
TimeUtil.getTimeFormatedRaw( itm.data.info.length
item.track.info.length )
) }\n" +
}\n" + ">>>${itm.data.info.uri}"
">>>${item.track.info.uri}", u.username + "#" + u.discriminator, this.footer {
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.track.info.uri) + "/maxresdefault.jpg" this.text = MessageUtil.getFooter(u)
) }
) if (itm.data.info.uri != null) {
this.thumbnail {
this.url =
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(itm.data.info.uri!!) + "/maxresdefault.jpg"
}
}
}
this.actionRow { this.actionRow(fun ActionRowBuilder.() {
this.components.addAll( components.addAll(
ButtonUtil.getMusicControllerButtons( ButtonUtil.getMusicControllerButtons(
player.paused, player.paused,
gts.repeating gts.repeating
).components ).components
) )
} })
} }
} }
is LoadResult.PlaylistLoaded -> {
TrackResponse.LoadType.PLAYLIST_LOADED -> { player.playTrack(track = itm.data.tracks.first())
val l = item.tracks.reversed() val l= itm.data.tracks.toList().reversed()
for (partialTrack in l) { for (partialTrack in l) {
gts.queue(partialTrack, type) gts.queue(partialTrack, type)
} }
if (!silent) if (!silent)
ctx.respond { ctx.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = "${type.s} playlist from link"
"${type.s} playlist from link", this.description = "**${itm.data.tracks.first().info.title}**\n*${itm.data.info.name}*\nby ${itm.data.tracks.first().info.author} ;: ${
"**${item.tracks.first().info.title}**\n*${item.playlistInfo.name}*\nby ${item.tracks.first().info.author} ;: ${ TimeUtil.getTimeFormatedRaw(
TimeUtil.getTimeFormatedRaw( itm.data.tracks.first().info.length
item.tracks.first().info.length )
) }\n" +
}\n" + ">>>${itm.data.tracks.first().info.uri}"
">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator this.footer {
) this.text = MessageUtil.getFooter(u)
) }
if (itm.data.tracks.first().info.uri != null) {
this.thumbnail {
this.url =
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(itm.data.tracks.first().info.uri!!) + "/maxresdefault.jpg"
}
}
}
this.actionRow { this.actionRow {
this.components.addAll( this.components.addAll(
@ -134,25 +149,31 @@ object MusicManager {
) )
} }
} }
}
TrackResponse.LoadType.SEARCH_RESULT -> { }
gts.queue(item.tracks.first(), type) is LoadResult.SearchResult -> {
gts.queue(itm.data.tracks.first(), type)
if (!silent) if (!silent)
ctx.respond { ctx.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbedWithImage( this.color = Color(0x52E01A)
Color(0x52E01A), this.title = "${type.s} track from query"
"${type.s} track from query", this.description = "**${itm.data.tracks.first().info.title}**\n*Queue*\nby ${itm.data.tracks.first().info.author} ;: ${
"**${item.tracks.first().info.title}**\n*Queue*\nby ${item.tracks.first().info.author} ;: ${ TimeUtil.getTimeFormatedRaw(
TimeUtil.getTimeFormatedRaw( itm.data.tracks.first().info.length
item.tracks.first().info.length )
) }\n" +
}\n" + ">>>${itm.data.tracks.first().info.uri}"
">>>${item.tracks.first().info.uri}", u.username + "#" + u.discriminator, this.footer {
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(item.tracks.first().info.uri) + "/maxresdefault.jpg" this.text = MessageUtil.getFooter(u)
) }
) if (itm.data.tracks.first().info.uri != null) {
this.thumbnail {
this.url =
"https://img.youtube.com/vi/" + UrlUtil.getYtThumbnailUrl(itm.data.tracks.first().info.uri!!) + "/maxresdefault.jpg"
}
}
}
this.actionRow { this.actionRow {
this.components.addAll( this.components.addAll(
@ -163,39 +184,47 @@ object MusicManager {
) )
} }
} }
}
TrackResponse.LoadType.NO_MATCHES -> { }
is LoadResult.NoMatches -> {
if (gts.isEmpty() && player.playingTrack == null) {
player.stopTrack()
link.destroy()
}
if (!silent) if (!silent)
ctx.respond { ctx.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "Not found"
"Not found", this.description = "There were no matches."
"There were no matches.", this.footer {
u.username + "#" + u.discriminator this.text = MessageUtil.getFooter(u)
) }
) }
} }
} }
is LoadResult.LoadFailed -> {
TrackResponse.LoadType.LOAD_FAILED -> { if (gts.isEmpty() && player.playingTrack == null) {
player.stopTrack()
link.destroy()
}
if (!silent) if (!silent)
ctx.respond { ctx.respond {
this.embeds.add( this.embed {
MessageUtil.getEmbed( this.color = Color(0xE0311A)
Color(0xE0311A), this.title = "Load failed"
"Load failed", this.description = "There was an error while loading."
"There was an error while loading.", u.username + "#" + u.discriminator this.footer {
) this.text = MessageUtil.getFooter(u)
) }
}
} }
} }
} }
} }
enum class AddType(val s: String) { enum class AddType(val s: String) {
QUEUE("Added"), QUEUE("Added"),
UPSERT("Upserted") UPSERT("Upserted")
} }
} }

View 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.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\""
}
}

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.extensions.util package net.moonleay.botendo.extensions.util
@ -22,6 +21,7 @@ package net.moonleay.botendo.extensions.util
import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import dev.kord.common.Color import dev.kord.common.Color
import dev.kord.rest.builder.message.embed
import net.moonleay.botendo.util.MessageUtil import net.moonleay.botendo.util.MessageUtil
class InfoExtension : Extension() { class InfoExtension : Extension() {
@ -31,15 +31,23 @@ class InfoExtension : Extension() {
name = "info" name = "info"
description = "Show infos about the bot" description = "Show infos about the bot"
this.action { this.action {
MessageUtil.sendEmbedForPublicSlashCommand( val u = this.user
this, Color(0x52E01A), "Botendo", this.respond {
"Botendo ***v." + net.moonleay.botendo.build.BuildConstants.version + "***\n" + this.embed {
this.color = Color(0x52E01A)
this.title = "Botendo"
this.description = "Botendo ***v." + net.moonleay.botendo.build.BuildConstants.version + "***\n" +
"Kord-Extensions ***v." + net.moonleay.botendo.build.BuildConstants.kordVersion + "***\n" + "Kord-Extensions ***v." + net.moonleay.botendo.build.BuildConstants.kordVersion + "***\n" +
"lavalink.kt ***v." + net.moonleay.botendo.build.BuildConstants.lavaVersion + "***\n" + "lavalink.kt ***v." + net.moonleay.botendo.build.BuildConstants.lavaVersion + "***\n" +
"Coroutines ***v." + net.moonleay.botendo.build.BuildConstants.coroutinesVersion + "***\n\n\n" + "Coroutines ***v." + net.moonleay.botendo.build.BuildConstants.coroutinesVersion + "***\n\n\n" +
"***Bot made by moonleay#0069***\n" + "***Bot made by moonleay***\n" +
"(c) 2023, licensed under GPL-3.0" "(c) 2023, licensed under GPL-3.0\n" +
) "More infos: https://moonleay.net/projects/botendo\n"
this.footer {
this.text = MessageUtil.getFooter(u)
}
}
}
} }
} }
} }

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.util package net.moonleay.botendo.util

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.util package net.moonleay.botendo.util

View file

@ -14,91 +14,19 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.util package net.moonleay.botendo.util
import com.kotlindiscord.kord.extensions.commands.Arguments import dev.kord.core.behavior.UserBehavior
import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext
import com.kotlindiscord.kord.extensions.components.forms.ModalForm
import com.kotlindiscord.kord.extensions.types.respond
import dev.kord.common.Color
import dev.kord.rest.builder.message.EmbedBuilder
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
object MessageUtil { object MessageUtil {
private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss") private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss")
///Send an embedded message as a reply suspend fun getFooter(u: UserBehavior? = null): String{
suspend fun sendEmbedForPublicSlashCommand(
ctx: PublicSlashCommandContext<Arguments, ModalForm>,
color: Color,
title: String,
description: String
) {
ctx.respond {
embeds.add(
getEmbed(
color,
title,
description,
ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator
)
)
}
}
///Send an embedded message with an image as a reply
suspend fun sendEmbedForPublicSlashCommandWithImage(
ctx: PublicSlashCommandContext<Arguments, ModalForm>,
color: Color,
title: String,
description: String,
thumbnailUrl: String
) {
ctx.respond {
embeds.add(
getEmbedWithImage(
color,
title,
description,
ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator,
thumbnailUrl
)
)
}
}
///Get an embedded msg with title, description and a src
fun getEmbed(
color: Color,
title: String,
description: String,
source: String
): EmbedBuilder {
val now: LocalDateTime = LocalDateTime.now() val now: LocalDateTime = LocalDateTime.now()
val ebb = EmbedBuilder() return ">" + dtf.format(now) + " - ${u?.asUser()?.username?:"Automatic Message"}"
ebb.title = title
ebb.description = description
ebb.footer = EmbedBuilder.Footer()
ebb.footer!!.text = ">" + dtf.format(now) + " - $source"
ebb.color = color
return ebb
}
///Get an embedded msg with image, title, description and a src
fun getEmbedWithImage(
color: Color,
title: String,
description: String,
source: String,
thumbnailUrl: String
): EmbedBuilder {
val ebb = getEmbed(color, title, description, source)
ebb.thumbnail = EmbedBuilder.Thumbnail()
ebb.thumbnail!!.url = thumbnailUrl
return ebb
} }
} }

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.util package net.moonleay.botendo.util

View file

@ -14,11 +14,11 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.util package net.moonleay.botendo.util
import java.time.Duration
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
object TimeUtil { object TimeUtil {
@ -87,4 +87,28 @@ object TimeUtil {
return s return s
} }
//This 100000%ly can be improved, I wrote this at 2am
fun getTimeUnformated(timeStr: String): Long {
var days: Long = 0
var hours: Long = 0
var minutes: Long = 0
var seconds: Long = 0
val timeArr = timeStr.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
for (s in timeArr) {
Logger.out(s)
if (s.endsWith("d")) {
days = s.split("d".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].toLong()
} else if (s.endsWith("h")) {
hours = s.split("h".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].toLong()
} else if (s.endsWith("m")) {
minutes = s.split("m".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].toLong()
} else if (s.endsWith("s")) {
seconds = s.split("s".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].toLong()
}
}
val value = Duration.ofSeconds(seconds).plus(Duration.ofMinutes(minutes)).plus(Duration.ofHours(hours))
.plus(Duration.ofDays(days)).toMillis()
return value
}
} }

View file

@ -14,7 +14,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
package net.moonleay.botendo.util package net.moonleay.botendo.util

View 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}}"
}
}

View file

@ -15,4 +15,3 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# #
#