├── .circleci └── config.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.bat ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── de │ └── blockbuild │ └── musikbot │ ├── Bot.java │ ├── Listener │ ├── MessageListener.java │ └── VoiceChannelListener.java │ ├── Main.java │ ├── commands │ ├── ConnectionCommand.java │ ├── MBCommand.java │ ├── MusicCommand.java │ ├── RadioCommand.java │ ├── SetupCommand.java │ ├── connection │ │ ├── JoinCommand.java │ │ ├── PingCommand.java │ │ └── QuitCommand.java │ ├── general │ │ ├── InfoCommand.java │ │ └── VersionCommand.java │ ├── music │ │ ├── FlushQueue.java │ │ ├── NextCommand.java │ │ ├── PauseCommand.java │ │ ├── PlayCommand.java │ │ ├── PlaylistCommand.java │ │ ├── PushCommand.java │ │ ├── QueueCommand.java │ │ ├── ShuffleCommand.java │ │ ├── SkipCommand.java │ │ ├── StopCommand.java │ │ ├── VolumeCommand.java │ │ └── YTAutoPlayCommand.java │ ├── radio │ │ ├── Radio100nlCommand.java │ │ ├── RadioBobCommand.java │ │ ├── RadioBonnRheinSiegCommand.java │ │ ├── RadioMnmCommand.java │ │ └── RautemusikCommand.java │ └── setup │ │ ├── AutoConnectCommand.java │ │ ├── AutoDisconnectCommand.java │ │ ├── BlacklistCommand.java │ │ ├── ConfigCommand.java │ │ ├── DefaultTextChannelCommand.java │ │ ├── DefaultVoiceChannelCommand.java │ │ ├── ReloadCommand.java │ │ └── WhitelistCommand.java │ ├── configuration │ ├── BotConfiguration.java │ ├── ConfigurationManager.java │ ├── GuildConfiguration.java │ └── PlaylistConfiguration.java │ ├── core │ ├── AudioPlayerSendHandler.java │ ├── BasicResultHandler.java │ ├── ExtendYoutubeAudioSourceManager.java │ ├── GuildMusicManager.java │ └── TrackScheduler.java │ └── metrics │ └── Metrics.java └── resources ├── 64.png ├── Sample_BotConfig.yml ├── Sample_GuildConfig.yml └── plugin.yml /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Java Gradle CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-java/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | docker: 9 | # specify the version you desire here 10 | - image: circleci/openjdk:8-jdk 11 | 12 | # Specify service dependencies here if necessary 13 | # CircleCI maintains a library of pre-built images 14 | # documented at https://circleci.com/docs/2.0/circleci-images/ 15 | # - image: circleci/postgres:9.4 16 | 17 | working_directory: ~/MusikBot 18 | 19 | environment: 20 | # Customize the JVM maximum heap limit 21 | JVM_OPTS: -Xmx3200m 22 | TERM: dumb 23 | 24 | steps: 25 | - checkout 26 | 27 | # Download and cache dependencies 28 | - restore_cache: 29 | keys: 30 | - v1-dependencies-{{ checksum "build.gradle" }} 31 | # fallback to using the latest cache if no exact match is found 32 | - v1-dependencies- 33 | 34 | - run: gradle dependencies 35 | 36 | - save_cache: 37 | paths: 38 | - ~/.gradle 39 | key: v1-dependencies-{{ checksum "build.gradle" }} 40 | 41 | # run tests! 42 | - run: gradle test 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # eclipse 2 | /.settings/ 3 | .project 4 | .classpath 5 | .settings/ 6 | .buildpath 7 | /bin/ 8 | # gradle 9 | /.gradle/ 10 | /build/ 11 | /.git/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Release](https://img.shields.io/github/release/Block-Build/MusikBot.svg)](https://github.com/Block-Build/MusikBot/releases/latest) 2 | # MusikBot ![GitHub Logo](/src/main/resources/64.png) 3 | 4 | Discord MusikBot on Minecraft 5 | The Discord MusikBot is a Music Bot you can host on your Minecraft Server as a Plugin! It's unimportant which MC version you are using, MusikBot supports nearly all of them! MusikBot is easy and fast to setup, have FUN! 6 | 7 | ### Features: 8 | * You can add songs from YouTube, SoundCloud, Bandcamp, Vimeo, Twitch streams, Local files or just URLs! 9 | * Plays playlists from YouTube 10 | * You can search for YouTube videos 11 | * Listen to choosen Radio streams! 12 | * Supported formats: MP3, FLAC, WAV, AAC, Opus, Vorbis, MP4/M4A, OGG, Stream playlists (M3U and PLS) 13 | * Adding songs to queue 14 | * Shuffle the playlist 15 | * YouTube autoplay 16 | * Get information about currend song 17 | * You are able to skip tracks 18 | * Able to change the volume of the Bot 19 | * Save your playlist to load and listen to it next time 20 | * Join the Bot to as much Servers as you want! They will act independently 21 | * Many things can be configured: Should the bot disconnect if it is alone? How about automatically joining a channel? And many more! 22 | * White- and blacklists for users and other bots 23 | * Change the command trigger to whatever you want 24 | * And a lot of more cool stuff! Just have a look to !help and config files;) 25 | * Much more is planned! Suggestions and feedback are welcome! Please open an issue 26 | 27 | ### Basic Commands: 28 | * !play [URL | title] 29 | * !queue [URL | title] 30 | * !next 31 | * !skip [amount] 32 | * !volume [0-100] 33 | * !info 34 | * !join [channel name] 35 | * !stop 36 | * !leave 37 | * !pause / !resume 38 | * ... 39 | * For more commands and information type !help 40 | 41 | ### Requirements: 42 | * Java 8 is Required! 43 | 44 | ### How to setup: 45 | * Copy paste Plugin in the 'plugins' folder of your Minecraft server 46 | * Start server once to generate the default config 47 | * You have to insert the token to the BotConfig.yml 48 | * To get a Bot Token you have to create a Discord Bot at this site: 49 | * https://discordapp.com/developers/applications/ 50 | * Create a new Application 51 | * Navigate to Bot and click 'add Bot' 52 | * Get the Token 53 | * Also fill in your Discord user ID 54 | * You could easy get Channel and User ID's from discord by right click after enableing the Developer Mode 55 | * After the server started successfully there will be an invite URL in console and config to join the Bot to your Discord Server. 56 | 57 | ### Support/Suggestions/Bugs: 58 | I've create this Bot to warm up my java knowledge. I hope you will enjoy it. 59 | If you have any problems, suggestions or bugs feel free to create an issue. Every feedback is welcome, thanks.:giggle: 60 | 61 | 62 | This project would not be possible without JDA the DiscodJavaApi and lavaplayer for the audio mechanic. 63 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | gradlew.bat build 2 | pause 3 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'application' 4 | id 'com.github.johnrengelman.shadow' version '4.0.4'} 5 | 6 | mainClassName = 'de.blockbuild.musikbot.Main' 7 | version = '1.2.5' 8 | sourceCompatibility = 1.8 9 | targetCompatibility = 1.8 10 | 11 | repositories { 12 | jcenter() 13 | mavenCentral() 14 | maven { 15 | url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' 16 | } 17 | maven { 18 | name = 'CodeMC' 19 | url = 'https://repo.codemc.org/repository/maven-public' 20 | url 'https://dl.bintray.com/breadmoirai/maven' 21 | } 22 | maven { 23 | name 'm2-dv8tion' 24 | url 'https://m2.dv8tion.net/releases' 25 | } 26 | } 27 | 28 | dependencies { 29 | compile 'com.sedmelluq:lavaplayer:1.3.75' 30 | compile 'com.jagrosh:jda-utilities:3.0.5' 31 | compile 'net.dv8tion:JDA:4.2.1_256' 32 | compile 'org.slf4j:slf4j-simple:1.7.25' 33 | compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1' 34 | compile 'com.github.breadmoirai:DiscordEmoji:1.1.0' 35 | 36 | compileOnly 'org.bukkit:bukkit:1.12.2-R0.1-SNAPSHOT' 37 | } 38 | 39 | jar { 40 | baseName = project.name 41 | manifest { 42 | attributes 'Implementation-Version': version 43 | attributes 'Main-Class': mainClassName 44 | } 45 | } 46 | 47 | shadowJar { 48 | classifier = 'Shaded' 49 | dependencies { 50 | exclude(dependency('org.spigotmc:spigot-api:1.12.1-R0.1-SNAPSHOT')) 51 | exclude(dependency('com.google.guava:guava:21.0')) 52 | exclude(dependency('org.hamcrest:hamcrest-core:1.1')) 53 | exclude(dependency('org.yaml:snakeyaml:1.19')) 54 | exclude(dependency('commons-lang:commons-lang:2.6')) 55 | } 56 | relocate 'org.apache', 'shadow.org.apache' 57 | relocate 'org.json', 'shadow.org.json' 58 | } 59 | 60 | build { 61 | dependsOn shadowJar 62 | } 63 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Block-Build/MusikBot/de9f60e55f3ecb88fa04627834d5983175050e21/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This settings file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * In a single project build this file can be empty or even removed. 6 | * 7 | * Detailed information about configuring a multi-project build in Gradle can be found 8 | * in the user guide at https://docs.gradle.org/4.3/userguide/multi_project_builds.html 9 | */ 10 | 11 | /* 12 | // To declare projects as part of a multi-project build use the 'include' method 13 | include 'shared' 14 | include 'api' 15 | include 'services:webservice' 16 | */ 17 | 18 | rootProject.name = 'MusikBot' 19 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/Bot.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.Arrays; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | import javax.security.auth.login.LoginException; 9 | 10 | import org.apache.commons.io.FileUtils; 11 | import com.jagrosh.jdautilities.command.Command; 12 | import com.jagrosh.jdautilities.command.CommandClientBuilder; 13 | import com.jagrosh.jdautilities.commons.waiter.EventWaiter; 14 | import com.jagrosh.jdautilities.command.Command.Category; 15 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; 16 | import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; 17 | import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers; 18 | 19 | import de.blockbuild.musikbot.Listener.MessageListener; 20 | import de.blockbuild.musikbot.Listener.VoiceChannelListener; 21 | import de.blockbuild.musikbot.commands.connection.JoinCommand; 22 | import de.blockbuild.musikbot.commands.connection.PingCommand; 23 | import de.blockbuild.musikbot.commands.connection.QuitCommand; 24 | import de.blockbuild.musikbot.commands.general.InfoCommand; 25 | import de.blockbuild.musikbot.commands.general.VersionCommand; 26 | import de.blockbuild.musikbot.commands.music.FlushQueue; 27 | import de.blockbuild.musikbot.commands.music.NextCommand; 28 | import de.blockbuild.musikbot.commands.music.PauseCommand; 29 | import de.blockbuild.musikbot.commands.music.PlayCommand; 30 | import de.blockbuild.musikbot.commands.music.PlaylistCommand; 31 | import de.blockbuild.musikbot.commands.music.QueueCommand; 32 | import de.blockbuild.musikbot.commands.music.ShuffleCommand; 33 | import de.blockbuild.musikbot.commands.music.SkipCommand; 34 | import de.blockbuild.musikbot.commands.music.StopCommand; 35 | import de.blockbuild.musikbot.commands.music.VolumeCommand; 36 | import de.blockbuild.musikbot.commands.music.YTAutoPlayCommand; 37 | import de.blockbuild.musikbot.commands.radio.Radio100nlCommand; 38 | import de.blockbuild.musikbot.commands.radio.RadioBobCommand; 39 | import de.blockbuild.musikbot.commands.radio.RadioBonnRheinSiegCommand; 40 | import de.blockbuild.musikbot.commands.radio.RadioMnmCommand; 41 | import de.blockbuild.musikbot.commands.radio.RautemusikCommand; 42 | import de.blockbuild.musikbot.commands.setup.AutoConnectCommand; 43 | import de.blockbuild.musikbot.commands.setup.AutoDisconnectCommand; 44 | import de.blockbuild.musikbot.commands.setup.BlacklistCommand; 45 | import de.blockbuild.musikbot.commands.setup.ConfigCommand; 46 | import de.blockbuild.musikbot.commands.setup.DefaultTextChannelCommand; 47 | import de.blockbuild.musikbot.commands.setup.DefaultVoiceChannelCommand; 48 | import de.blockbuild.musikbot.commands.setup.ReloadCommand; 49 | import de.blockbuild.musikbot.commands.setup.WhitelistCommand; 50 | import de.blockbuild.musikbot.configuration.BotConfiguration; 51 | import de.blockbuild.musikbot.core.GuildMusicManager; 52 | 53 | import net.dv8tion.jda.api.JDA; 54 | import net.dv8tion.jda.api.JDABuilder; 55 | import net.dv8tion.jda.api.OnlineStatus; 56 | import net.dv8tion.jda.api.Permission; 57 | import net.dv8tion.jda.api.entities.Activity; 58 | import net.dv8tion.jda.api.entities.ChannelType; 59 | import net.dv8tion.jda.api.entities.Activity.ActivityType; 60 | import net.dv8tion.jda.api.entities.Guild; 61 | import net.dv8tion.jda.api.entities.Icon; 62 | import net.dv8tion.jda.api.entities.TextChannel; 63 | import net.dv8tion.jda.api.entities.User; 64 | import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; 65 | import net.dv8tion.jda.api.requests.GatewayIntent; 66 | import net.dv8tion.jda.api.utils.cache.CacheFlag; 67 | import net.dv8tion.jda.api.entities.VoiceChannel; 68 | 69 | public class Bot { 70 | public final static Permission[] BASIC_PERMS = new Permission[] { Permission.MESSAGE_READ, Permission.MESSAGE_WRITE, 71 | Permission.MESSAGE_HISTORY, Permission.MESSAGE_ADD_REACTION, Permission.MESSAGE_EMBED_LINKS, 72 | Permission.VOICE_CONNECT, Permission.VOICE_SPEAK, Permission.MESSAGE_TTS }; 73 | public final static GatewayIntent[] Intents = new GatewayIntent[] { GatewayIntent.GUILD_VOICE_STATES, 74 | GatewayIntent.GUILD_MESSAGES, GatewayIntent.GUILD_MESSAGE_REACTIONS, GatewayIntent.DIRECT_MESSAGES }; 75 | private final Main main; 76 | private final AudioPlayerManager playerManager; 77 | private final Map musicManagers; 78 | private final EventWaiter waiter; 79 | private JDA jda; 80 | public final BotConfiguration config; 81 | 82 | public Bot(Main main) { 83 | System.out.println("[" + main.getName() + "] Get started..."); 84 | 85 | this.main = main; 86 | this.waiter = new EventWaiter(); 87 | this.musicManagers = new HashMap<>(); 88 | this.playerManager = new DefaultAudioPlayerManager(); 89 | this.config = new BotConfiguration(this); 90 | 91 | try { 92 | FileUtils.copyInputStreamToFile(main.getResource("Sample_BotConfig.yml"), 93 | new File(main.getDataFolder(), "Sample_BotConfig.yml")); 94 | FileUtils.copyInputStreamToFile(main.getResource("Sample_GuildConfig.yml"), 95 | new File(main.getDataFolder(), "Sample_GuildConfig.yml")); 96 | } catch (IOException e) { 97 | System.err.println("[" + main.getName() + "] Can't write Sample_Configs."); 98 | e.printStackTrace(); 99 | } 100 | 101 | if (start()) { 102 | initListeners(); 103 | initCommandClient(); 104 | System.out.println("[" + main.getName() + "] Started successfully"); 105 | } else { 106 | System.out.println("[" + main.getName() + "] Shut down"); 107 | main.onDisable(); 108 | } 109 | } 110 | 111 | public boolean start() { 112 | try { 113 | String token = config.getToken(); 114 | if (token == null || token.isEmpty()) { 115 | System.out.println("No token was provided. Please provide a vaild token."); 116 | System.out.println("Without a token the Bot will not be able to start."); 117 | return false; 118 | } else if (token.equals("Insert Token here")) { 119 | System.out.println("Token was left at default. Please provide a vaild token."); 120 | System.out.println("Without a token the Bot will not be able to start."); 121 | return false; 122 | } 123 | jda = JDABuilder.create(token, Arrays.asList(Intents)) 124 | .enableCache(CacheFlag.VOICE_STATE, CacheFlag.MEMBER_OVERRIDES) 125 | .disableCache(CacheFlag.ACTIVITY, CacheFlag.CLIENT_STATUS, CacheFlag.EMOTE) 126 | .setActivity(Activity.of(ActivityType.DEFAULT, "starting...")) 127 | .setStatus(OnlineStatus.DO_NOT_DISTURB).addEventListeners(waiter).build(); 128 | jda.awaitReady(); 129 | } catch (LoginException e) { 130 | System.out.println("Invalid bot Token"); 131 | return false; 132 | } catch (InterruptedException e) { 133 | // Should never triggered! 134 | e.printStackTrace(); 135 | return false; 136 | } 137 | 138 | try { 139 | jda.getSelfUser().getManager().setAvatar(Icon.from(main.getResource("64.png"))).queue(unused -> { 140 | }, ignored -> { 141 | }); 142 | } catch (IOException e) { 143 | System.err.println(e); 144 | } 145 | 146 | jda.getPresence().setPresence(OnlineStatus.ONLINE, Activity.of(ActivityType.DEFAULT, config.getGame())); 147 | if (!jda.getSelfUser().getName().equalsIgnoreCase("MusikBot")) { 148 | jda.getSelfUser().getManager().setName("MusikBot").queue(); 149 | } 150 | 151 | // Print invite token to console 152 | System.out.println("Invite Token:"); 153 | String inviteURL = jda.getInviteUrl(Bot.BASIC_PERMS); 154 | System.out.println(inviteURL); 155 | config.setInviteLink(inviteURL); 156 | 157 | AudioSourceManagers.registerRemoteSources(playerManager); 158 | AudioSourceManagers.registerLocalSource(playerManager); 159 | 160 | jda.getGuilds().forEach((guild) -> { 161 | getGuildAudioPlayer(guild); 162 | }); 163 | return true; 164 | } 165 | 166 | public void stop() { 167 | if (!(jda == null)) { 168 | jda.shutdown(); 169 | jda = null; 170 | } 171 | } 172 | 173 | public synchronized GuildMusicManager getGuildAudioPlayer(Guild guild) { 174 | GuildMusicManager musicManager = musicManagers.get(guild.getIdLong()); 175 | 176 | if (musicManager == null) { 177 | musicManager = new GuildMusicManager(playerManager, guild, this); 178 | musicManagers.put(guild.getIdLong(), musicManager); 179 | 180 | guild.getAudioManager().setSendingHandler(musicManager.getSendHandler()); 181 | } 182 | return musicManager; 183 | } 184 | 185 | public void initListeners() { 186 | jda.addEventListener(new MessageListener(this), new VoiceChannelListener()); 187 | } 188 | 189 | public void initCommandClient() { 190 | String ownerID = config.getOwnerID(); 191 | String trigger = config.getTrigger(); 192 | CommandClientBuilder ccb = new CommandClientBuilder(); 193 | ccb.setOwnerId(ownerID); 194 | ccb.setCoOwnerIds("240566179880501250"); 195 | ccb.useHelpBuilder(true); 196 | ccb.setHelpConsumer((event) -> { 197 | // Slightly changed default helpConsumer from JDA-Utilities. 198 | StringBuilder builder = new StringBuilder("**" + event.getSelfUser().getName() + "** commands:\n"); 199 | Category category = null; 200 | for (Command command : event.getClient().getCommands()) { 201 | if (!command.isHidden() && (!command.isOwnerCommand() || event.isOwner())) { 202 | if (category == null || !(category.getName() == command.getCategory().getName())) { 203 | category = command.getCategory(); 204 | builder.append("\n\n __").append(category == null ? "No Category" : category.getName()) 205 | .append("__:\n"); 206 | } 207 | builder.append("\n`").append(event.getClient().getPrefix()) 208 | .append(event.getClient().getPrefix() == null ? " " : "").append(command.getName()) 209 | .append(command.getArguments() == null ? "`" : " " + command.getArguments() + "`") 210 | .append(" - ").append(command.getHelp()); 211 | } 212 | } 213 | User owner = event.getJDA().getUserById(event.getClient().getOwnerIdLong()); 214 | if (owner != null) { 215 | builder.append("\n\nFor additional help, contact **").append(owner.getName()).append("**#") 216 | .append(owner.getDiscriminator()); 217 | } 218 | event.replyInDm(builder.toString(), unused -> { 219 | if (event.isFromType(ChannelType.TEXT)) 220 | event.reactSuccess(); 221 | }, t -> event.replyWarning("Help cannot be sent because you are blocking Direct Messages.")); 222 | }); 223 | ccb.setEmojis(config.getSuccess(), config.getWarning(), config.getError()); 224 | ccb.setPrefix(trigger); 225 | ccb.setLinkedCacheSize(100); 226 | registerCommandModule(ccb, 227 | //Music 228 | new PlayCommand(this), 229 | new QueueCommand(this), 230 | new NextCommand(this), 231 | new SkipCommand(this), 232 | new FlushQueue(this), 233 | new ShuffleCommand(this), 234 | new PlaylistCommand(this), 235 | new YTAutoPlayCommand(this), 236 | new VolumeCommand(this), 237 | new PauseCommand(this), 238 | new StopCommand(this), 239 | 240 | //General 241 | new InfoCommand(this), 242 | new VersionCommand(this), 243 | 244 | //Radio 245 | new RadioBonnRheinSiegCommand(this), 246 | new RautemusikCommand(this), 247 | new RadioBobCommand(this), 248 | new RadioMnmCommand(this), 249 | new Radio100nlCommand(this), 250 | 251 | //Connection 252 | new JoinCommand(this), 253 | new QuitCommand(this), 254 | new PingCommand(this), 255 | 256 | //Setup 257 | new BlacklistCommand(this), 258 | new WhitelistCommand(this), 259 | new AutoDisconnectCommand(this), 260 | new AutoConnectCommand(this), 261 | new DefaultTextChannelCommand(this), 262 | new DefaultVoiceChannelCommand(this), 263 | new ConfigCommand(this), 264 | new ReloadCommand(this)); 265 | 266 | jda.addEventListener(ccb.build()); 267 | } 268 | 269 | public void registerCommandModule(CommandClientBuilder ccb, Command... commands) { 270 | for (Command c : commands) { 271 | ccb.addCommand(c); 272 | } 273 | } 274 | 275 | public boolean joinDiscordVoiceChannel(Guild guild) { 276 | for (int i = 0; i < guild.getVoiceChannels().size(); i++) { 277 | try { 278 | guild.getAudioManager().openAudioConnection(guild.getVoiceChannels().get(i)); 279 | return true; 280 | } catch (IllegalArgumentException e) { 281 | System.out.println("no VoiceChannel"); 282 | } catch (InsufficientPermissionException e) { 283 | System.out.println("Missing permission: " + e.getPermission() + " to join '" 284 | + guild.getVoiceChannels().get(i).getName() + "'"); 285 | } catch (Exception e) { 286 | System.err.println(e); 287 | } 288 | } 289 | return false; 290 | } 291 | 292 | public boolean joinDiscordVoiceChannel(Guild guild, Long id) { 293 | try { 294 | guild.getAudioManager().openAudioConnection(guild.getVoiceChannelById(id)); 295 | return true; 296 | } catch (IllegalArgumentException e) { 297 | System.out.println(id + " is not a VoiceChannel"); 298 | } catch (InsufficientPermissionException e) { 299 | System.out.println("Missing permission: " + e.getPermission() + " to join '" + id + "'"); 300 | } catch (Exception e) { 301 | System.out.println(id + " isn't a vaild VoiceChannel"); 302 | } 303 | return false; 304 | } 305 | 306 | public boolean joinDiscordVoiceChannel(Guild guild, String name) { 307 | try { 308 | guild.getAudioManager().openAudioConnection((VoiceChannel) guild.getVoiceChannelsByName(name, true).get(0)); 309 | return true; 310 | } catch (IllegalArgumentException e) { 311 | System.out.println(name + " is not a VoiceChannel"); 312 | } catch (InsufficientPermissionException e) { 313 | System.out.println("Missing permission: " + e.getPermission() + " to join '" 314 | + guild.getVoiceChannels().get(0).getName() + "'"); 315 | } catch (Exception e) { 316 | System.out.println(name + " isn't a vaild VoiceChannel"); 317 | } 318 | return false; 319 | } 320 | 321 | public JDA getJda() { 322 | return jda; 323 | } 324 | 325 | public Main getMain() { 326 | return main; 327 | } 328 | 329 | public EventWaiter getWaiter() { 330 | return waiter; 331 | } 332 | 333 | public AudioPlayerManager getPlayerManager() { 334 | return playerManager; 335 | } 336 | 337 | public User getUserById(String id) { 338 | return this.jda.getUserById(id); 339 | } 340 | 341 | public User getUserById(Long id) { 342 | return this.jda.getUserById(id); 343 | } 344 | 345 | public String getUserNameById(String id) { 346 | User user = getUserById(id); 347 | if (user == null) { 348 | return "UNKNOWN"; 349 | } else { 350 | return user.getName(); 351 | } 352 | } 353 | 354 | public String getUserNameById(Long id) { 355 | User user = getUserById(id); 356 | if (user == null) { 357 | return "UNKNOWN"; 358 | } else { 359 | return user.getName(); 360 | } 361 | } 362 | 363 | public TextChannel getTextChannelById(Long id) { 364 | return this.jda.getTextChannelById(id); 365 | } 366 | 367 | public VoiceChannel getVoiceChannelById(Long id) { 368 | return this.jda.getVoiceChannelById(id); 369 | } 370 | 371 | public Guild getGuildById(String id) { 372 | try { 373 | return this.jda.getGuildById(id); 374 | } catch (Exception e) { 375 | return null; 376 | } 377 | } 378 | 379 | public Guild getGuildById(Long id) { 380 | try { 381 | return this.jda.getGuildById(id); 382 | } catch (Exception e) { 383 | return null; 384 | } 385 | } 386 | } 387 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/Listener/MessageListener.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.Listener; 2 | 3 | import java.util.Random; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | 7 | import net.dv8tion.jda.api.entities.*; 8 | import net.dv8tion.jda.api.events.message.MessageReceivedEvent; 9 | import net.dv8tion.jda.api.hooks.ListenerAdapter; 10 | 11 | public class MessageListener extends ListenerAdapter { 12 | 13 | MessageChannel channel; 14 | String msg; 15 | Bot bot; 16 | 17 | public MessageListener(Bot bot) { 18 | this.bot = bot; 19 | } 20 | 21 | @Override 22 | public void onMessageReceived(MessageReceivedEvent event) { 23 | channel = event.getChannel(); 24 | msg = event.getMessage().getContentDisplay(); 25 | 26 | if (event.isFromType(ChannelType.TEXT)) { 27 | } 28 | 29 | if (msg.equals("!ping")) { 30 | channel.sendMessage("pong!").queue(); 31 | } else if (msg.equals("!roll")) { 32 | Random rand = new Random(); 33 | int roll = rand.nextInt(6) + 1; 34 | channel.sendMessage("Your roll: " + roll).queue(sentMessage -> // This is called a lambda statement. 35 | { 36 | if (roll < 3) { 37 | channel.sendMessage("The roll for messageId: " + sentMessage.getId() 38 | + " wasn't very good... Must be bad luck!\n").queue(); 39 | } 40 | }); 41 | } else if (msg.equalsIgnoreCase("***trigger")) { 42 | channel.sendMessage(bot.config.getTrigger()).queue(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/Listener/VoiceChannelListener.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.Listener; 2 | 3 | import de.blockbuild.musikbot.core.AudioPlayerSendHandler; 4 | import de.blockbuild.musikbot.core.GuildMusicManager; 5 | 6 | import net.dv8tion.jda.api.entities.*; 7 | import net.dv8tion.jda.api.events.guild.voice.GuildVoiceLeaveEvent; 8 | import net.dv8tion.jda.api.events.guild.voice.GuildVoiceMoveEvent; 9 | import net.dv8tion.jda.api.hooks.ListenerAdapter; 10 | 11 | public class VoiceChannelListener extends ListenerAdapter { 12 | 13 | MessageChannel channel; 14 | String msg; 15 | 16 | @Override 17 | public void onGuildVoiceLeave(GuildVoiceLeaveEvent event) { 18 | GuildMusicManager musicManager = ((AudioPlayerSendHandler) event.getGuild().getAudioManager() 19 | .getSendingHandler()).getBot().getGuildAudioPlayer(event.getGuild()); 20 | 21 | if (musicManager.config.isDisconnectIfAloneEnabled()) { 22 | VoiceChannel channel = event.getChannelLeft(); 23 | // Member member = event.getMember(); 24 | Member selfMember = event.getGuild().getSelfMember(); 25 | 26 | if (!selfMember.getVoiceState().inVoiceChannel()) { 27 | return; 28 | } 29 | 30 | if (!(channel == selfMember.getVoiceState().getChannel())) { 31 | return; 32 | } 33 | 34 | if (channel.getMembers().size() > 1) { 35 | return; 36 | } 37 | 38 | if (!(musicManager.getAudioPlayer().getPlayingTrack() == null)) { 39 | musicManager.getAudioPlayer().stopTrack(); 40 | } 41 | // close audio connection 42 | selfMember.getGuild().getAudioManager().closeAudioConnection(); 43 | } 44 | } 45 | 46 | @Override 47 | public void onGuildVoiceMove(GuildVoiceMoveEvent event) { 48 | GuildMusicManager musicManager = ((AudioPlayerSendHandler) event.getGuild().getAudioManager() 49 | .getSendingHandler()).getBot().getGuildAudioPlayer(event.getGuild()); 50 | 51 | if (musicManager.config.isDisconnectIfAloneEnabled()) { 52 | VoiceChannel channel = event.getChannelLeft(); 53 | // Member member = event.getMember(); 54 | Member selfMember = event.getGuild().getSelfMember(); 55 | 56 | if (!selfMember.getVoiceState().inVoiceChannel()) { 57 | return; 58 | } 59 | 60 | if (!(channel == selfMember.getVoiceState().getChannel())) { 61 | return; 62 | } 63 | 64 | if (channel.getMembers().size() > 1) { 65 | return; 66 | } 67 | 68 | if (!(musicManager.getAudioPlayer().getPlayingTrack() == null)) { 69 | musicManager.getAudioPlayer().stopTrack(); 70 | } 71 | // close audio connection 72 | selfMember.getGuild().getAudioManager().closeAudioConnection(); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/Main.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.plugin.Plugin; 8 | import org.bukkit.plugin.java.JavaPlugin; 9 | 10 | import de.blockbuild.musikbot.metrics.Metrics; 11 | import net.dv8tion.jda.api.OnlineStatus; 12 | import net.dv8tion.jda.api.entities.Guild; 13 | import net.dv8tion.jda.api.entities.User; 14 | 15 | public class Main extends JavaPlugin { 16 | 17 | private Bot bot; 18 | 19 | @Override 20 | public void onEnable() { 21 | try { 22 | start(); 23 | Metrics metrics = new Metrics(this); 24 | 25 | metrics.addCustomChart(new Metrics.SingleLineChart("guilds_lin", () -> bot.getJda().getGuilds().size())); 26 | 27 | metrics.addCustomChart( 28 | new Metrics.SimplePie("guilds_pie", () -> String.valueOf(bot.getJda().getGuilds().size()))); 29 | 30 | metrics.addCustomChart(new Metrics.SingleLineChart("streams_lin", () -> { 31 | int counter = 0; 32 | for (Guild guild : bot.getJda().getGuilds()) 33 | if (bot.getGuildAudioPlayer(guild).getAudioPlayer().getPlayingTrack() != null) { 34 | counter++; 35 | } 36 | return counter; 37 | })); 38 | 39 | metrics.addCustomChart(new Metrics.SingleLineChart("users_lin", () -> bot.getJda().getUsers().size())); 40 | 41 | metrics.addCustomChart(new Metrics.SingleLineChart("users_online_lin", () -> { 42 | Set users = new HashSet(); 43 | for (Guild guild : bot.getJda().getGuilds()) { 44 | guild.getMembers().forEach((member) -> { 45 | if (member.getOnlineStatus() != OnlineStatus.OFFLINE 46 | && member.getOnlineStatus() != OnlineStatus.UNKNOWN) { 47 | users.add(member.getUser()); 48 | } 49 | }); 50 | } 51 | return users.size(); 52 | })); 53 | } catch (Exception e) { 54 | System.out.println(e); 55 | } 56 | } 57 | 58 | @Override 59 | public void onDisable() { 60 | if (bot != null) { 61 | bot.stop(); 62 | } 63 | } 64 | 65 | public void reload() { 66 | Plugin plugin = this.getServer().getPluginManager().getPlugin(this.getName()); 67 | this.getServer().getPluginManager().disablePlugin(plugin); 68 | this.getServer().getPluginManager().enablePlugin(plugin); 69 | } 70 | 71 | private void start() { 72 | Bukkit.getScheduler().runTaskLater(this, () -> { 73 | bot = new Bot(this); 74 | }, 1L); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/ConnectionCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands; 2 | 3 | import de.blockbuild.musikbot.Bot; 4 | import net.dv8tion.jda.api.Permission; 5 | import net.dv8tion.jda.api.entities.Role; 6 | 7 | public abstract class ConnectionCommand extends MBCommand { 8 | 9 | public ConnectionCommand(Bot bot) { 10 | super(bot); 11 | this.category = new Category("CONNECTION", event -> { 12 | if (event.getGuild() == null) { 13 | return true; 14 | } 15 | 16 | Role connection = bot.getGuildAudioPlayer(event.getGuild()).config.getConnectionRole(); 17 | 18 | if (event.isOwner() || event.getMember().hasPermission(Permission.MANAGE_SERVER) || connection == null 19 | || event.getMember().getRoles().contains(connection)) { 20 | 21 | if (!event.getSelfMember().getVoiceState().inVoiceChannel()) { 22 | return true; 23 | } 24 | 25 | if (!event.getMember().getVoiceState().getChannel() 26 | .equals(event.getSelfMember().getVoiceState().getChannel())) { 27 | // in different channels 28 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 29 | builder.append(" You must be in the same channel as me to use that command!"); 30 | event.reply(builder.toString()); 31 | return false; 32 | } 33 | return true; 34 | } else { 35 | event.reply(event.getClient().getWarning() + " You are not permitted to use this command"); 36 | return false; 37 | } 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/MBCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands; 2 | 3 | import com.jagrosh.jdautilities.command.Command; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | 6 | import de.blockbuild.musikbot.Bot; 7 | import de.blockbuild.musikbot.configuration.GuildConfiguration; 8 | import de.blockbuild.musikbot.core.GuildMusicManager; 9 | 10 | import net.dv8tion.jda.api.Permission; 11 | import net.dv8tion.jda.api.entities.ChannelType; 12 | import net.dv8tion.jda.api.entities.Guild; 13 | import net.dv8tion.jda.api.entities.Member; 14 | import net.dv8tion.jda.api.entities.TextChannel; 15 | import net.dv8tion.jda.api.entities.User; 16 | import net.dv8tion.jda.api.entities.VoiceChannel; 17 | 18 | public abstract class MBCommand extends Command implements Comparable { 19 | 20 | protected final Category GENERAL = new Category("GENERAL"); 21 | protected final Bot bot; 22 | protected Boolean joinOnCommand = false; 23 | 24 | protected User user; 25 | protected User selfUser; 26 | protected Member member; 27 | protected Member selfMember; 28 | protected VoiceChannel channel; 29 | protected VoiceChannel selfChannel; 30 | protected TextChannel textChannel; 31 | protected GuildMusicManager musicManager; 32 | protected Guild guild; 33 | protected String args; 34 | 35 | public MBCommand(Bot bot) { 36 | this.bot = bot; 37 | this.guildOnly = false; 38 | this.botPermissions = RECOMMENDED_PERMS(); 39 | this.category = GENERAL; 40 | } 41 | 42 | private Permission[] RECOMMENDED_PERMS() { 43 | return Bot.BASIC_PERMS; 44 | } 45 | 46 | @Override 47 | protected void execute(CommandEvent event) { 48 | args = event.getArgs(); 49 | user = event.getAuthor(); 50 | selfUser = event.getSelfUser(); 51 | 52 | if (event.getChannelType() == ChannelType.PRIVATE) { 53 | if (event.isOwner()) { 54 | if (!(args == null) && args.length() >= 18) { 55 | guild = null; 56 | guild = bot.getGuildById(args.substring(0, 18)); 57 | if (!(guild == null)) { 58 | args = args.substring(18).trim(); 59 | member = guild.getMember(user); 60 | selfMember = guild.getSelfMember(); 61 | channel = member.getVoiceState().getChannel(); 62 | selfChannel = selfMember.getVoiceState().getChannel(); 63 | musicManager = bot.getGuildAudioPlayer(guild); 64 | 65 | doGuildCommand(event); 66 | return; 67 | } 68 | } 69 | } 70 | doPrivateCommand(event); 71 | return; 72 | } 73 | 74 | guild = event.getGuild(); 75 | member = event.getMember(); 76 | selfMember = event.getSelfMember(); 77 | channel = member.getVoiceState().getChannel(); 78 | selfChannel = selfMember.getVoiceState().getChannel(); 79 | textChannel = event.getTextChannel(); 80 | musicManager = bot.getGuildAudioPlayer(guild); 81 | 82 | if (musicManager.config.getMessageDeleteDelay() > 0) { 83 | musicManager.deleteMessageLater(event.getChannel(), event.getMessage(), musicManager.config.getMessageDeleteDelay()); 84 | } 85 | 86 | if (musicManager.config.isDefaultTextChannelEnabled()) { 87 | if (!(textChannel.getIdLong() == musicManager.config.getDefaultTextChannel()) 88 | && !(musicManager.config.getDefaultTextChannel() == 0L)) { 89 | StringBuilder builder = new StringBuilder().append(event.getClient().getWarning()); 90 | builder.append(" You are only allowd to use commands in `") 91 | .append(bot.getTextChannelById(musicManager.config.getDefaultTextChannel()).getName()) 92 | .append("`"); 93 | event.replyInDm(builder.toString()); 94 | return; 95 | } 96 | } 97 | 98 | if (!event.isOwner() && musicManager.config.isBlockedUser(user.getIdLong()) 99 | || (!event.isOwner() && (musicManager.config.isWhitelistEnabled() 100 | && !(musicManager.config.isWhitelistedUser(user.getIdLong()))))) { 101 | User owner = bot.getUserById(bot.config.getOwnerID()); 102 | StringBuilder builder = new StringBuilder().append(event.getClient().getWarning()); 103 | builder.append(" You're not allowed to interact with me!"); 104 | if (!(owner == null)) { 105 | builder.append("\nFor additional info, contact ").append(owner.getName()).append("#") 106 | .append(owner.getDiscriminator()); 107 | } 108 | event.reply(builder.toString()); 109 | return; 110 | } 111 | 112 | try { 113 | doGuildCommand(event); 114 | } catch (Exception e) { 115 | e.printStackTrace(); 116 | } 117 | } 118 | 119 | public Long getLong(String string, CommandEvent event) { 120 | Long l = null; 121 | try { 122 | l = Long.valueOf(string); 123 | } catch (Exception e) { 124 | // nothing 125 | } finally { 126 | if (l == null) { 127 | StringBuilder builder = new StringBuilder().append(event.getClient().getError()); 128 | builder.append(" `").append(string).append("` isn't a vaild format.\n"); 129 | builder.append(" !").append(this.name).append(" ").append(this.arguments); 130 | event.reply(builder.toString()); 131 | } 132 | } 133 | return l; 134 | } 135 | 136 | protected boolean allowedToJoinVoiceChannel(GuildConfiguration config, long id) { 137 | if (config.isDefaultVoiceChannelEnabled() && !(config.getDefaultVoiceChannel() == 0L)) { 138 | if (config.getDefaultVoiceChannel() == id) { 139 | return true; 140 | } else { 141 | return false; 142 | } 143 | } else { 144 | return true; 145 | } 146 | } 147 | 148 | protected boolean allowedToJoinVoiceChannel(GuildConfiguration config, String id) { 149 | if (config.isDefaultVoiceChannelEnabled() && !(config.getDefaultVoiceChannel() == 0L)) { 150 | if (String.valueOf(config.getDefaultVoiceChannel()) == id) { 151 | return true; 152 | } else { 153 | return false; 154 | } 155 | } else { 156 | return true; 157 | } 158 | } 159 | 160 | public void sendCommandInfo(CommandEvent event) { 161 | StringBuilder builder = new StringBuilder().append(event.getClient().getWarning()); 162 | builder.append(" ").append(event.getClient().getPrefix()).append(this.name).append(" ").append(this.arguments); 163 | event.reply(builder.toString()); 164 | } 165 | 166 | public void sendDefaultVoiceChannelInfo(CommandEvent event, GuildMusicManager musicManager) { 167 | StringBuilder builder = new StringBuilder().append(event.getClient().getWarning()); 168 | builder.append(" Default VoiceChannel is active. I'm only allowed to join `") 169 | .append(bot.getVoiceChannelById(musicManager.config.getDefaultVoiceChannel()).getName()).append("`"); 170 | event.reply(builder.toString()); 171 | } 172 | 173 | protected abstract void doGuildCommand(CommandEvent event); 174 | 175 | protected abstract void doPrivateCommand(CommandEvent event); 176 | 177 | @Override 178 | public int compareTo(Command o) { 179 | return this.getName().compareTo(o.getName()); 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/MusicCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands; 2 | 3 | import de.blockbuild.musikbot.Bot; 4 | import de.blockbuild.musikbot.core.GuildMusicManager; 5 | 6 | import net.dv8tion.jda.api.Permission; 7 | import net.dv8tion.jda.api.entities.Role; 8 | import net.dv8tion.jda.api.entities.VoiceChannel; 9 | 10 | public abstract class MusicCommand extends MBCommand { 11 | 12 | public MusicCommand(Bot bot) { 13 | super(bot); 14 | this.category = new Category("MUSIC", event -> { 15 | if (event.getGuild() == null) { 16 | return true; 17 | } 18 | 19 | Role music = bot.getGuildAudioPlayer(event.getGuild()).config.getMusicRole(); 20 | 21 | if (event.isOwner() || event.getMember().hasPermission(Permission.MANAGE_SERVER) || music == null 22 | || event.getMember().getRoles().contains(music)) { 23 | 24 | VoiceChannel channel = event.getMember().getVoiceState().getChannel(); 25 | GuildMusicManager musicManager = bot.getGuildAudioPlayer(event.getGuild()); 26 | 27 | if (!event.getSelfMember().getVoiceState().inVoiceChannel()) { 28 | if (joinOnCommand) { 29 | if (allowedToJoinVoiceChannel(musicManager.config, channel.getIdLong())) { 30 | bot.joinDiscordVoiceChannel(event.getGuild(), channel.getIdLong()); 31 | return true; 32 | } else { 33 | sendDefaultVoiceChannelInfo(event, musicManager); 34 | return false; 35 | } 36 | } else { 37 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 38 | builder.append(" Use `!Join [Channel]` to let me join a channel"); 39 | event.reply(builder.toString()); 40 | return false; 41 | } 42 | } 43 | 44 | if (!channel.equals(event.getSelfMember().getVoiceState().getChannel())) { 45 | // in different channels 46 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 47 | builder.append(" You must be in the same channel as me to use that command!"); 48 | event.reply(builder.toString()); 49 | return false; 50 | } 51 | return true; 52 | } else { 53 | event.reply(event.getClient().getWarning() + " You are not permitted to use this command"); 54 | return false; 55 | } 56 | }); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/RadioCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands; 2 | 3 | import de.blockbuild.musikbot.Bot; 4 | import de.blockbuild.musikbot.core.GuildMusicManager; 5 | 6 | import net.dv8tion.jda.api.Permission; 7 | import net.dv8tion.jda.api.entities.Role; 8 | import net.dv8tion.jda.api.entities.VoiceChannel; 9 | 10 | public abstract class RadioCommand extends MBCommand { 11 | 12 | public RadioCommand(Bot bot) { 13 | super(bot); 14 | this.category = new Category("RADIO", event -> { 15 | if (event.getGuild() == null) { 16 | return true; 17 | } 18 | 19 | Role radio = bot.getGuildAudioPlayer(event.getGuild()).config.getRadioRole(); 20 | 21 | if (event.isOwner() || event.getMember().hasPermission(Permission.MANAGE_SERVER) || radio == null 22 | || event.getMember().getRoles().contains(radio)) { 23 | 24 | VoiceChannel channel = event.getMember().getVoiceState().getChannel(); 25 | GuildMusicManager musicManager = bot.getGuildAudioPlayer(event.getGuild()); 26 | 27 | if (!event.getSelfMember().getVoiceState().inVoiceChannel()) { 28 | if (joinOnCommand) { 29 | if (allowedToJoinVoiceChannel(musicManager.config, channel.getIdLong())) { 30 | bot.joinDiscordVoiceChannel(event.getGuild(), channel.getIdLong()); 31 | return true; 32 | } else { 33 | sendDefaultVoiceChannelInfo(event, musicManager); 34 | return false; 35 | } 36 | } else { 37 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 38 | builder.append(" Use `!Join [Channel]` to let me join a channel"); 39 | event.reply(builder.toString()); 40 | return false; 41 | } 42 | } 43 | 44 | if (!channel.equals(event.getSelfMember().getVoiceState().getChannel())) { 45 | // in different channels 46 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 47 | builder.append(" You must be in the same channel as me to use that command!"); 48 | event.reply(builder.toString()); 49 | return false; 50 | } 51 | return true; 52 | } else { 53 | event.reply(event.getClient().getWarning() + " You are not permitted to use this command"); 54 | return false; 55 | } 56 | }); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/SetupCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands; 2 | 3 | import de.blockbuild.musikbot.Bot; 4 | 5 | import net.dv8tion.jda.api.Permission; 6 | import net.dv8tion.jda.api.entities.Role; 7 | 8 | public abstract class SetupCommand extends MBCommand { 9 | 10 | public SetupCommand(Bot bot) { 11 | super(bot); 12 | this.category = new Category("SETUP", event -> { 13 | 14 | if (event.isOwner()) { 15 | return true; 16 | } else if (event.getGuild() == null) { 17 | return true; 18 | } else if (event.getMember().hasPermission(Permission.MANAGE_SERVER)) { 19 | return true; 20 | } 21 | 22 | Role setup = bot.getGuildAudioPlayer(event.getGuild()).config.getSetupRole(); 23 | 24 | if (setup == null || event.getMember().getRoles().contains(setup)) { 25 | return true; 26 | } else { 27 | event.reply(event.getClient().getWarning() + " You are not permitted to use this command"); 28 | return false; 29 | } 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/connection/JoinCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.connection; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.ConnectionCommand; 7 | 8 | public class JoinCommand extends ConnectionCommand { 9 | 10 | public JoinCommand(Bot bot) { 11 | super(bot); 12 | this.name = "join"; 13 | this.help = "Triggers the Bot to join a voice channel!"; 14 | this.arguments = "[ChannelName]"; 15 | this.joinOnCommand = false; 16 | } 17 | 18 | @Override 19 | protected void doGuildCommand(CommandEvent event) { 20 | if (args.isEmpty()) { 21 | if (channel == null) { 22 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 23 | builder.append(" You need to specify a channel!"); 24 | event.reply(builder.toString()); 25 | } else if (channel.equals(selfChannel)) { 26 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 27 | builder.append(" We are already in the same channel!"); 28 | event.reply(builder.toString()); 29 | } else { 30 | if (allowedToJoinVoiceChannel(musicManager.config, channel.getIdLong())) { 31 | bot.joinDiscordVoiceChannel(guild, channel.getIdLong()); 32 | } else { 33 | sendDefaultVoiceChannelInfo(event, musicManager); 34 | } 35 | } 36 | } else { 37 | if (allowedToJoinVoiceChannel(musicManager.config, args)) { 38 | if (!bot.joinDiscordVoiceChannel(guild, args)) { 39 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 40 | builder.append(" Missing permission or there is no channel called `").append(args).append("`."); 41 | event.reply(builder.toString()); 42 | } 43 | } else { 44 | sendDefaultVoiceChannelInfo(event, musicManager); 45 | } 46 | } 47 | } 48 | 49 | @Override 50 | protected void doPrivateCommand(CommandEvent event) { 51 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 52 | 53 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 54 | 55 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 56 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 57 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 58 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 59 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 60 | 61 | event.reply(builder.toString()); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/connection/PingCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.connection; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.ConnectionCommand; 7 | 8 | public class PingCommand extends ConnectionCommand { 9 | public PingCommand(Bot bot) { 10 | super(bot); 11 | this.name = "ping"; 12 | this.help = "Displays the responce time"; 13 | this.joinOnCommand = false; 14 | } 15 | 16 | @Override 17 | protected void doGuildCommand(CommandEvent event) { 18 | StringBuilder builder = new StringBuilder(event.getClient().getSuccess()); 19 | builder.append(" Ping: `").append(event.getJDA().getGatewayPing()).append("ms`"); 20 | event.reply(builder.toString()); 21 | } 22 | 23 | @Override 24 | protected void doPrivateCommand(CommandEvent event) { 25 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 26 | 27 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 28 | 29 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 30 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 31 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 32 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 33 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 34 | 35 | event.reply(builder.toString()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/connection/QuitCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.connection; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.ConnectionCommand; 7 | import de.blockbuild.musikbot.core.TrackScheduler; 8 | 9 | public class QuitCommand extends ConnectionCommand { 10 | 11 | public QuitCommand(Bot bot) { 12 | super(bot); 13 | this.name = "quit"; 14 | this.aliases = new String[] { "leave", "disconnect" }; 15 | this.help = "Disconnect and delete queue."; 16 | } 17 | 18 | @Override 19 | protected void doGuildCommand(CommandEvent event) { 20 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 21 | trackScheduler.flushQueue(); 22 | trackScheduler.stopTrack(); 23 | guild.getAudioManager().closeAudioConnection(); 24 | } 25 | 26 | @Override 27 | protected void doPrivateCommand(CommandEvent event) { 28 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 29 | 30 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 31 | 32 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 33 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 34 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 35 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 36 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 37 | 38 | event.reply(builder.toString()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/general/InfoCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.general; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | import com.jagrosh.jdautilities.command.CommandEvent; 7 | import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; 8 | 9 | import de.blockbuild.musikbot.Bot; 10 | import de.blockbuild.musikbot.commands.MBCommand; 11 | 12 | public class InfoCommand extends MBCommand { 13 | 14 | public InfoCommand(Bot bot) { 15 | super(bot); 16 | this.name = "info"; 17 | this.aliases = new String[] { "i" }; 18 | this.help = "Info of the current Track."; 19 | } 20 | 21 | @Override 22 | protected void doGuildCommand(CommandEvent event) { 23 | if (!(musicManager.getAudioPlayer().getPlayingTrack() == null)) { 24 | AudioTrackInfo trackInfo = musicManager.getAudioPlayer().getPlayingTrack().getInfo(); 25 | StringBuilder builder = new StringBuilder(event.getClient().getSuccess()).append("\n"); 26 | builder.append("Title: `").append(trackInfo.title).append("`\n"); 27 | builder.append("Author: `").append(trackInfo.author).append("`\n"); 28 | builder.append("Duration: `").append(getTime(trackInfo.length)).append("`\n"); 29 | builder.append("Source: `") 30 | .append(musicManager.getAudioPlayer().getPlayingTrack().getSourceManager().getSourceName()) 31 | .append("`\n"); 32 | builder.append("URL: `").append(trackInfo.uri).append("`\n"); 33 | event.reply(builder.toString()); 34 | } else { 35 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 36 | builder.append(" Currently there is no track playing. Use `").append(event.getClient().getPrefix()) 37 | .append("play` to start a track."); 38 | event.reply(builder.toString()); 39 | } 40 | } 41 | 42 | @Override 43 | protected void doPrivateCommand(CommandEvent event) { 44 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 45 | 46 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 47 | 48 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 49 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 50 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 51 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 52 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 53 | 54 | event.reply(builder.toString()); 55 | } 56 | 57 | private String getTime(long lng) { 58 | return (new SimpleDateFormat("mm:ss")).format(new Date(lng)); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/general/VersionCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.general; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.MBCommand; 7 | 8 | public class VersionCommand extends MBCommand { 9 | 10 | public VersionCommand(Bot bot) { 11 | super(bot); 12 | this.name = "version"; 13 | this.help = "MusikBot version."; 14 | } 15 | 16 | @Override 17 | protected void doGuildCommand(CommandEvent event) { 18 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 19 | 20 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 21 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 22 | builder.append("GuitHub: `https://github.com/Block-Build/MusikBot`\n"); 23 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 24 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 25 | 26 | event.reply(builder.toString()); 27 | } 28 | 29 | @Override 30 | protected void doPrivateCommand(CommandEvent event) { 31 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 32 | 33 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 34 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 35 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 36 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 37 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 38 | 39 | event.reply(builder.toString()); 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/FlushQueue.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import com.github.breadmoirai.discordemoji.Emoji; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 6 | 7 | import de.blockbuild.musikbot.Bot; 8 | import de.blockbuild.musikbot.commands.MusicCommand; 9 | import de.blockbuild.musikbot.core.TrackScheduler; 10 | 11 | public class FlushQueue extends MusicCommand { 12 | 13 | public FlushQueue(Bot bot) { 14 | super(bot); 15 | this.name = "flush"; 16 | this.aliases = new String[] { "f", "fl" }; 17 | this.help = "Clears the queue"; 18 | this.arguments = "[Amount]"; 19 | } 20 | 21 | @Override 22 | protected void doGuildCommand(CommandEvent event) { 23 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 24 | if (args.isEmpty()) { 25 | trackScheduler.flushQueue(); 26 | StringBuilder builder = new StringBuilder(); 27 | builder.append(event.getClient().getSuccess()).append(" Queue flushed!"); 28 | event.reply(builder.toString()); 29 | } else { 30 | int i = 0; 31 | try { 32 | i = Integer.parseInt(args); 33 | } catch (Exception e) { 34 | // no integer 35 | } finally { 36 | StringBuilder builder = new StringBuilder(); 37 | if (i > 0) { 38 | int num = trackScheduler.flushQueue(i); 39 | builder.append(event.getClient().getSuccess()).append(" **").append(num) 40 | .append("** Tracks got flushed!"); 41 | if (!(trackScheduler.getNextTrack() == null)) { 42 | AudioTrack track = trackScheduler.getNextTrack(); 43 | builder.append("\n").append(Emoji.NOTES.getUtf8()).append(" Next Track: **") 44 | .append(track.getInfo().title).append("**"); 45 | builder.append(" (`").append(trackScheduler.getTime(track.getDuration())).append("`)"); 46 | } 47 | } else { 48 | builder.append(event.getClient().getError()).append(" **").append(args) 49 | .append(" The number must be greater than zero!"); 50 | } 51 | event.reply(builder.toString()); 52 | } 53 | } 54 | } 55 | 56 | @Override 57 | protected void doPrivateCommand(CommandEvent event) { 58 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 59 | 60 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 61 | 62 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 63 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 64 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 65 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 66 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 67 | 68 | event.reply(builder.toString()); 69 | } 70 | } -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/NextCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import com.github.breadmoirai.discordemoji.Emoji; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 6 | 7 | import de.blockbuild.musikbot.Bot; 8 | import de.blockbuild.musikbot.commands.MusicCommand; 9 | import de.blockbuild.musikbot.core.TrackScheduler; 10 | 11 | public class NextCommand extends MusicCommand { 12 | 13 | public NextCommand(Bot bot) { 14 | super(bot); 15 | this.name = "next"; 16 | this.aliases = new String[] { "n" }; 17 | this.help = "Returns the next title of the next track."; 18 | this.joinOnCommand = true; 19 | } 20 | 21 | @Override 22 | protected void doGuildCommand(CommandEvent event) { 23 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 24 | StringBuilder builder = new StringBuilder(); 25 | if (trackScheduler.getNextTrack() == null) { 26 | builder.append(event.getClient().getWarning()).append(" The queue is empty!"); 27 | } else { 28 | AudioTrack track = trackScheduler.getNextTrack(); 29 | builder.append(Emoji.TRACK_NEXT.getUtf8()).append(" Next track: **").append(track.getInfo().title).append("**"); 30 | builder.append(" (`").append(trackScheduler.getTime(track.getDuration())).append("`)"); 31 | } 32 | event.reply(builder.toString()); 33 | } 34 | 35 | @Override 36 | protected void doPrivateCommand(CommandEvent event) { 37 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 38 | 39 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 40 | 41 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 42 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 43 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 44 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 45 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 46 | 47 | event.reply(builder.toString()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/PauseCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import com.github.breadmoirai.discordemoji.Emoji; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; 6 | 7 | import de.blockbuild.musikbot.Bot; 8 | import de.blockbuild.musikbot.commands.MusicCommand; 9 | 10 | public class PauseCommand extends MusicCommand { 11 | public PauseCommand(Bot bot) { 12 | super(bot); 13 | this.name = "pause"; 14 | this.aliases = new String[] { "resume" }; 15 | this.help = "Pause or resume playback."; 16 | } 17 | 18 | @Override 19 | protected void doGuildCommand(CommandEvent event) { 20 | AudioPlayer player = musicManager.getAudioPlayer(); 21 | if (!(player.getPlayingTrack() == null)) { 22 | StringBuilder builder = new StringBuilder(); 23 | if (player.isPaused()) { 24 | player.setPaused(false); 25 | 26 | builder.append(Emoji.ARROW_FORWARD.getUtf8()); 27 | builder.append(" Playback resumed."); 28 | } else { 29 | player.setPaused(true); 30 | 31 | builder.append(Emoji.PAUSE_BUTTON.getUtf8()); 32 | builder.append(" Playback paused."); 33 | } 34 | event.reply(builder.toString()); 35 | } else { 36 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 37 | builder.append(" Currently there is no track playing. Use `").append(event.getClient().getPrefix()) 38 | .append("play` to start a track."); 39 | event.reply(builder.toString()); 40 | } 41 | } 42 | 43 | @Override 44 | protected void doPrivateCommand(CommandEvent event) { 45 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 46 | 47 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 48 | 49 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 50 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 51 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 52 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 53 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 54 | 55 | event.reply(builder.toString()); 56 | } 57 | } -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/PlayCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import com.github.breadmoirai.discordemoji.Emoji; 6 | import com.jagrosh.jdautilities.command.CommandEvent; 7 | import com.jagrosh.jdautilities.menu.ButtonMenu; 8 | import com.jagrosh.jdautilities.menu.OrderedMenu; 9 | import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; 10 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; 11 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; 12 | import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; 13 | import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; 14 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 15 | import de.blockbuild.musikbot.Bot; 16 | import de.blockbuild.musikbot.commands.MusicCommand; 17 | import de.blockbuild.musikbot.core.TrackScheduler; 18 | 19 | import net.dv8tion.jda.api.Permission; 20 | import net.dv8tion.jda.api.entities.Message; 21 | import net.dv8tion.jda.api.exceptions.PermissionException; 22 | 23 | public class PlayCommand extends MusicCommand { 24 | 25 | private Boolean isSearch; 26 | 27 | public PlayCommand(Bot bot) { 28 | super(bot); 29 | this.name = "play"; 30 | this.aliases = new String[] { "p" }; 31 | this.help = "Shows current track or plays given track"; 32 | this.arguments = "[URL|title]"; 33 | this.joinOnCommand = true; 34 | this.isSearch = false; 35 | } 36 | 37 | @Override 38 | protected void doGuildCommand(CommandEvent event) { 39 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 40 | AudioPlayer player = musicManager.getAudioPlayer(); 41 | AudioPlayerManager playerManager = bot.getPlayerManager(); 42 | 43 | if (args.isEmpty()) { 44 | if (!event.getMessage().getAttachments().isEmpty()) { 45 | if (!event.getMessage().getAttachments().get(0).isImage()) { 46 | String TrackURL = event.getMessage().getAttachments().get(0).getUrl(); 47 | String FileName = event.getMessage().getAttachments().get(0).getFileName(); 48 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Trying to load **" + FileName + "**", m -> playerManager 49 | .loadItemOrdered(musicManager, TrackURL, new ResultHandler(trackScheduler, event, m))); 50 | } 51 | } else if (player.getPlayingTrack() == null) { 52 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", m -> { 53 | if (trackScheduler.playNextTrack()) { 54 | // If player don't play but songs are in queue 55 | // Could show the wrong track if the next song fail to load 56 | trackScheduler.messageNowPlayingTrackLong(player.getPlayingTrack(), m, null); 57 | } else { 58 | m.editMessage(event.getClient().getWarning() + " **Nothing to play at the moment!**").queue(); 59 | } 60 | }); 61 | 62 | } else { 63 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", 64 | m -> trackScheduler.messageNowPlayingTrackLong(player.getPlayingTrack(), m, null)); 65 | } 66 | } else { 67 | final String TrackUrl; 68 | if (args.startsWith("http")) { 69 | isSearch = false; 70 | TrackUrl = args; 71 | } else { 72 | isSearch = true; 73 | TrackUrl = "ytsearch:" + args; 74 | } 75 | 76 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Searching... `" + event.getArgs() + "`", m -> playerManager 77 | .loadItemOrdered(musicManager, TrackUrl, new ResultHandler(trackScheduler, event, m))); 78 | } 79 | } 80 | 81 | @Override 82 | protected void doPrivateCommand(CommandEvent event) { 83 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 84 | 85 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 86 | 87 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 88 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 89 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 90 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 91 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 92 | 93 | event.reply(builder.toString()); 94 | } 95 | 96 | private class ResultHandler implements AudioLoadResultHandler { 97 | 98 | private TrackScheduler trackScheduler; 99 | private CommandEvent event; 100 | private final Message m; 101 | 102 | public ResultHandler(TrackScheduler trackScheduler, CommandEvent event, Message m) { 103 | this.m = m; 104 | this.trackScheduler = trackScheduler; 105 | this.event = event; 106 | } 107 | 108 | @Override 109 | public void trackLoaded(AudioTrack track) { 110 | trackScheduler.messageAddTrack(track, m); 111 | trackScheduler.playTrack(track); 112 | } 113 | 114 | @Override 115 | public void playlistLoaded(AudioPlaylist playlist) { 116 | if (isSearch) { 117 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 118 | builder.append(" Click the number or type in chat to choose one of the search results:"); 119 | 120 | final OrderedMenu.Builder bbuilder = new OrderedMenu.Builder().useCancelButton(true) 121 | .allowTextInput(true).setEventWaiter(bot.getWaiter()).setTimeout(1, TimeUnit.MINUTES); 122 | bbuilder.setText(builder.toString()).setColor(event.getSelfMember().getColor()) 123 | .setChoices(new String[0]).setSelection((msg, i) -> { 124 | 125 | AudioTrack track = playlist.getTracks().get(i - 1); 126 | trackScheduler.playTrack(track); 127 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", reply -> { 128 | trackScheduler.messageAddTrack(track, reply); 129 | }); 130 | }).setUsers(event.getAuthor()); 131 | 132 | for (int i = 0; i < 5 && i < playlist.getTracks().size(); i++) { 133 | 134 | AudioTrack track = playlist.getTracks().get(i); 135 | 136 | bbuilder.addChoice("`[" + trackScheduler.getTime(track.getDuration()) + "]` [**" 137 | + track.getInfo().title + "**](" + track.getInfo().uri + ")"); 138 | } 139 | bbuilder.build().display(m); 140 | } else { 141 | final AudioTrack firstTrack = playlist.getSelectedTrack() == null ? playlist.getTracks().get(0) 142 | : playlist.getSelectedTrack(); 143 | 144 | String message = trackScheduler.messageAddTrack(firstTrack, m); 145 | trackScheduler.playTrack(firstTrack); 146 | 147 | if (event.getMember().hasPermission(event.getTextChannel(), Permission.MESSAGE_ADD_REACTION)) { 148 | 149 | StringBuilder builder = new StringBuilder(Emoji.MAG_RIGHT.getUtf8()); 150 | builder.append(" The track you provided has a playlist of **" + playlist.getTracks().size() 151 | + "** tracks attached. Select " + Emoji.THUMBSUP.getUtf8() 152 | + " to load the whole playlist."); 153 | 154 | new ButtonMenu.Builder().setText(message + "\n" + builder.toString()) 155 | .setChoices(Emoji.THUMBSUP.getUtf8(), Emoji.THUMBSDOWN.getUtf8()) 156 | .addUsers(event.getAuthor()).setEventWaiter(bot.getWaiter()) 157 | .setTimeout(30, TimeUnit.SECONDS).setAction(rem -> { 158 | 159 | if (rem.getName().equals(Emoji.THUMBSUP.getUtf8())) { 160 | loadPlaylist(playlist, firstTrack); 161 | m.editMessage(message + "\n" + Emoji.WHITE_CHECK_MARK.getUtf8() + " Added **" 162 | + (playlist.getTracks().size() - 1) + "** additional tracks to queue!") 163 | .queue(); 164 | } 165 | }).setFinalAction(m -> { 166 | try { 167 | m.clearReactions().queue(); 168 | } catch (PermissionException ignore) { 169 | } 170 | }).build().display(m); 171 | } 172 | } 173 | } 174 | 175 | private void loadPlaylist(AudioPlaylist playlist, AudioTrack exclude) { 176 | for (AudioTrack track : playlist.getTracks()) { 177 | if (!track.equals(exclude)) { 178 | trackScheduler.queueTrack(track); 179 | } 180 | } 181 | } 182 | 183 | @Override 184 | public void noMatches() { 185 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 186 | builder.append(" No result found: **").append(args).append("**"); 187 | event.reply(builder.toString()); 188 | } 189 | 190 | @Override 191 | public void loadFailed(FriendlyException throwable) { 192 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 193 | builder.append(" Faild to load **").append(args).append("**"); 194 | event.reply(builder.toString()); 195 | } 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/PlaylistCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | import com.github.breadmoirai.discordemoji.Emoji; 7 | import com.jagrosh.jdautilities.command.CommandEvent; 8 | import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; 9 | import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; 10 | import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; 11 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 12 | 13 | import de.blockbuild.musikbot.Bot; 14 | import de.blockbuild.musikbot.commands.MusicCommand; 15 | import de.blockbuild.musikbot.configuration.PlaylistConfiguration; 16 | import de.blockbuild.musikbot.core.TrackScheduler; 17 | 18 | public class PlaylistCommand extends MusicCommand { 19 | List tracks; 20 | private int amount; 21 | 22 | public PlaylistCommand(Bot bot) { 23 | super(bot); 24 | this.name = "playlist"; 25 | this.aliases = new String[] { "pl" }; 26 | this.help = "save, load, delete or list your playlists"; 27 | this.arguments = " "; 28 | this.joinOnCommand = true; 29 | } 30 | 31 | @Override 32 | protected void doGuildCommand(CommandEvent event) { 33 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 34 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 35 | 36 | String x[] = args.split(" ", 2); 37 | 38 | if (args.isEmpty() || x.length < 2) { 39 | if (args.startsWith("list") || args.startsWith("show") || args.startsWith("load")) { 40 | builder.append(" **Your Playlists:**\n"); 41 | File[] filelist = new File(bot.getMain().getDataFolder(), "/Playlists/" + user.getId() + "/") 42 | .listFiles(); 43 | if (filelist.length == 0) { 44 | builder.append("`No saved playlist.`"); 45 | } else { 46 | for (File file : filelist) { 47 | builder.append("`").append(file.getName().substring(0, file.getName().length() - 4)) 48 | .append("`\n"); 49 | } 50 | } 51 | event.reply(builder.toString()); 52 | } else { 53 | sendCommandInfo(event); 54 | } 55 | return; 56 | } 57 | 58 | String name = x[1]; 59 | PlaylistConfiguration playlist = new PlaylistConfiguration(bot, user, name); 60 | 61 | switch (x[0]) { 62 | case "save": 63 | case "create": 64 | if (musicManager.getAudioPlayer().getPlayingTrack() == null) { 65 | builder.append(" First add some tracks to the player."); 66 | event.reply(builder.toString()); 67 | return; 68 | } 69 | playlist.clearPlaylist(); 70 | playlist.addTrack(musicManager.getAudioPlayer().getPlayingTrack().getInfo().uri); 71 | playlist.addTracks(trackScheduler.getQueue()); 72 | 73 | if (playlist.writeConfig()) { 74 | builder.append(" Successfully saved playlist **").append(name).append("** containing **") 75 | .append(playlist.getAmount()).append("** Tracks"); 76 | } else { 77 | builder.append(" Failed to save playlist **").append(name).append("**"); 78 | } 79 | event.reply(builder.toString()); 80 | 81 | break; 82 | case "remove": 83 | case "delete": 84 | case "del": 85 | playlist.deleteConfig(); 86 | builder.append(" Successfully deleted: **").append(name).append("**."); 87 | event.reply(builder.toString()); 88 | 89 | break; 90 | case "load": 91 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", m -> { 92 | StringBuilder builder1 = new StringBuilder(); 93 | if (playlist.getPlaylist().isEmpty()) { 94 | builder1.append(event.getClient().getWarning()); 95 | builder1.append(" Playlist `").append(name).append("` dosen't exsist."); 96 | } else { 97 | amount = 0; 98 | for (String track : playlist.getPlaylist()) { 99 | bot.getPlayerManager().loadItemOrdered(musicManager, track, 100 | new ResultHandler(trackScheduler, event)); 101 | } 102 | 103 | builder1.append(event.getClient().getSuccess()); 104 | builder1.append(" Successfully load **").append(amount); 105 | builder1.append("** tracks from Playlist **").append(name).append("**"); 106 | } 107 | m.editMessage(builder1.toString()).queue(); 108 | }); 109 | break; 110 | case "list": 111 | case "show": 112 | builder.append(" Playlist **").append(name).append(":**\n"); 113 | for (String track : playlist.getPlaylist()) { 114 | builder.append("`").append(track).append("`\n"); 115 | } 116 | event.reply(builder.toString()); 117 | 118 | break; 119 | default: 120 | sendCommandInfo(event); 121 | break; 122 | } 123 | } 124 | 125 | @Override 126 | protected void doPrivateCommand(CommandEvent event) { 127 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 128 | 129 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 130 | 131 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 132 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 133 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 134 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 135 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 136 | 137 | event.reply(builder.toString()); 138 | } 139 | 140 | private class ResultHandler implements AudioLoadResultHandler { 141 | private TrackScheduler trackScheduler; 142 | private CommandEvent event; 143 | 144 | public ResultHandler(TrackScheduler trackScheduler, CommandEvent event) { 145 | this.trackScheduler = trackScheduler; 146 | this.event = event; 147 | } 148 | 149 | @Override 150 | public void trackLoaded(AudioTrack track) { 151 | trackScheduler.queueTrack(track); 152 | amount++; 153 | } 154 | 155 | @Override 156 | public void playlistLoaded(AudioPlaylist playlist) { 157 | // should never called 158 | } 159 | 160 | @Override 161 | public void noMatches() { 162 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 163 | builder.append(" No result found: **").append(args).append("**"); 164 | event.reply(builder.toString()); 165 | } 166 | 167 | @Override 168 | public void loadFailed(FriendlyException throwable) { 169 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 170 | builder.append(" Faild to load **").append(args).append("**"); 171 | event.reply(builder.toString()); 172 | } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/PushCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; 5 | import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; 6 | import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; 7 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 8 | 9 | import de.blockbuild.musikbot.Bot; 10 | import de.blockbuild.musikbot.commands.MBCommand; 11 | import de.blockbuild.musikbot.core.TrackScheduler; 12 | 13 | import net.dv8tion.jda.api.entities.Message; 14 | 15 | public class PushCommand extends MBCommand { 16 | 17 | public PushCommand(Bot bot) { 18 | super(bot); 19 | this.name = "push"; 20 | // this.aliases = new String[] { "" }; 21 | this.help = "Plays a given track and queues the current playing track"; 22 | // this.arguments = ""; 23 | this.joinOnCommand = true; 24 | } 25 | 26 | @Override 27 | protected void doGuildCommand(CommandEvent event) { 28 | 29 | } 30 | 31 | @Override 32 | protected void doPrivateCommand(CommandEvent event) { 33 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 34 | 35 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 36 | 37 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 38 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 39 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 40 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 41 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 42 | 43 | event.reply(builder.toString()); 44 | } 45 | 46 | private class ResultHandler implements AudioLoadResultHandler { 47 | 48 | private TrackScheduler trackScheduler; 49 | private CommandEvent event; 50 | final private Message m; 51 | 52 | public ResultHandler(TrackScheduler trackScheduler, CommandEvent event, Message m) { 53 | this.trackScheduler = trackScheduler; 54 | this.event = event; 55 | this.m = m; 56 | } 57 | 58 | @Override 59 | public void trackLoaded(AudioTrack track) { 60 | } 61 | 62 | @Override 63 | public void playlistLoaded(AudioPlaylist playlist) { 64 | } 65 | 66 | @Override 67 | public void noMatches() { 68 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 69 | builder.append(" No result found: **").append(args).append("**"); 70 | event.reply(builder.toString()); 71 | } 72 | 73 | @Override 74 | public void loadFailed(FriendlyException throwable) { 75 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 76 | builder.append(" Faild to load **").append(args).append("**"); 77 | event.reply(builder.toString()); 78 | } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/QueueCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import java.util.List; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | import com.github.breadmoirai.discordemoji.Emoji; 7 | import com.jagrosh.jdautilities.command.CommandEvent; 8 | import com.jagrosh.jdautilities.menu.ButtonMenu; 9 | import com.jagrosh.jdautilities.menu.OrderedMenu; 10 | import com.jagrosh.jdautilities.menu.Paginator; 11 | import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; 12 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; 13 | import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; 14 | import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; 15 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 16 | 17 | import de.blockbuild.musikbot.Bot; 18 | import de.blockbuild.musikbot.commands.MusicCommand; 19 | import de.blockbuild.musikbot.core.TrackScheduler; 20 | 21 | import net.dv8tion.jda.api.Permission; 22 | import net.dv8tion.jda.api.entities.Message; 23 | import net.dv8tion.jda.api.exceptions.PermissionException; 24 | 25 | public class QueueCommand extends MusicCommand { 26 | 27 | private Boolean isSearch; 28 | 29 | public QueueCommand(Bot bot) { 30 | super(bot); 31 | this.name = "queue"; 32 | this.aliases = new String[] { "q" }; 33 | this.help = "Returns the playlist or adds the given track to queue."; 34 | this.arguments = "[URL|title]"; 35 | this.joinOnCommand = true; 36 | this.isSearch = false; 37 | } 38 | 39 | @Override 40 | protected void doGuildCommand(CommandEvent event) { 41 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 42 | AudioPlayerManager playerManager = bot.getPlayerManager(); 43 | 44 | if (args.isEmpty()) { 45 | if (!event.getMessage().getAttachments().isEmpty()) { 46 | // Add track to queue 47 | if (!event.getMessage().getAttachments().get(0).isImage()) { 48 | String TrackURL = event.getMessage().getAttachments().get(0).getUrl(); 49 | String FileName = event.getMessage().getAttachments().get(0).getFileName(); 50 | 51 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Trying to load **" + FileName + "**", m -> playerManager 52 | .loadItemOrdered(musicManager, TrackURL, new ResultHandler(trackScheduler, event, m))); 53 | } 54 | } else { 55 | if (trackScheduler.isQueueEmpty()) { 56 | // If the queue is empty 57 | event.reply(Emoji.NOTEPAD_SPIRAL.getUtf8() + " **Queued tracks:**\n`No tracks Queued!`"); 58 | } else { 59 | // List queued Tracks 60 | List tracks = trackScheduler.getQueue(); 61 | long time = 0; 62 | 63 | Paginator.Builder pbuilder = new Paginator.Builder().setEventWaiter(bot.getWaiter()) 64 | .setColor(event.getSelfMember().getColor()).setItemsPerPage(15).waitOnSinglePage(true) 65 | .wrapPageEnds(true).setTimeout(2, TimeUnit.MINUTES).setItems(new String[0]) 66 | .showPageNumbers(true).useNumberedItems(true); 67 | 68 | for (AudioTrack track : tracks) { 69 | pbuilder.addItems("`[" + trackScheduler.getTime(track.getDuration()) + "]` [**" 70 | + track.getInfo().title + "**](" + track.getInfo().uri + ")"); 71 | time += track.getDuration(); 72 | } 73 | 74 | pbuilder.setText(Emoji.NOTEPAD_SPIRAL.getUtf8() + " **Queued tracks:**\n" + Emoji.NOTES.getUtf8() 75 | + " Current queue **[** `" + tracks.size() + " Tracks` **|** `" 76 | + trackScheduler.getTimeBig(time) + "` **]**"); 77 | 78 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", m -> pbuilder.build().display(m)); 79 | } 80 | } 81 | } else { 82 | // Load search or URL 83 | final String TrackUrl; 84 | if (args.startsWith("http")) { 85 | isSearch = false; 86 | TrackUrl = args; 87 | } else { 88 | isSearch = true; 89 | TrackUrl = "ytsearch:" + args; 90 | } 91 | 92 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Searching... `" + event.getArgs() + "`", m -> playerManager 93 | .loadItemOrdered(musicManager, TrackUrl, new ResultHandler(trackScheduler, event, m))); 94 | } 95 | } 96 | 97 | @Override 98 | protected void doPrivateCommand(CommandEvent event) { 99 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 100 | 101 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 102 | 103 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 104 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 105 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 106 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 107 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 108 | 109 | event.reply(builder.toString()); 110 | } 111 | 112 | private class ResultHandler implements AudioLoadResultHandler { 113 | 114 | private TrackScheduler trackScheduler; 115 | private CommandEvent event; 116 | private final Message m; 117 | 118 | public ResultHandler(TrackScheduler trackScheduler, CommandEvent event, Message m) { 119 | this.trackScheduler = trackScheduler; 120 | this.event = event; 121 | this.m = m; 122 | } 123 | 124 | @Override 125 | public void trackLoaded(AudioTrack track) { 126 | int pos = trackScheduler.queueTrack(track); 127 | if (pos == 0) { 128 | trackScheduler.messageAddTrack(track, m); 129 | } else { 130 | trackScheduler.messageQueueTrack(track, m, pos); 131 | } 132 | } 133 | 134 | @Override 135 | public void playlistLoaded(AudioPlaylist playlist) { 136 | if (isSearch) { 137 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 138 | builder.append(" Click the number or type in chat to choose one of the search results:"); 139 | 140 | final OrderedMenu.Builder bbuilder = new OrderedMenu.Builder().useCancelButton(true) 141 | .allowTextInput(true).setEventWaiter(bot.getWaiter()).setTimeout(1, TimeUnit.MINUTES); 142 | bbuilder.setText(builder.toString()).setColor(event.getSelfMember().getColor()) 143 | .setChoices(new String[0]).setSelection((msg, i) -> { 144 | 145 | AudioTrack track = playlist.getTracks().get(i - 1); 146 | int pos = trackScheduler.queueTrack(track); 147 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", reply -> { 148 | if (pos == 0) { 149 | trackScheduler.messageAddTrack(track, reply); 150 | } else { 151 | trackScheduler.messageQueueTrack(track, reply, pos); 152 | } 153 | }); 154 | }).setUsers(event.getAuthor()); 155 | 156 | for (int i = 0; i < 5 && i < playlist.getTracks().size(); i++) { 157 | 158 | AudioTrack track = playlist.getTracks().get(i); 159 | 160 | bbuilder.addChoice("`[" + trackScheduler.getTime(track.getDuration()) + "]` [**" 161 | + track.getInfo().title + "**](" + track.getInfo().uri + ")"); 162 | } 163 | bbuilder.build().display(m); 164 | } else { 165 | final AudioTrack firstTrack = playlist.getSelectedTrack() == null ? playlist.getTracks().get(0) 166 | : playlist.getSelectedTrack(); 167 | 168 | int pos = trackScheduler.queueTrack(firstTrack); 169 | String message = pos == 0 ? trackScheduler.messageAddTrack(firstTrack, m) 170 | : trackScheduler.messageQueueTrack(firstTrack, m, pos); 171 | 172 | if (event.getMember().hasPermission(event.getTextChannel(), Permission.MESSAGE_ADD_REACTION)) { 173 | 174 | StringBuilder builder = new StringBuilder(Emoji.MAG_RIGHT.getUtf8()); 175 | builder.append(" The track you provided has a playlist of **" + playlist.getTracks().size() 176 | + "** tracks attached. Select " + Emoji.THUMBSUP.getUtf8() 177 | + " to queue the whole playlist."); 178 | 179 | new ButtonMenu.Builder().setText(message + "\n" + builder.toString()) 180 | .setChoices(Emoji.THUMBSUP.getUtf8(), Emoji.THUMBSDOWN.getUtf8()) 181 | .addUsers(event.getAuthor()).setEventWaiter(bot.getWaiter()) 182 | .setTimeout(30, TimeUnit.SECONDS).setAction(rem -> { 183 | 184 | if (rem.getName().equals(Emoji.THUMBSUP.getUtf8())) { 185 | loadPlaylist(playlist, firstTrack); 186 | m.editMessage(message + "\n" + Emoji.WHITE_CHECK_MARK.getUtf8() + " Added **" 187 | + (playlist.getTracks().size() - 1) + "** additional tracks to queue!") 188 | .queue(); 189 | } 190 | }).setFinalAction(m -> { 191 | try { 192 | m.clearReactions().queue(); 193 | } catch (PermissionException ignore) { 194 | } 195 | }).build().display(m); 196 | } 197 | } 198 | } 199 | 200 | private void loadPlaylist(AudioPlaylist playlist, AudioTrack exclude) { 201 | for (AudioTrack track : playlist.getTracks()) { 202 | if (!track.equals(exclude)) { 203 | trackScheduler.queueTrack(track); 204 | } 205 | } 206 | } 207 | 208 | @Override 209 | public void noMatches() { 210 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 211 | builder.append(" No result found: **").append(args).append("**"); 212 | event.reply(builder.toString()); 213 | } 214 | 215 | @Override 216 | public void loadFailed(FriendlyException throwable) { 217 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 218 | builder.append(" Faild to load **").append(args).append("**"); 219 | event.reply(builder.toString()); 220 | } 221 | } 222 | } -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/ShuffleCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import com.github.breadmoirai.discordemoji.Emoji; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | 6 | import de.blockbuild.musikbot.Bot; 7 | import de.blockbuild.musikbot.commands.MusicCommand; 8 | import de.blockbuild.musikbot.core.TrackScheduler; 9 | 10 | public class ShuffleCommand extends MusicCommand { 11 | 12 | public ShuffleCommand(Bot bot) { 13 | super(bot); 14 | this.name = "shuffle"; 15 | this.help = "Shuffles the playlist"; 16 | } 17 | 18 | @Override 19 | protected void doGuildCommand(CommandEvent event) { 20 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 21 | 22 | StringBuilder builder = new StringBuilder(); 23 | if (trackScheduler.isQueueEmpty()) { 24 | builder.append(event.getClient().getWarning()).append(" The queue is empty!"); 25 | } else { 26 | trackScheduler.shuffle(); 27 | builder.append(Emoji.TWISTED_RIGHTWARDS_ARROWS.getUtf8()); 28 | builder.append(" Queue shuffled!"); 29 | } 30 | event.reply(builder.toString()); 31 | } 32 | 33 | @Override 34 | protected void doPrivateCommand(CommandEvent event) { 35 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 36 | 37 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 38 | 39 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 40 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 41 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 42 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 43 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 44 | 45 | event.reply(builder.toString()); 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/SkipCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import com.github.breadmoirai.discordemoji.Emoji; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; 6 | 7 | import de.blockbuild.musikbot.Bot; 8 | import de.blockbuild.musikbot.commands.MusicCommand; 9 | import de.blockbuild.musikbot.core.TrackScheduler; 10 | 11 | public class SkipCommand extends MusicCommand { 12 | 13 | public SkipCommand(Bot bot) { 14 | super(bot); 15 | this.name = "skip"; 16 | this.aliases = new String[] { "s", "sk" }; 17 | this.help = "Skips the track"; 18 | this.arguments = "[Amount]"; 19 | this.joinOnCommand = true; 20 | } 21 | 22 | @Override 23 | protected void doGuildCommand(CommandEvent event) { 24 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 25 | AudioPlayer player = musicManager.getAudioPlayer(); 26 | 27 | if (!(args.isEmpty())) { 28 | int i = 0; 29 | try { 30 | i = Integer.parseInt(args); 31 | } catch (Exception e) { 32 | // no integer 33 | } finally { 34 | if (i > 0) { 35 | int num = trackScheduler.flushQueue(i - 1); 36 | StringBuilder builder = new StringBuilder(event.getClient().getSuccess()); 37 | builder.append(" **").append(num + 1).append("** tracks got skipped!"); 38 | 39 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", m -> { 40 | if (trackScheduler.playNextTrack()) { 41 | trackScheduler.messageNowPlayingTrackLong(player.getPlayingTrack(), m, builder.toString()); 42 | } else { 43 | builder.append("\n") 44 | .append(event.getClient().getWarning() + " **Nothing to play at the moment!**"); 45 | m.editMessage(builder.toString()).queue(); 46 | } 47 | }); 48 | } else { 49 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 50 | builder.append(" The number must be greater than zero!"); 51 | event.reply(builder.toString()); 52 | } 53 | } 54 | } else { 55 | if (trackScheduler.playNextTrack()) { 56 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", 57 | m -> trackScheduler.messageNowPlayingTrackLong(player.getPlayingTrack(), m, null)); 58 | } else { 59 | event.reply(event.getClient().getWarning() + " **Nothing to play at the moment!**"); 60 | } 61 | } 62 | 63 | } 64 | 65 | @Override 66 | protected void doPrivateCommand(CommandEvent event) { 67 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 68 | 69 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 70 | 71 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 72 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 73 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 74 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 75 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 76 | 77 | event.reply(builder.toString()); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/StopCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.MusicCommand; 7 | import de.blockbuild.musikbot.core.TrackScheduler; 8 | 9 | public class StopCommand extends MusicCommand { 10 | 11 | public StopCommand(Bot bot) { 12 | super(bot); 13 | this.name = "stop"; 14 | this.help = "Stops playback"; 15 | } 16 | 17 | @Override 18 | protected void doGuildCommand(CommandEvent event) { 19 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 20 | trackScheduler.stopTrack(); 21 | } 22 | 23 | @Override 24 | protected void doPrivateCommand(CommandEvent event) { 25 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 26 | 27 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 28 | 29 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 30 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 31 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 32 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 33 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 34 | 35 | event.reply(builder.toString()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/VolumeCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import com.github.breadmoirai.discordemoji.Emoji; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | 6 | import de.blockbuild.musikbot.Bot; 7 | import de.blockbuild.musikbot.commands.MusicCommand; 8 | 9 | public class VolumeCommand extends MusicCommand { 10 | 11 | public VolumeCommand(Bot bot) { 12 | super(bot); 13 | this.name = "volume"; 14 | this.aliases = new String[] { "vol", "v" }; 15 | this.help = "Changes the volume."; 16 | this.arguments = "[0-150]"; 17 | } 18 | 19 | @Override 20 | protected void doGuildCommand(CommandEvent event) { 21 | if (args.isEmpty()) { 22 | StringBuilder builder = new StringBuilder(event.getClient().getSuccess()); 23 | builder.append(" Current volume is `").append(musicManager.getVolume()).append("`."); 24 | event.reply(builder.toString()); 25 | } else { 26 | int volume; 27 | try { 28 | volume = Integer.parseInt(args); 29 | } catch (NumberFormatException e) { 30 | volume = -1; 31 | } 32 | StringBuilder builder = new StringBuilder(); 33 | if (volume < 0 || volume > 150) { 34 | builder.append(event.getClient().getError()); 35 | builder.append(" Volume must be a valid integer between `0` and `150`!"); 36 | } else { 37 | musicManager.setVolume(volume); 38 | builder.append(volume < 50 ? Emoji.SOUND.getUtf8() : Emoji.LOUD_SOUND.getUtf8()); 39 | builder.append(" Volume now set to `").append(volume).append("`."); 40 | } 41 | event.reply(builder.toString()); 42 | } 43 | } 44 | 45 | @Override 46 | protected void doPrivateCommand(CommandEvent event) { 47 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 48 | 49 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 50 | 51 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 52 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 53 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 54 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 55 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 56 | 57 | event.reply(builder.toString()); 58 | } 59 | } -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/music/YTAutoPlayCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.music; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.MusicCommand; 7 | 8 | public class YTAutoPlayCommand extends MusicCommand { 9 | public YTAutoPlayCommand(Bot bot) { 10 | super(bot); 11 | this.name = "autoplay"; 12 | this.aliases = new String[] { "ytautoplay", "ap", "yap" }; 13 | this.help = "Enable or disable Youtube autoplay"; 14 | this.arguments = ""; 15 | this.joinOnCommand = true; 16 | } 17 | 18 | @Override 19 | protected void doGuildCommand(CommandEvent event) { 20 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 21 | 22 | if (args.equalsIgnoreCase("enable")) { 23 | musicManager.setIsAutoPlay(true); 24 | builder.append(" YouTube autoplay: `enabled`"); 25 | } else if (args.equalsIgnoreCase("disable")) { 26 | musicManager.setIsAutoPlay(false); 27 | builder.append(" YouTube autoplay: `disabled`"); 28 | } else { 29 | sendCommandInfo(event); 30 | return; 31 | } 32 | event.reply(builder.toString()); 33 | } 34 | 35 | @Override 36 | protected void doPrivateCommand(CommandEvent event) { 37 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 38 | 39 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 40 | 41 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 42 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 43 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 44 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 45 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 46 | 47 | event.reply(builder.toString()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/radio/Radio100nlCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.radio; 2 | 3 | import com.github.breadmoirai.discordemoji.Emoji; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; 6 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; 7 | import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; 8 | import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; 9 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 10 | 11 | import de.blockbuild.musikbot.Bot; 12 | import de.blockbuild.musikbot.commands.RadioCommand; 13 | import de.blockbuild.musikbot.core.TrackScheduler; 14 | 15 | import net.dv8tion.jda.api.entities.Message; 16 | 17 | public class Radio100nlCommand extends RadioCommand { 18 | public Radio100nlCommand(Bot bot) { 19 | super(bot); 20 | this.name = "radio100%nl"; 21 | this.aliases = new String[] { "100%nl" }; 22 | this.help = "Streams Radio 100%NL!"; 23 | this.joinOnCommand = true; 24 | } 25 | 26 | @Override 27 | protected void doGuildCommand(CommandEvent event) { 28 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 29 | AudioPlayerManager playerManager = bot.getPlayerManager(); 30 | 31 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", m -> playerManager.loadItemOrdered(musicManager, 32 | "https://stream.100p.nl/100pctnl.mp3", new ResultHandler(trackScheduler, event, m))); 33 | } 34 | 35 | @Override 36 | protected void doPrivateCommand(CommandEvent event) { 37 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 38 | 39 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 40 | 41 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 42 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 43 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 44 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 45 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 46 | 47 | event.reply(builder.toString()); 48 | } 49 | 50 | private class ResultHandler implements AudioLoadResultHandler { 51 | 52 | private TrackScheduler trackScheduler; 53 | private CommandEvent event; 54 | final private Message m; 55 | 56 | public ResultHandler(TrackScheduler trackScheduler, CommandEvent event, Message m) { 57 | this.trackScheduler = trackScheduler; 58 | this.event = event; 59 | this.m = m; 60 | } 61 | 62 | @Override 63 | public void trackLoaded(AudioTrack track) { 64 | trackScheduler.playTrack(track); 65 | trackScheduler.messageAddTrack(track, m); 66 | } 67 | 68 | @Override 69 | public void playlistLoaded(AudioPlaylist playlist) { 70 | // should never called 71 | } 72 | 73 | @Override 74 | public void noMatches() { 75 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 76 | builder.append(" No result found: **").append(args).append("**"); 77 | event.reply(builder.toString()); 78 | } 79 | 80 | @Override 81 | public void loadFailed(FriendlyException throwable) { 82 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 83 | builder.append(" Faild to load **").append(args).append("**"); 84 | event.reply(builder.toString()); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/radio/RadioBobCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.radio; 2 | 3 | import com.github.breadmoirai.discordemoji.Emoji; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; 6 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; 7 | import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; 8 | import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; 9 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 10 | 11 | import de.blockbuild.musikbot.Bot; 12 | import de.blockbuild.musikbot.commands.RadioCommand; 13 | import de.blockbuild.musikbot.core.TrackScheduler; 14 | 15 | import net.dv8tion.jda.api.entities.Message; 16 | 17 | public class RadioBobCommand extends RadioCommand { 18 | 19 | public RadioBobCommand(Bot bot) { 20 | super(bot); 21 | this.name = "radiobob"; 22 | this.aliases = new String[] { "rb", "bob" }; 23 | this.help = "Streams RadioBob!"; 24 | this.joinOnCommand = true; 25 | } 26 | 27 | @Override 28 | protected void doGuildCommand(CommandEvent event) { 29 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 30 | AudioPlayerManager playerManager = bot.getPlayerManager(); 31 | 32 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", 33 | m -> playerManager.loadItemOrdered(musicManager, 34 | "http://streams.radiobob.de/bob-live/mp3-192/mediaplayer", 35 | new ResultHandler(trackScheduler, event, m))); 36 | } 37 | 38 | @Override 39 | protected void doPrivateCommand(CommandEvent event) { 40 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 41 | 42 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 43 | 44 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 45 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 46 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 47 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 48 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 49 | 50 | event.reply(builder.toString()); 51 | } 52 | 53 | private class ResultHandler implements AudioLoadResultHandler { 54 | 55 | private TrackScheduler trackScheduler; 56 | private CommandEvent event; 57 | final private Message m; 58 | 59 | public ResultHandler(TrackScheduler trackScheduler, CommandEvent event, Message m) { 60 | this.trackScheduler = trackScheduler; 61 | this.event = event; 62 | this.m = m; 63 | } 64 | 65 | @Override 66 | public void trackLoaded(AudioTrack track) { 67 | trackScheduler.playTrack(track); 68 | trackScheduler.messageAddTrack(track, m); 69 | } 70 | 71 | @Override 72 | public void playlistLoaded(AudioPlaylist playlist) { 73 | // should never called 74 | } 75 | 76 | @Override 77 | public void noMatches() { 78 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 79 | builder.append(" No result found: **").append(args).append("**"); 80 | event.reply(builder.toString()); 81 | } 82 | 83 | @Override 84 | public void loadFailed(FriendlyException throwable) { 85 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 86 | builder.append(" Faild to load **").append(args).append("**"); 87 | event.reply(builder.toString()); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/radio/RadioBonnRheinSiegCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.radio; 2 | 3 | import com.github.breadmoirai.discordemoji.Emoji; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; 6 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; 7 | import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; 8 | import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; 9 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 10 | 11 | import de.blockbuild.musikbot.Bot; 12 | import de.blockbuild.musikbot.commands.RadioCommand; 13 | import de.blockbuild.musikbot.core.TrackScheduler; 14 | 15 | import net.dv8tion.jda.api.entities.Message; 16 | 17 | public class RadioBonnRheinSiegCommand extends RadioCommand { 18 | 19 | public RadioBonnRheinSiegCommand(Bot bot) { 20 | super(bot); 21 | this.name = "radiobonnrheinsieg"; 22 | this.aliases = new String[] { "rbrs" }; 23 | this.help = "Streams RadioBonnRheinSieg!"; 24 | this.joinOnCommand = true; 25 | } 26 | 27 | @Override 28 | protected void doGuildCommand(CommandEvent event) { 29 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 30 | AudioPlayerManager playerManager = bot.getPlayerManager(); 31 | 32 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", m -> playerManager.loadItemOrdered(musicManager, 33 | "http://stream.lokalradio.nrw/rbrs", new ResultHandler(trackScheduler, event, m))); 34 | } 35 | 36 | @Override 37 | protected void doPrivateCommand(CommandEvent event) { 38 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 39 | 40 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 41 | 42 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 43 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 44 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 45 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 46 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 47 | 48 | event.reply(builder.toString()); 49 | } 50 | 51 | private class ResultHandler implements AudioLoadResultHandler { 52 | 53 | private TrackScheduler trackScheduler; 54 | private CommandEvent event; 55 | final private Message m; 56 | 57 | public ResultHandler(TrackScheduler trackScheduler, CommandEvent event, Message m) { 58 | this.trackScheduler = trackScheduler; 59 | this.event = event; 60 | this.m = m; 61 | } 62 | 63 | @Override 64 | public void trackLoaded(AudioTrack track) { 65 | trackScheduler.playTrack(track); 66 | trackScheduler.messageAddTrack(track, m); 67 | } 68 | 69 | @Override 70 | public void playlistLoaded(AudioPlaylist playlist) { 71 | // should never called 72 | } 73 | 74 | @Override 75 | public void noMatches() { 76 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 77 | builder.append(" No result found: **").append(args).append("**"); 78 | event.reply(builder.toString()); 79 | } 80 | 81 | @Override 82 | public void loadFailed(FriendlyException throwable) { 83 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 84 | builder.append(" Faild to load **").append(args).append("**"); 85 | event.reply(builder.toString()); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/radio/RadioMnmCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.radio; 2 | 3 | import com.github.breadmoirai.discordemoji.Emoji; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; 6 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; 7 | import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; 8 | import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; 9 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 10 | 11 | import de.blockbuild.musikbot.Bot; 12 | import de.blockbuild.musikbot.commands.RadioCommand; 13 | import de.blockbuild.musikbot.core.TrackScheduler; 14 | 15 | import net.dv8tion.jda.api.entities.Message; 16 | 17 | public class RadioMnmCommand extends RadioCommand { 18 | 19 | public RadioMnmCommand(Bot bot) { 20 | super(bot); 21 | this.name = "radiomnm"; 22 | this.aliases = new String[] { "mnm" }; 23 | this.help = "Streams Mnm!"; 24 | this.joinOnCommand = true; 25 | } 26 | 27 | @Override 28 | protected void doGuildCommand(CommandEvent event) { 29 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 30 | AudioPlayerManager playerManager = bot.getPlayerManager(); 31 | 32 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", m -> playerManager.loadItemOrdered(musicManager, 33 | "http://icecast.vrtcdn.be/mnm-high.mp3", new ResultHandler(trackScheduler, event, m))); 34 | } 35 | 36 | @Override 37 | protected void doPrivateCommand(CommandEvent event) { 38 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 39 | 40 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 41 | 42 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 43 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 44 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 45 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 46 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 47 | 48 | event.reply(builder.toString()); 49 | } 50 | 51 | private class ResultHandler implements AudioLoadResultHandler { 52 | 53 | private TrackScheduler trackScheduler; 54 | private CommandEvent event; 55 | final private Message m; 56 | 57 | public ResultHandler(TrackScheduler trackScheduler, CommandEvent event, Message m) { 58 | this.trackScheduler = trackScheduler; 59 | this.event = event; 60 | this.m = m; 61 | } 62 | 63 | @Override 64 | public void trackLoaded(AudioTrack track) { 65 | trackScheduler.playTrack(track); 66 | trackScheduler.messageAddTrack(track, m); 67 | } 68 | 69 | @Override 70 | public void playlistLoaded(AudioPlaylist playlist) { 71 | // should never called 72 | } 73 | 74 | @Override 75 | public void noMatches() { 76 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 77 | builder.append(" No result found: **").append(args).append("**"); 78 | event.reply(builder.toString()); 79 | } 80 | 81 | @Override 82 | public void loadFailed(FriendlyException throwable) { 83 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 84 | builder.append(" Faild to load **").append(args).append("**"); 85 | event.reply(builder.toString()); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/radio/RautemusikCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.radio; 2 | 3 | import com.github.breadmoirai.discordemoji.Emoji; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; 6 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; 7 | import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; 8 | import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; 9 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 10 | 11 | import de.blockbuild.musikbot.Bot; 12 | import de.blockbuild.musikbot.commands.RadioCommand; 13 | import de.blockbuild.musikbot.core.TrackScheduler; 14 | 15 | import net.dv8tion.jda.api.entities.Message; 16 | 17 | public class RautemusikCommand extends RadioCommand { 18 | 19 | public RautemusikCommand(Bot bot) { 20 | super(bot); 21 | this.name = "rautemusik"; 22 | this.aliases = new String[] { "raute", "main", "#" }; 23 | this.help = "Streams Rautemusik!"; 24 | this.arguments = "<12punks | 90s | BigCityBeats | BreakZ.FM | ChartHits | Christmas | Club | DAS Coachingradio | Country | Deutschrap | Goldies | Globalize Yourself Stereo/gyr | Happy | HappyHardcore | HardeR | House | JaM | Kids | Klassik | Lounge | LoveHits | Main | Oriental | PartyHits | Rock | Salsa | Schlager | Sex | Solo Piano | Study | TechHouse | Top40 | Trance | Trap | Traurig | Volksmusik | Wacken Radio | Weihnachten | Workout>"; 25 | this.joinOnCommand = true; 26 | } 27 | 28 | @Override 29 | protected void doGuildCommand(CommandEvent event) { 30 | TrackScheduler trackScheduler = musicManager.getTrackScheduler(); 31 | AudioPlayerManager playerManager = bot.getPlayerManager(); 32 | if (args.isEmpty()) { 33 | if (event.getMessage().getContentDisplay().trim().toLowerCase().startsWith("main", 1)) { 34 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", m -> playerManager.loadItemOrdered(musicManager, 35 | "http://main-high.rautemusik.fm/listen.mp3", new ResultHandler(trackScheduler, event, m))); 36 | } else { 37 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 38 | builder.append(" ").append(this.arguments); 39 | event.reply(builder.toString()); 40 | } 41 | } else { 42 | String link; 43 | 44 | switch (args.toLowerCase()) { 45 | case "12punks": 46 | link = "http://12punks-high.rautemusik.fm/listen.mp3"; 47 | break; 48 | case "90s": 49 | link = "http://90s-high.rautemusik.fm/listen.mp3"; 50 | break; 51 | case "bigcitybeats": 52 | link = "http://bcb-high.rautemusik.fm/listen.mp3"; 53 | break; 54 | case "breakz.fm": 55 | link = "http://breakz-high.rautemusik.fm/listen.mp3"; 56 | break; 57 | case "charthits": 58 | link = "http://charthits-high.rautemusik.fm/listen.mp3"; 59 | break; 60 | case "christmas": 61 | link = "http://christmas-high.rautemusik.fm/listen.mp3"; 62 | break; 63 | case "club": 64 | link = "http://club-high.rautemusik.fm/listen.mp3"; 65 | break; 66 | case "das coachingradio": 67 | link = "http://coaching-high.rautemusik.fm/listen.mp3"; 68 | break; 69 | case "country": 70 | link = "http://country-high.rautemusik.fm/listen.mp3"; 71 | break; 72 | case "deutschrap": 73 | link = "http://deutschrap-high.rautemusik.fm/listen.mp3"; 74 | break; 75 | case "goldies": 76 | link = "http://goldies-high.rautemusik.fm/listen.mp3"; 77 | break; 78 | case "globalize yourself stereo": 79 | link = "http://gys-high.rautemusik.fm/listen.mp3"; 80 | break; 81 | case "gys": 82 | link = "http://gys-high.rautemusik.fm/listen.mp3"; 83 | break; 84 | case "happy": 85 | link = "http://happy-high.rautemusik.fm/listen.mp3"; 86 | break; 87 | case "happyhardcore": 88 | link = "http://happyhardcore-high.rautemusik.fm/listen.mp3"; 89 | break; 90 | case "harder": 91 | link = "http://harder-high.rautemusik.fm/listen.mp3"; 92 | break; 93 | case "house": 94 | link = "http://house-high.rautemusik.fm/listen.mp3"; 95 | break; 96 | case "jak": 97 | link = "http://jam-high.rautemusik.fm/listen.mp3"; 98 | break; 99 | case "kids": 100 | link = "http://kids-high.rautemusik.fm/listen.mp3"; 101 | break; 102 | case "klassik": 103 | link = "http://klassik-high.rautemusik.fm/listen.mp3"; 104 | break; 105 | case "lounge": 106 | link = "http://lounge-high.rautemusik.fm/listen.mp3"; 107 | break; 108 | case "lovehits": 109 | link = "http://lovehits-high.rautemusik.fm//listen.mp3"; 110 | break; 111 | case "main": 112 | link = "http://main-high.rautemusik.fm/listen.mp3"; 113 | break; 114 | case "oriental": 115 | link = "http://oriental-high.rautemusik.fm/listen.mp3"; 116 | break; 117 | case "partyhits": 118 | link = "http://partyhits-high.rautemusik.fm/listen.mp3"; 119 | break; 120 | case "rock": 121 | link = "http://rock-high.rautemusik.fm/listen.mp3"; 122 | break; 123 | case "salsa": 124 | link = "http://salsa-high.rautemusik.fm/listen.mp3"; 125 | break; 126 | case "schlager": 127 | link = "http://schlager-high.rautemusik.fm/listen.mp3"; 128 | break; 129 | case "sex": 130 | link = "http://sex-high.rautemusik.fm/listen.mp3"; 131 | break; 132 | case "solo piano": 133 | link = "http://solopiano-high.rautemusik.fm/listen.mp3"; 134 | break; 135 | case "study": 136 | link = "http://study-high.rautemusik.fm/listen.mp3"; 137 | break; 138 | case "techHouse": 139 | link = "http://techhouse-high.rautemusik.fm/listen.mp3"; 140 | break; 141 | case "top40": 142 | link = "http://top40-high.rautemusik.fm/listen.mp3"; 143 | break; 144 | case "trance": 145 | link = "http://trance-high.rautemusik.fm/listen.mp3"; 146 | break; 147 | case "trap": 148 | link = "http://trap-high.rautemusik.fm/listen.mp3"; 149 | break; 150 | case "traurig": 151 | link = "http://traurig-high.rautemusik.fm/listen.mp3"; 152 | break; 153 | case "volksmusik": 154 | link = "http://volksmusik-high.rautemusik.fm/listen.mp3"; 155 | break; 156 | case "wacken radio": 157 | link = "http://wackenradio-high.rautemusik.fm/listen.mp3"; 158 | break; 159 | case "weihnachten": 160 | link = "http://weihnachten-high.rautemusik.fm/listen.mp3"; 161 | break; 162 | case "workout": 163 | link = "http://workout-high.rautemusik.fm/listen.mp3"; 164 | break; 165 | 166 | default: 167 | link = null; 168 | break; 169 | } 170 | 171 | if (!(link == null)) { 172 | event.reply(Emoji.MAG_RIGHT.getUtf8() + " Loading...", m -> playerManager.loadItemOrdered(playerManager, 173 | link, new ResultHandler(trackScheduler, event, m))); 174 | } else { 175 | StringBuilder builder = new StringBuilder(event.getClient().getWarning()); 176 | builder.append(" **").append(args).append("** Isn't a vaild radio station"); 177 | event.reply(builder.toString()); 178 | } 179 | } 180 | } 181 | 182 | @Override 183 | protected void doPrivateCommand(CommandEvent event) { 184 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 185 | 186 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 187 | 188 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 189 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 190 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 191 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 192 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 193 | 194 | event.reply(builder.toString()); 195 | } 196 | 197 | private class ResultHandler implements AudioLoadResultHandler { 198 | 199 | private TrackScheduler trackScheduler; 200 | private CommandEvent event; 201 | final private Message m; 202 | 203 | public ResultHandler(TrackScheduler trackScheduler, CommandEvent event, Message m) { 204 | this.trackScheduler = trackScheduler; 205 | this.event = event; 206 | this.m = m; 207 | } 208 | 209 | @Override 210 | public void trackLoaded(AudioTrack track) { 211 | trackScheduler.playTrack(track); 212 | trackScheduler.messageAddTrack(track, m); 213 | } 214 | 215 | @Override 216 | public void playlistLoaded(AudioPlaylist playlist) { 217 | // should never called 218 | } 219 | 220 | @Override 221 | public void noMatches() { 222 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 223 | builder.append(" No result found: **").append(args).append("**"); 224 | event.reply(builder.toString()); 225 | } 226 | 227 | @Override 228 | public void loadFailed(FriendlyException throwable) { 229 | StringBuilder builder = new StringBuilder(event.getClient().getError()); 230 | builder.append(" Faild to load **").append(args).append("**"); 231 | event.reply(builder.toString()); 232 | } 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/setup/AutoConnectCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.setup; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.SetupCommand; 7 | 8 | public class AutoConnectCommand extends SetupCommand { 9 | 10 | public AutoConnectCommand(Bot bot) { 11 | super(bot); 12 | this.name = "autoconnect"; 13 | this.help = "set's auto connect option's in config"; 14 | this.arguments = " [voicechannelid|URL|clear]"; 15 | } 16 | 17 | @Override 18 | protected void doGuildCommand(CommandEvent event) { 19 | if (args.isEmpty()) { 20 | sendCommandInfo(event); 21 | return; 22 | } 23 | 24 | if (args.startsWith("enable")) { 25 | musicManager.config.setAutoConnectEnabled(true); 26 | 27 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 28 | builder.append(" 'Auto_Connect_On_Startup' set to `Enabled`"); 29 | event.reply(builder.toString()); 30 | 31 | } else if (args.startsWith("disable")) { 32 | musicManager.config.setAutoConnectEnabled(false); 33 | 34 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 35 | builder.append(" 'Auto_Connect_On_Startup' set to `Disabled`"); 36 | event.reply(builder.toString()); 37 | 38 | } else if (args.startsWith("channel ")) { 39 | if (args.substring(8).startsWith("clear")) { 40 | musicManager.config.setAutoConnectVoiceChannelId(0L); 41 | 42 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 43 | builder.append(" 'Auto_Connect_On_Startup' VoiceChannelId removed"); 44 | event.reply(builder.toString()); 45 | return; 46 | } 47 | 48 | Long l = this.getLong(args.substring(8), event); 49 | if (l == null) 50 | return; 51 | 52 | musicManager.config.setAutoConnectVoiceChannelId(l); 53 | 54 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 55 | builder.append(" 'Auto_Connect_On_Startup' set VoiceChannelId: `").append(l).append("`"); 56 | event.reply(builder.toString()); 57 | 58 | } else if (args.startsWith("track ")) { 59 | String x = args.substring(6); 60 | if (x.startsWith("clear")) { 61 | musicManager.config.setAutoConnectTrack(""); 62 | 63 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 64 | builder.append(" 'Auto_Connect_On_Startup' Track removed"); 65 | event.reply(builder.toString()); 66 | 67 | } else if (!x.startsWith("http")) { 68 | StringBuilder builder = new StringBuilder().append(event.getClient().getError()); 69 | builder.append(" Track must be a URL."); 70 | event.reply(builder.toString()); 71 | 72 | sendCommandInfo(event); 73 | } else { 74 | musicManager.config.setAutoConnectTrack(x); 75 | 76 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 77 | builder.append(" 'Auto_Connect_On_Startup' set Track: `").append(x).append("`"); 78 | event.reply(builder.toString()); 79 | } 80 | } else { 81 | sendCommandInfo(event); 82 | } 83 | } 84 | 85 | @Override 86 | protected void doPrivateCommand(CommandEvent event) { 87 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 88 | 89 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 90 | 91 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 92 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 93 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 94 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 95 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 96 | 97 | event.reply(builder.toString()); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/setup/AutoDisconnectCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.setup; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.SetupCommand; 7 | 8 | public class AutoDisconnectCommand extends SetupCommand { 9 | 10 | public AutoDisconnectCommand(Bot bot) { 11 | super(bot); 12 | this.name = "autodisconnect"; 13 | this.help = "set's auto disconnect option in config"; 14 | this.arguments = " "; 15 | } 16 | 17 | @Override 18 | protected void doGuildCommand(CommandEvent event) { 19 | if (args.startsWith("alone ")) { 20 | if (args.substring(6).startsWith("enable")) { 21 | musicManager.config.setDisconnectIfAlone(true); 22 | 23 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 24 | builder.append(" 'Auto_Disconnect_If_Alone' set to `Enabled`"); 25 | event.reply(builder.toString()); 26 | 27 | } else if (args.substring(6).startsWith("disable")) { 28 | musicManager.config.setDisconnectIfAlone(false); 29 | 30 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 31 | builder.append(" 'Auto_Disconnect_If_Alone' set to `Disabled`"); 32 | event.reply(builder.toString()); 33 | 34 | } else { 35 | sendCommandInfo(event); 36 | } 37 | 38 | } else if (args.startsWith("trackend ")) { 39 | if (args.substring(9).startsWith("enable")) { 40 | musicManager.config.setDisconnectAfterLastTrack(true); 41 | 42 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 43 | builder.append(" 'Auto_Disconnect_After_Last_Track' set to `Enabled`"); 44 | event.reply(builder.toString()); 45 | 46 | } else if (args.substring(9).startsWith("disable")) { 47 | musicManager.config.setDisconnectAfterLastTrack(false); 48 | 49 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 50 | builder.append(" 'Auto_Disconnect_After_Last_Track' set to `Disabled`"); 51 | event.reply(builder.toString()); 52 | 53 | } else { 54 | sendCommandInfo(event); 55 | } 56 | } else { 57 | sendCommandInfo(event); 58 | } 59 | } 60 | 61 | @Override 62 | protected void doPrivateCommand(CommandEvent event) { 63 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 64 | 65 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 66 | 67 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 68 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 69 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 70 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 71 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 72 | 73 | event.reply(builder.toString()); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/setup/BlacklistCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.setup; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.SetupCommand; 7 | 8 | public class BlacklistCommand extends SetupCommand { 9 | 10 | public BlacklistCommand(Bot bot) { 11 | super(bot); 12 | this.name = "blacklist"; 13 | this.help = "edits the blocked users list"; 14 | this.arguments = " [UserID]"; 15 | } 16 | 17 | @Override 18 | protected void doGuildCommand(CommandEvent event) { 19 | if (args.isEmpty()) { 20 | sendCommandInfo(event); 21 | return; 22 | } 23 | 24 | if (args.startsWith("add ")) { 25 | Long l = this.getLong(args.substring(4), event); 26 | if (l == null) 27 | return; 28 | 29 | musicManager.config.blacklistAdd(l); 30 | 31 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 32 | builder.append(" Successfully added '").append(bot.getUserNameById(l)).append(" ").append(l) 33 | .append("' to blacklist."); 34 | event.reply(builder.toString()); 35 | 36 | } else if (args.startsWith("remove ")) { 37 | Long l = this.getLong(args.substring(7), event); 38 | if (l == null) 39 | return; 40 | 41 | if (!musicManager.config.isBlockedUser(l)) { 42 | StringBuilder builder = new StringBuilder().append(event.getClient().getWarning()); 43 | builder.append(" ").append(l).append(" is not blocked."); 44 | event.reply(builder.toString()); 45 | return; 46 | } 47 | 48 | musicManager.config.blacklistRemove(l); 49 | 50 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 51 | builder.append(" Successfully removed '").append(bot.getUserNameById(l)).append(" ").append(l) 52 | .append("' from blacklist."); 53 | event.reply(builder.toString()); 54 | 55 | } else if (args.startsWith("clear")) { 56 | musicManager.config.blacklistClear(); 57 | 58 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 59 | builder.append(" Blacklist successfully cleard"); 60 | event.reply(builder.toString()); 61 | 62 | } else if (args.startsWith("list")) { 63 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 64 | builder.append(" **Blacklist:**\n"); 65 | for (Long l : musicManager.config.getBlacklist()) { 66 | builder.append("").append(bot.getUserNameById(l)).append(" `").append(l).append("`").append("\n"); 67 | } 68 | event.reply(builder.toString()); 69 | } else { 70 | sendCommandInfo(event); 71 | } 72 | } 73 | 74 | @Override 75 | protected void doPrivateCommand(CommandEvent event) { 76 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 77 | 78 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 79 | 80 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 81 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 82 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 83 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 84 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 85 | 86 | event.reply(builder.toString()); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/setup/ConfigCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.setup; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.SetupCommand; 7 | 8 | public class ConfigCommand extends SetupCommand { 9 | 10 | public ConfigCommand(Bot bot) { 11 | super(bot); 12 | this.name = "config"; 13 | this.aliases = new String[] { "cfg" }; 14 | this.help = "To load, save or show the Config"; 15 | this.arguments = ""; 16 | } 17 | 18 | @Override 19 | protected void doGuildCommand(CommandEvent event) { 20 | StringBuilder builder = new StringBuilder(); 21 | if (args.startsWith("save")) { 22 | if (musicManager.config.writeConfig()) { 23 | builder.append(event.getClient().getSuccess()).append(" Config saved successfully"); 24 | event.reply(builder.toString()); 25 | } else { 26 | builder.append(event.getClient().getError()).append(" Faild to save config"); 27 | event.reply(builder.toString()); 28 | } 29 | } else if (args.startsWith("load")) { 30 | if (musicManager.config.readConfig()) { 31 | builder.append(event.getClient().getSuccess()).append(" Config load successfully"); 32 | event.reply(builder.toString()); 33 | } else { 34 | builder.append(event.getClient().getError()).append(" Faild to load config"); 35 | event.reply(builder.toString()); 36 | } 37 | } else if (args.startsWith("show")) { 38 | builder.append(event.getClient().getSuccess()).append(" "); 39 | 40 | if (event.isOwner()) { 41 | builder.append("**Bot Configuration**").append("\n"); 42 | builder.append(bot.config.getRawConfiguration()).append("\n"); 43 | } 44 | 45 | builder.append("**Guild Configuration**").append("\n"); 46 | builder.append(musicManager.config.getRawConfiguration()).append("\n"); 47 | event.replyInDm(builder.toString()); 48 | } else { 49 | sendCommandInfo(event); 50 | } 51 | } 52 | 53 | @Override 54 | protected void doPrivateCommand(CommandEvent event) { 55 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 56 | 57 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 58 | 59 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 60 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 61 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 62 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 63 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 64 | 65 | event.reply(builder.toString()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/setup/DefaultTextChannelCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.setup; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.SetupCommand; 7 | 8 | public class DefaultTextChannelCommand extends SetupCommand { 9 | 10 | public DefaultTextChannelCommand(Bot bot) { 11 | super(bot); 12 | this.name = "defaulttextchannel"; 13 | this.help = "set's the `Default_TextChannel` option's in config"; 14 | this.arguments = " [textchannelid|clear]"; 15 | } 16 | 17 | @Override 18 | protected void doGuildCommand(CommandEvent event) { 19 | if (args.isEmpty()) { 20 | sendCommandInfo(event); 21 | return; 22 | } 23 | 24 | if (args.startsWith("enable")) { 25 | musicManager.config.setDefaultTextChannelEnabled(true); 26 | 27 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 28 | builder.append(" 'Default_TextChannel' set to `Enabled`"); 29 | event.reply(builder.toString()); 30 | 31 | } else if (args.startsWith("disable")) { 32 | musicManager.config.setDefaultTextChannelEnabled(false); 33 | 34 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 35 | builder.append(" 'Default_TextChannel' set to `Disabled`"); 36 | event.reply(builder.toString()); 37 | 38 | } else if (args.startsWith("channel ")) { 39 | if (args.substring(8).startsWith("clear")) { 40 | musicManager.config.setDefaultTextChannel(0L); 41 | 42 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 43 | builder.append(" 'Default_TextChannel' VoiceChannelId removed"); 44 | event.reply(builder.toString()); 45 | return; 46 | } 47 | Long l = this.getLong(args.substring(8), event); 48 | if (l == null) 49 | return; 50 | 51 | musicManager.config.setDefaultTextChannel(l); 52 | 53 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 54 | builder.append(" 'Default_TextChannel' set VoiceChannelId: `").append(l).append("`"); 55 | event.reply(builder.toString()); 56 | 57 | } else { 58 | sendCommandInfo(event); 59 | } 60 | } 61 | 62 | @Override 63 | protected void doPrivateCommand(CommandEvent event) { 64 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 65 | 66 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 67 | 68 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 69 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 70 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 71 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 72 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 73 | 74 | event.reply(builder.toString()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/setup/DefaultVoiceChannelCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.setup; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.SetupCommand; 7 | 8 | public class DefaultVoiceChannelCommand extends SetupCommand { 9 | 10 | public DefaultVoiceChannelCommand(Bot bot) { 11 | super(bot); 12 | this.name = "defaultvoicechannel"; 13 | this.help = "set's the `Default_VoiceChannel` option's in config"; 14 | this.arguments = " [textchannelid|clear]"; 15 | } 16 | 17 | @Override 18 | protected void doGuildCommand(CommandEvent event) { 19 | if (args.isEmpty()) { 20 | sendCommandInfo(event); 21 | return; 22 | } 23 | 24 | if (args.startsWith("enable")) { 25 | musicManager.config.setDefaultVoiceChannelEnabled(true); 26 | 27 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 28 | builder.append(" 'Default_VoiceChannel' set to `Enabled`"); 29 | event.reply(builder.toString()); 30 | 31 | } else if (args.startsWith("disable")) { 32 | musicManager.config.setDefaultVoiceChannelEnabled(false); 33 | 34 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 35 | builder.append(" 'Default_VoiceChannel' set to `Disabled`"); 36 | event.reply(builder.toString()); 37 | 38 | } else if (args.startsWith("channel ")) { 39 | if (args.substring(8).startsWith("clear")) { 40 | musicManager.config.setDefaultVoiceChannel(0L); 41 | 42 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 43 | builder.append(" 'Default_VoiceChannel' VoiceChannelId removed"); 44 | event.reply(builder.toString()); 45 | return; 46 | } 47 | Long l = this.getLong(args.substring(8), event); 48 | if (l == null) 49 | return; 50 | 51 | musicManager.config.setDefaultVoiceChannel(l); 52 | 53 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 54 | builder.append(" 'Default_VoiceChannel' set VoiceChannelId: `").append(l).append("`"); 55 | event.reply(builder.toString()); 56 | 57 | } else { 58 | sendCommandInfo(event); 59 | } 60 | } 61 | 62 | @Override 63 | protected void doPrivateCommand(CommandEvent event) { 64 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 65 | 66 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 67 | 68 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 69 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 70 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 71 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 72 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 73 | 74 | event.reply(builder.toString()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/setup/ReloadCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.setup; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.SetupCommand; 7 | 8 | public class ReloadCommand extends SetupCommand { 9 | 10 | public ReloadCommand(Bot bot) { 11 | super(bot); 12 | this.name = "reload"; 13 | this.help = "Reload the Plugin."; 14 | } 15 | 16 | @Override 17 | protected void doGuildCommand(CommandEvent event) { 18 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 19 | builder.append(" Reloading..."); 20 | event.reply(builder.toString()); 21 | 22 | bot.getMain().reload(); 23 | } 24 | 25 | @Override 26 | protected void doPrivateCommand(CommandEvent event) { 27 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 28 | 29 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 30 | 31 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 32 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 33 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 34 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 35 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 36 | 37 | event.reply(builder.toString()); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/commands/setup/WhitelistCommand.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.commands.setup; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | 5 | import de.blockbuild.musikbot.Bot; 6 | import de.blockbuild.musikbot.commands.SetupCommand; 7 | 8 | public class WhitelistCommand extends SetupCommand { 9 | 10 | public WhitelistCommand(Bot bot) { 11 | super(bot); 12 | this.name = "whitelist"; 13 | this.help = "edits the whitelist"; 14 | this.arguments = " [UserID]"; 15 | } 16 | 17 | @Override 18 | protected void doGuildCommand(CommandEvent event) { 19 | if (args.isEmpty()) { 20 | sendCommandInfo(event); 21 | return; 22 | } 23 | 24 | if (args.startsWith("add ")) { 25 | Long l = this.getLong(args.substring(4), event); 26 | if (l == null) 27 | return; 28 | 29 | musicManager.config.whitelistAdd(l); 30 | 31 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 32 | builder.append(" Successfully added '").append(bot.getUserNameById(l)).append(" ").append(l) 33 | .append("' to whitelist."); 34 | event.reply(builder.toString()); 35 | 36 | } else if (args.startsWith("remove ")) { 37 | Long l = this.getLong(args.substring(7), event); 38 | if (l == null) 39 | return; 40 | 41 | if (!musicManager.config.isWhitelistedUser(l)) { 42 | StringBuilder builder = new StringBuilder().append(event.getClient().getWarning()); 43 | builder.append(" ").append(l).append(" is not whitelisted."); 44 | event.reply(builder.toString()); 45 | return; 46 | } 47 | 48 | musicManager.config.whitelistRemove(l); 49 | 50 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 51 | builder.append(" Successfully removed '").append(bot.getUserNameById(l)).append(" ").append(l) 52 | .append("' from whitelist."); 53 | event.reply(builder.toString()); 54 | 55 | } else if (args.startsWith("clear")) { 56 | musicManager.config.whitelistClear(); 57 | 58 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 59 | builder.append(" Whitelist successfully cleard"); 60 | event.reply(builder.toString()); 61 | 62 | } else if (args.startsWith("list")) { 63 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 64 | builder.append(" **Whitelist:**\n"); 65 | for (Long l : musicManager.config.getWhitelist()) { 66 | builder.append("").append(bot.getUserNameById(l)).append(" `").append(l).append("`\n"); 67 | } 68 | event.reply(builder.toString()); 69 | 70 | } else if (args.startsWith("enable")) { 71 | musicManager.config.setWhitelistEnabled(true); 72 | 73 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 74 | builder.append(" Whitelist now is `Enabled`"); 75 | event.reply(builder.toString()); 76 | 77 | } else if (args.startsWith("disable")) { 78 | musicManager.config.setWhitelistEnabled(false); 79 | 80 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 81 | builder.append(" Whitelist now is `Disabled`"); 82 | event.reply(builder.toString()); 83 | } else { 84 | sendCommandInfo(event); 85 | } 86 | } 87 | 88 | @Override 89 | protected void doPrivateCommand(CommandEvent event) { 90 | event.reply(event.getClient().getError() + " This command cannot be used in Direct messages."); 91 | 92 | StringBuilder builder = new StringBuilder().append(event.getClient().getSuccess()); 93 | 94 | builder.append(" **MusikBot** ").append("by Block-Build\n"); 95 | builder.append("SpigotMC: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 96 | builder.append("GitHub: `https://github.com/Block-Build/MusikBot`\n"); 97 | builder.append("Version: `").append(bot.getMain().getDescription().getVersion()).append("`\n"); 98 | builder.append("Do you have any problem or suggestion? Open an Issue on GitHub."); 99 | 100 | event.reply(builder.toString()); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/configuration/BotConfiguration.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.configuration; 2 | 3 | import java.io.File; 4 | import java.util.Map; 5 | 6 | import org.bukkit.configuration.ConfigurationSection; 7 | import org.bukkit.configuration.file.YamlConfiguration; 8 | import de.blockbuild.musikbot.Bot; 9 | 10 | public class BotConfiguration extends ConfigurationManager { 11 | private String token, trigger, game, ownerID, inviteURL; 12 | private Map emojis; 13 | private static String header; 14 | 15 | public BotConfiguration(Bot bot) { 16 | super(new File(bot.getMain().getDataFolder(), "BotConfig.yml")); 17 | 18 | StringBuilder builder = new StringBuilder(); 19 | builder.append("MusikBot by Block-Build\n"); 20 | builder.append("+===================+\n"); 21 | builder.append("| BOT CONFIGURATION |\n"); 22 | builder.append("+===================+\n"); 23 | builder.append("\n"); 24 | builder.append("You have to insert the bot token and owner id.\n"); 25 | builder.append( 26 | "Instructions on: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/`\n"); 27 | builder.append( 28 | "Support/Suggestions/Bugs? Have a look on this site: `https://github.com/Block-Build/MusikBot`\n"); 29 | builder.append("\n"); 30 | header = builder.toString(); 31 | 32 | readConfig(); 33 | writeConfig(); 34 | } 35 | 36 | public boolean writeConfig() { 37 | YamlConfiguration config = new YamlConfiguration(); 38 | 39 | config.set("Bot_Token", this.token); 40 | config.set("Owner_ID", this.ownerID); 41 | config.set("Command_Trigger", this.trigger); 42 | config.set("Game", this.game); 43 | this.phraseMap(config.createSection("Emojis"), this.emojis, "Success", "Warning", "Error"); 44 | config.set("Invite_URL", this.inviteURL); 45 | 46 | return this.saveConfig(config, header); 47 | } 48 | 49 | public boolean readConfig() { 50 | try { 51 | YamlConfiguration config = this.loadConfig(); 52 | ConfigurationSection c; 53 | 54 | config.addDefault("Bot_Token", "insert token here"); 55 | config.addDefault("Owner_ID", "12345"); 56 | config.addDefault("Command_Trigger", "!"); 57 | config.addDefault("Game", "Ready for playing music. !Play"); 58 | 59 | c = this.addDefaultSection(config, "Emojis"); 60 | c.addDefault("Success", "\uD83D\uDE03"); 61 | c.addDefault("Warning", "\uD83D\uDE2E"); 62 | c.addDefault("Error", "\uD83D\uDE26"); 63 | 64 | this.token = config.getString("Bot_Token"); 65 | this.ownerID = config.getString("Owner_ID"); 66 | this.trigger = config.getString("Command_Trigger"); 67 | this.game = config.getString("Game"); 68 | 69 | this.emojis = config.getConfigurationSection("Emojis").getValues(false); 70 | return true; 71 | } catch (Exception e) { 72 | System.out.println("Couldn't read BotConfiguration!"); 73 | e.printStackTrace(); 74 | return false; 75 | } 76 | } 77 | 78 | public String getToken() { 79 | return this.token; 80 | } 81 | 82 | public String getGame() { 83 | return this.game; 84 | } 85 | 86 | public String getTrigger() { 87 | return this.trigger; 88 | } 89 | 90 | public String getOwnerID() { 91 | return this.ownerID; 92 | } 93 | 94 | public String getSuccess() { 95 | return (String) this.emojis.get("Success"); 96 | } 97 | 98 | public String getWarning() { 99 | return (String) this.emojis.get("Warning"); 100 | } 101 | 102 | public String getError() { 103 | return (String) this.emojis.get("Error"); 104 | } 105 | 106 | public void setInviteLink(String inviteURL) { 107 | this.inviteURL = "`" + inviteURL + "`"; 108 | writeConfig(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/configuration/ConfigurationManager.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.configuration; 2 | 3 | import java.io.File; 4 | import java.util.Map; 5 | 6 | import org.bukkit.configuration.ConfigurationSection; 7 | import org.bukkit.configuration.file.YamlConfiguration; 8 | 9 | public abstract class ConfigurationManager { 10 | private final File file; 11 | 12 | public ConfigurationManager(File file) { 13 | this.file = file; 14 | } 15 | 16 | public synchronized boolean saveConfig(YamlConfiguration config, String header) { 17 | try { 18 | config.options().header(header); 19 | config.options().copyDefaults(true); 20 | config.save(this.file); 21 | return true; 22 | } catch (Exception e) { 23 | System.out.println("Couldn't save " + file.getName()); 24 | e.printStackTrace(); 25 | return false; 26 | } 27 | } 28 | 29 | public synchronized YamlConfiguration loadConfig() { 30 | try { 31 | YamlConfiguration config = YamlConfiguration.loadConfiguration(file); 32 | config.options().copyDefaults(true); 33 | return config; 34 | 35 | } catch (Exception e) { 36 | System.out.println("Couldn't load " + file.getName()); 37 | e.printStackTrace(); 38 | } 39 | return null; 40 | } 41 | 42 | public synchronized boolean deleteConfig() { 43 | return file.delete(); 44 | } 45 | 46 | public abstract boolean writeConfig(); 47 | 48 | public abstract boolean readConfig(); 49 | 50 | public String getRawConfiguration() { 51 | return loadConfig().saveToString(); 52 | } 53 | 54 | protected ConfigurationSection phraseMap(ConfigurationSection section, Map map, String... keys) { 55 | 56 | for (String s : keys) { 57 | section.addDefault(s, map.get(s)); 58 | } 59 | return section; 60 | } 61 | 62 | protected ConfigurationSection addDefaultSection(YamlConfiguration config, String section) { 63 | if (config.contains(section)) { 64 | return config.getConfigurationSection(section); 65 | } else { 66 | return config.createSection(section); 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/configuration/GuildConfiguration.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.configuration; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import org.bukkit.configuration.ConfigurationSection; 8 | import org.bukkit.configuration.file.YamlConfiguration; 9 | 10 | import de.blockbuild.musikbot.Bot; 11 | import de.blockbuild.musikbot.core.GuildMusicManager; 12 | 13 | import net.dv8tion.jda.api.entities.Role; 14 | 15 | public class GuildConfiguration extends ConfigurationManager { 16 | private final GuildMusicManager musicManager; 17 | private String guildName; 18 | private int volume, messageDeleteDelay; 19 | private List blacklist, whitelist; 20 | private Boolean disconnectIfAlone, disconnectAfterLastTrack, useWhitelist; 21 | private Map autoConnect, defaultTextChannel, defaultVoiceChannel, roles, nowPlaying; 22 | private static String header; 23 | 24 | public GuildConfiguration(Bot bot, GuildMusicManager musicManager) { 25 | super(new File(bot.getMain().getDataFolder(), "/Guilds/" + musicManager.getGuild().getId() + ".yml")); 26 | this.musicManager = musicManager; 27 | this.guildName = musicManager.getGuild().getName(); 28 | 29 | StringBuilder builder = new StringBuilder(); 30 | builder.append("MusikBot by Block-Build\n"); 31 | builder.append("+=====================+\n"); 32 | builder.append("| GUILD CONFIGURATION |\n"); 33 | builder.append("+=====================+\n"); 34 | builder.append("\n"); 35 | header = builder.toString(); 36 | 37 | readConfig(); 38 | writeConfig(); 39 | } 40 | 41 | public boolean writeConfig() { 42 | try { 43 | YamlConfiguration config = new YamlConfiguration(); 44 | 45 | config.set("Guild_Name", this.guildName); 46 | config.set("Volume", this.volume); 47 | config.set("Delete_Command_Massages_Delay", this.messageDeleteDelay); 48 | config.set("Whitelist_Enabled", this.useWhitelist); 49 | config.set("Whitelist", this.whitelist); 50 | config.set("Blacklist", this.blacklist); 51 | 52 | this.phraseMap(config.createSection("Command_Permission_Roles"), this.roles, "Music_Commands", 53 | "Radio_Commands", "Connection_Commands", "Setup_Commands"); 54 | 55 | config.set("Auto_Disconnect_If_Alone", this.disconnectIfAlone); 56 | config.set("Auto_Disconnect_After_Last_Track", this.disconnectAfterLastTrack); 57 | 58 | this.phraseMap(config.createSection("Auto_Connect_On_Startup"), this.autoConnect, "Enabled", 59 | "VoiceChannelId", "Track"); 60 | this.phraseMap(config.createSection("Message_Now_Playing_Track"), this.nowPlaying, "Enabled", 61 | "TextChannelId"); 62 | this.phraseMap(config.createSection("Default_TextChannel"), this.defaultTextChannel, "Enabled", 63 | "TextChannelId"); 64 | this.phraseMap(config.createSection("Default_VoiceChannel"), this.defaultVoiceChannel, "Enabled", 65 | "VoiceChannelId"); 66 | 67 | return this.saveConfig(config, header); 68 | } catch (Exception e) { 69 | e.printStackTrace(); 70 | return false; 71 | } 72 | } 73 | 74 | public boolean readConfig() { 75 | try { 76 | YamlConfiguration config = this.loadConfig(); 77 | ConfigurationSection c; 78 | 79 | config.addDefault("Guild_Name", this.guildName); 80 | config.addDefault("Volume", 100); 81 | config.addDefault("Delete_Command_Massages_Delay", 0); 82 | config.addDefault("Whitelist_Enabled", ""); 83 | config.addDefault("Whitelist", null); 84 | config.addDefault("Blacklist", null); 85 | 86 | c = this.addDefaultSection(config, "Command_Permission_Roles"); 87 | c.addDefault("Music_Commands", ""); 88 | c.addDefault("Radio_Commands", ""); 89 | c.addDefault("Connection_Commands", ""); 90 | c.addDefault("Setup_Commands", ""); 91 | 92 | config.addDefault("Auto_Disconnect_If_Alone", false); 93 | config.addDefault("Auto_Disconnect_After_Last_Track", false); 94 | 95 | c = this.addDefaultSection(config, "Auto_Connect_On_Startup"); 96 | c.addDefault("Enabled", false); 97 | c.addDefault("VoiceChannelId", 0L); 98 | c.addDefault("Track", ""); 99 | 100 | c = this.addDefaultSection(config, "Message_Now_Playing_Track"); 101 | c.addDefault("Enabled", false); 102 | c.addDefault("TextChannelId", 0L); 103 | 104 | c = this.addDefaultSection(config, "Default_TextChannel"); 105 | c.addDefault("Enabled", false); 106 | c.addDefault("TextChannelId", 0L); 107 | 108 | c = this.addDefaultSection(config, "Default_VoiceChannel"); 109 | c.addDefault("Enabled", false); 110 | c.addDefault("VoiceChannelId", 0L); 111 | 112 | this.volume = !(config.getInt("Volume") < 1) && !(config.getInt("Volume") > 100) ? config.getInt("Volume") 113 | : 100; 114 | this.messageDeleteDelay = config.getInt("Delete_Command_Massages_Delay"); 115 | this.useWhitelist = config.getBoolean("Whitelist_Enabled"); 116 | this.whitelist = config.getLongList("Whitelist"); 117 | this.blacklist = config.getLongList("Blacklist"); 118 | this.roles = config.getConfigurationSection("Command_Permission_Roles").getValues(false); 119 | this.disconnectIfAlone = config.getBoolean("Auto_Disconnect_If_Alone"); 120 | this.disconnectAfterLastTrack = config.getBoolean("Auto_Disconnect_After_Last_Track"); 121 | 122 | this.autoConnect = config.getConfigurationSection("Auto_Connect_On_Startup").getValues(false); 123 | this.nowPlaying = config.getConfigurationSection("Message_Now_Playing_Track").getValues(false); 124 | this.defaultTextChannel = config.getConfigurationSection("Default_TextChannel").getValues(false); 125 | this.defaultVoiceChannel = config.getConfigurationSection("Default_VoiceChannel").getValues(false); 126 | 127 | initConfig(); 128 | return true; 129 | } catch (Exception e) { 130 | System.out.println("Couldn't read GuildConfiguration!"); 131 | e.printStackTrace(); 132 | return false; 133 | } 134 | } 135 | 136 | private void initConfig() { 137 | musicManager.getAudioPlayer().setVolume(this.volume); 138 | 139 | if (messageDeleteDelay < 0) { 140 | messageDeleteDelay = 0; 141 | } 142 | 143 | if (isAutoConnectEnabled() && getAutoConnectVoiceChannelId() == 0L) 144 | setAutoConnectEnabled(false); 145 | 146 | if (isNowPlayingTrackEnabled() && getNowPlayingTrackTextChannelId() == 0L) 147 | setNowPlayingTrackEnabled(false); 148 | 149 | if (isDefaultTextChannelEnabled() && getDefaultTextChannel() == 0L) 150 | setDefaultTextChannelEnabled(false); 151 | 152 | if (isDefaultVoiceChannelEnabled() && getDefaultVoiceChannel() == 0L) 153 | setDefaultVoiceChannelEnabled(false); 154 | } 155 | 156 | public Boolean isDisconnectIfAloneEnabled() { 157 | return disconnectIfAlone; 158 | } 159 | 160 | public Boolean isDisconnectAfterLastTrackEnabled() { 161 | return disconnectAfterLastTrack; 162 | } 163 | 164 | public void setDisconnectIfAlone(Boolean bool) { 165 | disconnectIfAlone = bool; 166 | } 167 | 168 | public void setDisconnectAfterLastTrack(Boolean bool) { 169 | disconnectAfterLastTrack = bool; 170 | } 171 | 172 | public Boolean isWhitelistEnabled() { 173 | return useWhitelist; 174 | } 175 | 176 | public void setWhitelistEnabled(Boolean bool) { 177 | useWhitelist = bool; 178 | } 179 | 180 | public Boolean isAutoConnectEnabled() { 181 | return (Boolean) autoConnect.get("Enabled"); 182 | } 183 | 184 | public long getAutoConnectVoiceChannelId() { 185 | return Long.parseLong(autoConnect.get("VoiceChannelId").toString()); 186 | } 187 | 188 | public String getAutoConnectTrack() { 189 | return (String) autoConnect.get("Track"); 190 | } 191 | 192 | public void setAutoConnectEnabled(Boolean bool) { 193 | autoConnect.replace("Enabled", bool); 194 | } 195 | 196 | public void setAutoConnectVoiceChannelId(Long voiceChannelId) { 197 | autoConnect.replace("VoiceChannelId", voiceChannelId); 198 | } 199 | 200 | public void setAutoConnectTrack(String track) { 201 | autoConnect.replace("Track", track); 202 | } 203 | 204 | public Boolean isNowPlayingTrackEnabled() { 205 | return (Boolean) nowPlaying.get("Enabled"); 206 | } 207 | 208 | public void setNowPlayingTrackEnabled(Boolean bool) { 209 | nowPlaying.replace("Enabled", bool); 210 | } 211 | 212 | public long getNowPlayingTrackTextChannelId() { 213 | return Long.parseLong(nowPlaying.get("TextChannelId").toString()); 214 | } 215 | 216 | public void setNowPlayingTrackTextChannelId(Long textChannelId) { 217 | nowPlaying.replace("TextChannelId", textChannelId); 218 | } 219 | 220 | public int getVolume() { 221 | return this.volume; 222 | } 223 | 224 | public void setVolume(int volume) { 225 | this.volume = volume; 226 | } 227 | 228 | public boolean isBlockedUser(long ID) { 229 | return this.blacklist.contains(ID); 230 | } 231 | 232 | public void blacklistAdd(Long id) { 233 | blacklist.add(id); 234 | } 235 | 236 | public void blacklistRemove(Long id) { 237 | blacklist.remove(id); 238 | } 239 | 240 | public void blacklistClear() { 241 | blacklist.clear(); 242 | } 243 | 244 | public List getBlacklist() { 245 | return blacklist; 246 | } 247 | 248 | public boolean isWhitelistedUser(long ID) { 249 | return this.whitelist.contains(ID); 250 | } 251 | 252 | public void whitelistAdd(Long id) { 253 | whitelist.add(id); 254 | } 255 | 256 | public void whitelistRemove(Long id) { 257 | whitelist.remove(id); 258 | } 259 | 260 | public void whitelistClear() { 261 | whitelist.clear(); 262 | } 263 | 264 | public List getWhitelist() { 265 | return whitelist; 266 | } 267 | 268 | public boolean isDefaultTextChannelEnabled() { 269 | return (Boolean) defaultTextChannel.get("Enabled"); 270 | } 271 | 272 | public void setDefaultTextChannelEnabled(boolean bool) { 273 | defaultTextChannel.replace("Enabled", bool); 274 | } 275 | 276 | public long getDefaultTextChannel() { 277 | return (long) defaultTextChannel.get("TextChannelId"); 278 | } 279 | 280 | public void setDefaultTextChannel(long id) { 281 | defaultTextChannel.replace("TextChannelId", id); 282 | } 283 | 284 | public boolean isDefaultVoiceChannelEnabled() { 285 | return (Boolean) defaultVoiceChannel.get("Enabled"); 286 | } 287 | 288 | public void setDefaultVoiceChannelEnabled(boolean bool) { 289 | defaultVoiceChannel.replace("Enabled", bool); 290 | } 291 | 292 | public long getDefaultVoiceChannel() { 293 | return (long) defaultVoiceChannel.get("VoiceChannelId"); 294 | } 295 | 296 | public void setDefaultVoiceChannel(long id) { 297 | defaultVoiceChannel.replace("VoiceChannelId", id); 298 | } 299 | 300 | public Role getMusicRole() { 301 | return this.getRole((String) roles.get("Music_Commands")); 302 | } 303 | 304 | public Role getRadioRole() { 305 | return this.getRole((String) roles.get("Radio_Commands")); 306 | } 307 | 308 | public Role getConnectionRole() { 309 | return this.getRole((String) roles.get("Connection_Commands")); 310 | } 311 | 312 | public Role getSetupRole() { 313 | return this.getRole((String) roles.get("Setup_Commands")); 314 | } 315 | 316 | private Role getRole(String role) { 317 | if (role.isEmpty() || role.equals("@everyone")) { 318 | return null; 319 | } 320 | List r = musicManager.getGuild().getRolesByName(role, true); 321 | if (r.isEmpty()) { 322 | System.err.println("[MusikBot] '" + role + "' isn't a vaild role"); 323 | return null; 324 | } 325 | return r.get(0); 326 | } 327 | 328 | public int getMessageDeleteDelay() { 329 | return messageDeleteDelay; 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/configuration/PlaylistConfiguration.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.configuration; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | import org.bukkit.configuration.file.YamlConfiguration; 7 | 8 | import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; 9 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 10 | 11 | import de.blockbuild.musikbot.Bot; 12 | 13 | import net.dv8tion.jda.api.entities.User; 14 | 15 | public class PlaylistConfiguration extends ConfigurationManager { 16 | private String playlistName, userName; 17 | private List playlist; 18 | private static String header; 19 | 20 | public PlaylistConfiguration(Bot bot, User user, String name) { 21 | super(new File(bot.getMain().getDataFolder(), "/Playlists/" + user.getId() + "/" + name + ".yml")); 22 | this.userName = user.getName(); 23 | this.playlistName = name; 24 | 25 | StringBuilder builder = new StringBuilder(); 26 | builder.append("MusikBot by Block-Build\n"); 27 | builder.append("+========================+\n"); 28 | builder.append("| PLAYLIST CONFIGURATION |\n"); 29 | builder.append("+========================+\n"); 30 | builder.append("\n"); 31 | header = builder.toString(); 32 | 33 | readConfig(); 34 | } 35 | 36 | @Override 37 | public boolean writeConfig() { 38 | YamlConfiguration config = new YamlConfiguration(); 39 | 40 | config.set("User_Name", this.userName); 41 | config.set("Playlist_Name", this.playlistName); 42 | config.set("Amount", playlist.size()); 43 | config.set("Playlist", this.playlist); 44 | 45 | return this.saveConfig(config, header); 46 | } 47 | 48 | @Override 49 | public boolean readConfig() { 50 | try { 51 | YamlConfiguration config = this.loadConfig(); 52 | 53 | this.playlist = config.getStringList("Playlist"); 54 | return true; 55 | } catch (Exception e) { 56 | System.out.println("Couldn't read Playlist `" + this.playlistName + "`!"); 57 | e.printStackTrace(); 58 | return false; 59 | } 60 | } 61 | 62 | public void setPlaylist(AudioPlaylist playlist) { 63 | for (AudioTrack track : playlist.getTracks()) { 64 | this.playlist.add(track.getInfo().uri); 65 | } 66 | } 67 | 68 | public void setPlaylist(List URL) { 69 | this.playlist = URL; 70 | } 71 | 72 | public List getPlaylist() { 73 | return this.playlist; 74 | } 75 | 76 | public void addTracks(List tracks) { 77 | for (AudioTrack track : tracks) { 78 | this.playlist.add(track.getInfo().uri); 79 | } 80 | } 81 | 82 | public void addTrack(String URL) { 83 | this.playlist.add(URL); 84 | } 85 | 86 | public void addTrack(AudioTrack track) { 87 | this.playlist.add(track.getInfo().uri); 88 | } 89 | 90 | public void removeTrack(String URL) { 91 | this.playlist.remove(URL); 92 | } 93 | 94 | public void removeTrack(AudioTrack track) { 95 | this.playlist.remove(track.getInfo().uri); 96 | } 97 | 98 | public void removeTrack(int track) { 99 | this.playlist.remove(track); 100 | } 101 | 102 | public void clearPlaylist() { 103 | this.playlist.clear(); 104 | } 105 | 106 | public int getAmount() { 107 | return this.playlist.size(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/core/AudioPlayerSendHandler.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.core; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; 6 | import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame; 7 | 8 | import de.blockbuild.musikbot.Bot; 9 | 10 | import net.dv8tion.jda.api.audio.AudioSendHandler; 11 | 12 | public class AudioPlayerSendHandler implements AudioSendHandler { 13 | private final Bot bot; 14 | public final AudioPlayer player; 15 | public AudioFrame lastFrame; 16 | 17 | public AudioPlayerSendHandler(AudioPlayer player, Bot bot) { 18 | this.player = player; 19 | this.bot = bot; 20 | } 21 | 22 | @Override 23 | public boolean canProvide() { 24 | lastFrame = player.provide(); 25 | return lastFrame != null; 26 | } 27 | 28 | @Override 29 | public ByteBuffer provide20MsAudio() { 30 | return ByteBuffer.wrap(lastFrame.getData()); 31 | } 32 | 33 | @Override 34 | public boolean isOpus() { 35 | return true; 36 | } 37 | 38 | public AudioPlayer getPlayer() { 39 | return player; 40 | } 41 | 42 | public Bot getBot() { 43 | return bot; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/core/BasicResultHandler.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.core; 2 | 3 | import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; 4 | import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; 5 | import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; 6 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 7 | 8 | public class BasicResultHandler implements AudioLoadResultHandler { 9 | 10 | private TrackScheduler trackScheduler; 11 | 12 | public BasicResultHandler(GuildMusicManager musicManager) { 13 | this.trackScheduler = musicManager.getTrackScheduler(); 14 | } 15 | 16 | @Override 17 | public void trackLoaded(AudioTrack track) { 18 | trackScheduler.playTrack(track); 19 | } 20 | 21 | @Override 22 | public void playlistLoaded(AudioPlaylist playlist) { 23 | // player.playTrack(playlist.getTracks().get(0)); 24 | 25 | for (AudioTrack track : playlist.getTracks()) { 26 | trackScheduler.queueTrack(track); 27 | } 28 | } 29 | 30 | @Override 31 | public void noMatches() { 32 | } 33 | 34 | @Override 35 | public void loadFailed(FriendlyException throwable) { 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/core/ExtendYoutubeAudioSourceManager.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.core; 2 | 3 | import java.io.IOException; 4 | import java.nio.charset.Charset; 5 | import org.apache.commons.io.IOUtils; 6 | import org.apache.http.client.methods.CloseableHttpResponse; 7 | import org.apache.http.client.methods.HttpGet; 8 | import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager; 9 | import com.sedmelluq.discord.lavaplayer.tools.DataFormatTools; 10 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 11 | 12 | public class ExtendYoutubeAudioSourceManager extends YoutubeAudioSourceManager { 13 | 14 | public String getYTAutoPlayNextVideoId(String videoId) throws IOException { 15 | try (CloseableHttpResponse response = getHttpInterface().execute(new HttpGet(videoId))) { 16 | 17 | int statusCode = response.getStatusLine().getStatusCode(); 18 | if (statusCode != 200) { 19 | throw new IOException("Invalid status code for video page response: " + statusCode); 20 | } 21 | 22 | String html = IOUtils.toString(response.getEntity().getContent(), Charset.forName("UTF-8")); 23 | String part = DataFormatTools.extractBetween(html, "watch-sidebar-head", "stat attribution"); 24 | String autoVideoId = getVideoIdFromString(part); 25 | if (autoVideoId == null) { 26 | return null; 27 | } else { 28 | return getWatchUrl(getVideoIdFromString(part)); 29 | } 30 | } 31 | } 32 | 33 | public String getYTAutoPlayNextVideoId(AudioTrack track) throws IOException { 34 | try (CloseableHttpResponse response = getHttpInterface().execute(new HttpGet(track.getInfo().uri))) { 35 | 36 | int statusCode = response.getStatusLine().getStatusCode(); 37 | if (statusCode != 200) { 38 | throw new IOException("Invalid status code for video page response: " + statusCode); 39 | } 40 | 41 | String html = IOUtils.toString(response.getEntity().getContent(), Charset.forName("UTF-8")); 42 | String part = DataFormatTools.extractBetween(html, "watch-sidebar-head", "stat attribution"); 43 | String autoVideoId = getVideoIdFromString(part); 44 | if (autoVideoId == null) { 45 | return null; 46 | } else { 47 | return getWatchUrl(getVideoIdFromString(part)); 48 | } 49 | } 50 | } 51 | 52 | private String getVideoIdFromString(String string) { 53 | if (string == null || string.length() < 20) { 54 | return null; 55 | } 56 | 57 | int startIndex = string.indexOf("/watch?v="); 58 | if (startIndex == 0) { 59 | return null; 60 | } else { 61 | startIndex += "/watch?v=".length(); 62 | } 63 | return string.substring(startIndex, startIndex + 11); 64 | } 65 | 66 | private static String getWatchUrl(String videoId) { 67 | return "https://www.youtube.com/watch?v=" + videoId; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/core/GuildMusicManager.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.core; 2 | 3 | import java.util.concurrent.Executors; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; 7 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; 8 | import de.blockbuild.musikbot.Bot; 9 | import de.blockbuild.musikbot.configuration.GuildConfiguration; 10 | 11 | import net.dv8tion.jda.api.entities.Guild; 12 | import net.dv8tion.jda.api.entities.Message; 13 | import net.dv8tion.jda.api.entities.MessageChannel; 14 | import net.dv8tion.jda.api.entities.TextChannel; 15 | 16 | public class GuildMusicManager { 17 | private final AudioPlayer player; 18 | private final TrackScheduler trackScheduler; 19 | public final GuildConfiguration config; 20 | private final Bot bot; 21 | private final Guild guild; 22 | private Boolean autoPlay; 23 | 24 | public GuildMusicManager(AudioPlayerManager playerManager, Guild guild, Bot bot) { 25 | this.bot = bot; 26 | this.guild = guild; 27 | this.player = playerManager.createPlayer(); 28 | this.trackScheduler = new TrackScheduler(bot, this); 29 | this.player.addListener(trackScheduler); 30 | this.autoPlay = false; 31 | this.config = new GuildConfiguration(bot, this); 32 | 33 | if (config.isAutoConnectEnabled()) { 34 | if (config.getAutoConnectVoiceChannelId() == 0) { 35 | bot.joinDiscordVoiceChannel(guild); 36 | } else { 37 | if (!bot.joinDiscordVoiceChannel(guild, config.getAutoConnectVoiceChannelId()) 38 | && config.isDefaultTextChannelEnabled()) { 39 | TextChannel channel = bot.getTextChannelById(config.getDefaultTextChannel()); 40 | StringBuilder builder = new StringBuilder(); 41 | builder.append(" Missing permission or there is no channel called `") 42 | .append(config.getDefaultTextChannel()).append("`."); 43 | channel.sendMessage(builder.toString()); 44 | 45 | } 46 | } 47 | if (!(config.getAutoConnectTrack() == null)) { 48 | playerManager.loadItemOrdered(playerManager, config.getAutoConnectTrack(), 49 | new BasicResultHandler(this)); 50 | 51 | if (config.isNowPlayingTrackEnabled()) { 52 | Executors.newSingleThreadScheduledExecutor().schedule(() -> { 53 | 54 | TextChannel tc = guild.getTextChannelById(config.getNowPlayingTrackTextChannelId()); 55 | tc.sendMessage(trackScheduler.messageNowPlayingTrackShort(player.getPlayingTrack())) 56 | .queue(m -> { 57 | if (config.getMessageDeleteDelay() > 0) { 58 | deleteMessageLater(tc, m, config.getMessageDeleteDelay()); 59 | } 60 | }); 61 | }, 5, TimeUnit.SECONDS); 62 | 63 | } 64 | } 65 | } 66 | } 67 | 68 | public void deleteMessageLater(MessageChannel channel, Message message, int delay) { 69 | Executors.newSingleThreadScheduledExecutor().schedule(() -> { 70 | message.delete().queue(unused -> { 71 | }, ignored -> { 72 | }); 73 | }, delay, TimeUnit.MINUTES); 74 | } 75 | 76 | public Guild getGuild() { 77 | return this.guild; 78 | } 79 | 80 | public AudioPlayerSendHandler getSendHandler() { 81 | return new AudioPlayerSendHandler(player, bot); 82 | } 83 | 84 | public TrackScheduler getTrackScheduler() { 85 | return this.trackScheduler; 86 | } 87 | 88 | public AudioPlayer getAudioPlayer() { 89 | return this.player; 90 | } 91 | 92 | public void setVolume(int volume) { 93 | player.setVolume(volume); 94 | config.setVolume(volume); 95 | } 96 | 97 | public int getVolume() { 98 | return player.getVolume(); 99 | } 100 | 101 | public Boolean isAutoPlay() { 102 | return this.autoPlay; 103 | } 104 | 105 | public void setIsAutoPlay(boolean bool) { 106 | this.autoPlay = bool; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/core/TrackScheduler.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.core; 2 | 3 | import java.io.IOException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | import java.util.Date; 8 | import java.util.Iterator; 9 | import java.util.List; 10 | import java.util.concurrent.BlockingQueue; 11 | import java.util.concurrent.LinkedBlockingQueue; 12 | 13 | import com.github.breadmoirai.discordemoji.Emoji; 14 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; 15 | import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter; 16 | import com.sedmelluq.discord.lavaplayer.player.event.AudioEventListener; 17 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 18 | import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason; 19 | 20 | import de.blockbuild.musikbot.Bot; 21 | import net.dv8tion.jda.api.entities.Guild; 22 | import net.dv8tion.jda.api.entities.Message; 23 | import net.dv8tion.jda.api.entities.TextChannel; 24 | 25 | public class TrackScheduler extends AudioEventAdapter implements AudioEventListener { 26 | 27 | private final GuildMusicManager musicManager; 28 | private final AudioPlayer player; 29 | private final BlockingQueue queue; 30 | private final Guild guild; 31 | private final Bot bot; 32 | private final ExtendYoutubeAudioSourceManager eyasm; 33 | 34 | public TrackScheduler(Bot bot, GuildMusicManager musicManager) { 35 | this.musicManager = musicManager; 36 | this.player = musicManager.getAudioPlayer(); 37 | this.queue = new LinkedBlockingQueue(); 38 | this.bot = bot; 39 | this.guild = musicManager.getGuild(); 40 | this.eyasm = new ExtendYoutubeAudioSourceManager(); 41 | } 42 | 43 | public int queueTrack(AudioTrack track) { 44 | if (!player.startTrack(track, true)) { 45 | queue.offer(track); 46 | return queue.size(); 47 | } else { 48 | return 0; 49 | } 50 | } 51 | 52 | public boolean playTrack(AudioTrack track) { 53 | return player.startTrack(track, false); 54 | } 55 | 56 | public boolean playNextTrack() { 57 | String url = nextYTAutoPlay(player.getPlayingTrack()); 58 | if (!(url == null)) { 59 | bot.getPlayerManager().loadItemOrdered(musicManager, url, new BasicResultHandler(musicManager)); 60 | // wait for loading track 61 | try { 62 | Thread.sleep(1000); 63 | } catch (InterruptedException ignore) { 64 | } 65 | 66 | return true; 67 | } else if (queue.isEmpty()) { 68 | player.stopTrack(); 69 | return false; 70 | } else { 71 | // wait for loading next track 72 | player.playTrack(queue.poll()); 73 | try { 74 | Thread.sleep(400); 75 | } catch (InterruptedException ignore) { 76 | } 77 | return true; 78 | } 79 | } 80 | 81 | public void shuffle() { 82 | List q = new ArrayList(); 83 | Iterator x = queue.iterator(); 84 | while (x.hasNext()) { 85 | AudioTrack track = x.next(); 86 | q.add(track); 87 | } 88 | Collections.shuffle((List) q); 89 | queue.clear(); 90 | for (AudioTrack track : q) { 91 | queue.offer(track); 92 | } 93 | } 94 | 95 | @Override 96 | public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) { 97 | if (endReason.mayStartNext) { 98 | if (playNextTrack()) { 99 | if (musicManager.config.isNowPlayingTrackEnabled()) { 100 | TextChannel tc = bot.getTextChannelById(musicManager.config.getNowPlayingTrackTextChannelId()); 101 | // tc.sendMessage(Emoji.MAG_RIGHT.getUtf8() + " Loading...") 102 | // tc.queue(m -> messageNowPlayingTrackShort(player.getPlayingTrack(), m)); 103 | tc.sendMessage(messageNowPlayingTrackShort(player.getPlayingTrack())).queue(m -> { 104 | if (musicManager.config.getMessageDeleteDelay() > 0) { 105 | musicManager.deleteMessageLater(tc, m, musicManager.config.getMessageDeleteDelay()); 106 | } 107 | }); 108 | } 109 | } 110 | } 111 | 112 | if (player.getPlayingTrack() == null && queue.isEmpty() 113 | && musicManager.config.isDisconnectAfterLastTrackEnabled()) { 114 | guild.getAudioManager().closeAudioConnection(); 115 | } 116 | } 117 | 118 | public String nextYTAutoPlay(AudioTrack track) { 119 | if (musicManager.isAutoPlay() && !(track == null) && track.getSourceManager().getSourceName() == "youtube") { 120 | try { 121 | String autoUrl = eyasm.getYTAutoPlayNextVideoId(track); 122 | if (autoUrl == null) { 123 | return null; 124 | } else { 125 | // bot.getPlayerManager().loadItemOrdered(musicManager, autoUrl, new 126 | // BasicResultHandler(player)); 127 | return autoUrl; 128 | } 129 | } catch (IOException e) { 130 | System.out.println("Error on Youtube autoplay."); 131 | e.printStackTrace(); 132 | return null; 133 | } 134 | } else { 135 | return null; 136 | } 137 | } 138 | 139 | @Override 140 | public void onTrackStart(AudioPlayer player, AudioTrack track) { 141 | if (player.isPaused()) { 142 | player.setPaused(false); 143 | } 144 | } 145 | 146 | public String getPlaylist() { 147 | StringBuilder builder = new StringBuilder(); 148 | if (queue.isEmpty()) { 149 | builder.append("`Queue is empty.`"); 150 | } else { 151 | builder.append("Tracks queued: `").append(queue.size()).append("`\n"); 152 | int i = 0; 153 | Iterator x = queue.iterator(); 154 | while (x.hasNext()) { 155 | AudioTrack track = x.next(); 156 | builder.append("`").append(++i).append(". ").append(track.getInfo().title).append("`\n"); 157 | } 158 | } 159 | return builder.toString(); 160 | } 161 | 162 | public AudioTrack getNextTrack() { 163 | return queue.peek(); 164 | } 165 | 166 | public boolean isQueueEmpty() { 167 | return queue.isEmpty(); 168 | } 169 | 170 | public List getQueue() { 171 | List list = new ArrayList(); 172 | for (AudioTrack track : queue) { 173 | list.add(track); 174 | } 175 | return list; 176 | } 177 | 178 | public void flushQueue() { 179 | queue.clear(); 180 | } 181 | 182 | public void stopTrack() { 183 | player.playTrack(null); 184 | } 185 | 186 | public int flushQueue(int amount) { 187 | int num = 0; 188 | int size = queue.size(); 189 | for (int i = 0; i < amount && i < size; i++) { 190 | queue.poll(); 191 | num++; 192 | } 193 | return num; 194 | } 195 | 196 | // Messages temporary place 197 | public final String messageAddTrack(AudioTrack track, Message m) { 198 | StringBuilder builder = new StringBuilder(Emoji.ARROW_FORWARD.getUtf8()); 199 | builder.append(" Successfully added: **").append(track.getInfo().title).append("**"); 200 | builder.append(" (`").append(getTime(track.getDuration())).append("`)"); 201 | m.editMessage(builder.toString()).queue(); 202 | return builder.toString(); 203 | } 204 | 205 | public final String messageQueueTrack(AudioTrack track, Message m, int position) { 206 | StringBuilder builder = new StringBuilder(Emoji.PENCIL.getUtf8()); 207 | builder.append(" Successfully queued: **").append(track.getInfo().title).append("**"); 208 | builder.append(" (`").append(getTime(track.getDuration())).append("`)"); 209 | builder.append(" at position **" + position + "**"); 210 | m.editMessage(builder.toString()).queue(); 211 | return builder.toString(); 212 | } 213 | 214 | public final String messageNowPlayingTrackLong(AudioTrack track, Message m, String prefix) { 215 | if (track == null) { 216 | m.delete().queue(); 217 | return null; 218 | } 219 | StringBuilder builder = new StringBuilder(); 220 | if (prefix != null) { 221 | builder.append(prefix).append("\n"); 222 | } 223 | builder.append(Emoji.NOTES.getUtf8()); 224 | builder.append(" Now playing: **").append(track.getInfo().title).append("**. Left time: (`"); 225 | builder.append(getTime(track.getDuration() - track.getPosition())).append("`) Minutes."); 226 | m.editMessage(builder.toString()).queue(); 227 | return builder.toString(); 228 | } 229 | 230 | public final String messageNowPlayingTrackShort(AudioTrack track, Message m) { 231 | if (track == null) { 232 | m.delete().queue(); 233 | return null; 234 | } 235 | StringBuilder builder = new StringBuilder(); 236 | 237 | builder.append(Emoji.NOTES.getUtf8()); 238 | builder.append(" Now playing: **").append(track.getInfo().title).append("**."); 239 | m.editMessage(builder.toString()).queue(); 240 | return builder.toString(); 241 | } 242 | 243 | public final String messageNowPlayingTrackShort(AudioTrack track) { 244 | if (track == null) { 245 | return null; 246 | } 247 | StringBuilder builder = new StringBuilder(); 248 | 249 | builder.append(Emoji.NOTES.getUtf8()); 250 | builder.append(" Now playing: **").append(track.getInfo().title).append("**."); 251 | return builder.toString(); 252 | } 253 | 254 | public String getTime(long lng) { 255 | return (new SimpleDateFormat("mm:ss")).format(new Date(lng)); 256 | } 257 | 258 | public String getTimeBig(long lng) { 259 | return (new SimpleDateFormat("hh:mm:ss")).format(new Date(lng)); 260 | } 261 | } -------------------------------------------------------------------------------- /src/main/java/de/blockbuild/musikbot/metrics/Metrics.java: -------------------------------------------------------------------------------- 1 | package de.blockbuild.musikbot.metrics; 2 | 3 | import com.google.gson.JsonArray; 4 | import com.google.gson.JsonObject; 5 | import com.google.gson.JsonParser; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.configuration.file.YamlConfiguration; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.plugin.Plugin; 10 | import org.bukkit.plugin.RegisteredServiceProvider; 11 | import org.bukkit.plugin.ServicePriority; 12 | 13 | import javax.net.ssl.HttpsURLConnection; 14 | import java.io.*; 15 | import java.lang.reflect.InvocationTargetException; 16 | import java.lang.reflect.Method; 17 | import java.net.URL; 18 | import java.nio.charset.StandardCharsets; 19 | import java.util.*; 20 | import java.util.concurrent.Callable; 21 | import java.util.logging.Level; 22 | import java.util.zip.GZIPOutputStream; 23 | 24 | /** 25 | * bStats collects some data for plugin authors. 26 | *

27 | * Check out https://bStats.org/ to learn more about bStats! 28 | */ 29 | 30 | public class Metrics { 31 | static { 32 | // You can use the property to disable the check in your test environment 33 | if (System.getProperty("bstats.relocatecheck") == null 34 | || !System.getProperty("bstats.relocatecheck").equals("false")) { 35 | // Maven's Relocate is clever and changes strings, too. So we have to use this 36 | // little "trick" ... :D 37 | final String defaultPackage = new String( 38 | new byte[] { 'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't' }); 39 | final String examplePackage = new String( 40 | new byte[] { 'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e' }); 41 | // We want to make sure nobody just copy & pastes the example and use the wrong 42 | // package names 43 | if (Metrics.class.getPackage().getName().equals(defaultPackage) 44 | || Metrics.class.getPackage().getName().equals(examplePackage)) { 45 | throw new IllegalStateException("bStats Metrics class has not been relocated correctly!"); 46 | } 47 | } 48 | } 49 | 50 | // The version of this bStats class 51 | public static final int B_STATS_VERSION = 1; 52 | 53 | // The url to which the data is sent 54 | private static final String URL = "https://bStats.org/submitData/bukkit"; 55 | 56 | // Is bStats enabled on this server? 57 | private boolean enabled; 58 | 59 | // Should failed requests be logged? 60 | private static boolean logFailedRequests; 61 | 62 | // Should the sent data be logged? 63 | private static boolean logSentData; 64 | 65 | // Should the response text be logged? 66 | private static boolean logResponseStatusText; 67 | 68 | // The uuid of the server 69 | private static String serverUUID; 70 | 71 | // The plugin 72 | private final Plugin plugin; 73 | 74 | // A list with all custom charts 75 | private final List charts = new ArrayList<>(); 76 | 77 | /** 78 | * Class constructor. 79 | * 80 | * @param plugin The plugin which stats should be submitted. 81 | */ 82 | public Metrics(Plugin plugin) { 83 | if (plugin == null) { 84 | throw new IllegalArgumentException("Plugin cannot be null!"); 85 | } 86 | this.plugin = plugin; 87 | 88 | // Get the config file 89 | File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); 90 | File configFile = new File(bStatsFolder, "config.yml"); 91 | YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); 92 | 93 | // Check if the config file exists 94 | if (!config.isSet("serverUuid")) { 95 | 96 | // Add default values 97 | config.addDefault("enabled", true); 98 | // Every server gets it's unique random id. 99 | config.addDefault("serverUuid", UUID.randomUUID().toString()); 100 | // Should failed request be logged? 101 | config.addDefault("logFailedRequests", false); 102 | // Should the sent data be logged? 103 | config.addDefault("logSentData", false); 104 | // Should the response text be logged? 105 | config.addDefault("logResponseStatusText", false); 106 | 107 | // Inform the server owners about bStats 108 | config.options().header( 109 | "bStats collects some data for plugin authors like how many servers are using their plugins.\n" 110 | + "To honor their work, you should not disable it.\n" 111 | + "This has nearly no effect on the server performance!\n" 112 | + "Check out https://bStats.org/ to learn more :)") 113 | .copyDefaults(true); 114 | try { 115 | config.save(configFile); 116 | } catch (IOException ignored) { 117 | } 118 | } 119 | 120 | // Load the data 121 | enabled = config.getBoolean("enabled", true); 122 | serverUUID = config.getString("serverUuid"); 123 | logFailedRequests = config.getBoolean("logFailedRequests", false); 124 | logSentData = config.getBoolean("logSentData", false); 125 | logResponseStatusText = config.getBoolean("logResponseStatusText", false); 126 | 127 | if (enabled) { 128 | boolean found = false; 129 | // Search for all other bStats Metrics classes to see if we are the first one 130 | for (Class service : Bukkit.getServicesManager().getKnownServices()) { 131 | try { 132 | service.getField("B_STATS_VERSION"); // Our identifier :) 133 | found = true; // We aren't the first 134 | break; 135 | } catch (NoSuchFieldException ignored) { 136 | } 137 | } 138 | // Register our service 139 | Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal); 140 | if (!found) { 141 | // We are the first! 142 | startSubmitting(); 143 | } 144 | } 145 | } 146 | 147 | /** 148 | * Checks if bStats is enabled. 149 | * 150 | * @return Whether bStats is enabled or not. 151 | */ 152 | public boolean isEnabled() { 153 | return enabled; 154 | } 155 | 156 | /** 157 | * Adds a custom chart. 158 | * 159 | * @param chart The chart to add. 160 | */ 161 | public void addCustomChart(CustomChart chart) { 162 | if (chart == null) { 163 | throw new IllegalArgumentException("Chart cannot be null!"); 164 | } 165 | charts.add(chart); 166 | } 167 | 168 | /** 169 | * Starts the Scheduler which submits our data every 30 minutes. 170 | */ 171 | private void startSubmitting() { 172 | final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags 173 | timer.scheduleAtFixedRate(new TimerTask() { 174 | @Override 175 | public void run() { 176 | if (!plugin.isEnabled()) { // Plugin was disabled 177 | timer.cancel(); 178 | return; 179 | } 180 | // Nevertheless we want our code to run in the Bukkit main thread, so we have to 181 | // use the Bukkit scheduler 182 | // Don't be afraid! The connection to the bStats server is still async, only the 183 | // stats collection is sync ;) 184 | Bukkit.getScheduler().runTask(plugin, () -> submitData()); 185 | } 186 | }, 1000 * 60 * 5, 1000 * 60 * 30); 187 | // Submit the data every 30 minutes, first time after 5 minutes to give other 188 | // plugins enough time to start 189 | // WARNING: Changing the frequency has no effect but your plugin WILL be 190 | // blocked/deleted! 191 | // WARNING: Just don't do it! 192 | } 193 | 194 | /** 195 | * Gets the plugin specific data. This method is called using Reflection. 196 | * 197 | * @return The plugin specific data. 198 | */ 199 | public JsonObject getPluginData() { 200 | JsonObject data = new JsonObject(); 201 | 202 | String pluginName = plugin.getDescription().getName(); 203 | String pluginVersion = plugin.getDescription().getVersion(); 204 | 205 | data.addProperty("pluginName", pluginName); // Append the name of the plugin 206 | data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin 207 | JsonArray customCharts = new JsonArray(); 208 | for (CustomChart customChart : charts) { 209 | // Add the data of the custom charts 210 | JsonObject chart = customChart.getRequestJsonObject(); 211 | if (chart == null) { // If the chart is null, we skip it 212 | continue; 213 | } 214 | customCharts.add(chart); 215 | } 216 | data.add("customCharts", customCharts); 217 | 218 | return data; 219 | } 220 | 221 | /** 222 | * Gets the server specific data. 223 | * 224 | * @return The server specific data. 225 | */ 226 | private JsonObject getServerData() { 227 | // Minecraft specific data 228 | int playerAmount; 229 | try { 230 | // Around MC 1.8 the return type was changed to a collection from an array, 231 | // This fixes java.lang.NoSuchMethodError: 232 | // org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection; 233 | Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers"); 234 | playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class) 235 | ? ((Collection) onlinePlayersMethod.invoke(Bukkit.getServer())).size() 236 | : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length; 237 | } catch (Exception e) { 238 | playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed 239 | } 240 | int onlineMode = Bukkit.getOnlineMode() ? 1 : 0; 241 | String bukkitVersion = Bukkit.getVersion(); 242 | String bukkitName = Bukkit.getName(); 243 | 244 | // OS/Java specific data 245 | String javaVersion = System.getProperty("java.version"); 246 | String osName = System.getProperty("os.name"); 247 | String osArch = System.getProperty("os.arch"); 248 | String osVersion = System.getProperty("os.version"); 249 | int coreCount = Runtime.getRuntime().availableProcessors(); 250 | 251 | JsonObject data = new JsonObject(); 252 | 253 | data.addProperty("serverUUID", serverUUID); 254 | 255 | data.addProperty("playerAmount", playerAmount); 256 | data.addProperty("onlineMode", onlineMode); 257 | data.addProperty("bukkitVersion", bukkitVersion); 258 | data.addProperty("bukkitName", bukkitName); 259 | 260 | data.addProperty("javaVersion", javaVersion); 261 | data.addProperty("osName", osName); 262 | data.addProperty("osArch", osArch); 263 | data.addProperty("osVersion", osVersion); 264 | data.addProperty("coreCount", coreCount); 265 | 266 | return data; 267 | } 268 | 269 | /** 270 | * Collects the data and sends it afterwards. 271 | */ 272 | private void submitData() { 273 | final JsonObject data = getServerData(); 274 | 275 | JsonArray pluginData = new JsonArray(); 276 | // Search for all other bStats Metrics classes to get their plugin data 277 | for (Class service : Bukkit.getServicesManager().getKnownServices()) { 278 | try { 279 | service.getField("B_STATS_VERSION"); // Our identifier :) 280 | 281 | for (RegisteredServiceProvider provider : Bukkit.getServicesManager().getRegistrations(service)) { 282 | try { 283 | Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider()); 284 | if (plugin instanceof JsonObject) { 285 | pluginData.add((JsonObject) plugin); 286 | } else { // old bstats version compatibility 287 | try { 288 | Class jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject"); 289 | if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) { 290 | Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString"); 291 | jsonStringGetter.setAccessible(true); 292 | String jsonString = (String) jsonStringGetter.invoke(plugin); 293 | JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject(); 294 | pluginData.add(object); 295 | } 296 | } catch (ClassNotFoundException e) { 297 | // minecraft version 1.14+ 298 | if (logFailedRequests) { 299 | this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e); 300 | } 301 | continue; // continue looping since we cannot do any other thing. 302 | } 303 | } 304 | } catch (NullPointerException | NoSuchMethodException | IllegalAccessException 305 | | InvocationTargetException ignored) { 306 | } 307 | } 308 | } catch (NoSuchFieldException ignored) { 309 | } 310 | } 311 | 312 | data.add("plugins", pluginData); 313 | 314 | // Create a new thread for the connection to the bStats server 315 | new Thread(new Runnable() { 316 | @Override 317 | public void run() { 318 | try { 319 | // Send the data 320 | sendData(plugin, data); 321 | } catch (Exception e) { 322 | // Something went wrong! :( 323 | if (logFailedRequests) { 324 | plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), 325 | e); 326 | } 327 | } 328 | } 329 | }).start(); 330 | } 331 | 332 | /** 333 | * Sends the data to the bStats server. 334 | * 335 | * @param plugin Any plugin. It's just used to get a logger instance. 336 | * @param data The data to send. 337 | * @throws Exception If the request failed. 338 | */ 339 | private static void sendData(Plugin plugin, JsonObject data) throws Exception { 340 | if (data == null) { 341 | throw new IllegalArgumentException("Data cannot be null!"); 342 | } 343 | if (Bukkit.isPrimaryThread()) { 344 | throw new IllegalAccessException("This method must not be called from the main thread!"); 345 | } 346 | if (logSentData) { 347 | plugin.getLogger().info("Sending data to bStats: " + data.toString()); 348 | } 349 | HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection(); 350 | 351 | // Compress the data to save bandwidth 352 | byte[] compressedData = compress(data.toString()); 353 | 354 | // Add headers 355 | connection.setRequestMethod("POST"); 356 | connection.addRequestProperty("Accept", "application/json"); 357 | connection.addRequestProperty("Connection", "close"); 358 | connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request 359 | connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); 360 | connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format 361 | connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION); 362 | 363 | // Send data 364 | connection.setDoOutput(true); 365 | DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()); 366 | outputStream.write(compressedData); 367 | outputStream.flush(); 368 | outputStream.close(); 369 | 370 | InputStream inputStream = connection.getInputStream(); 371 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 372 | 373 | StringBuilder builder = new StringBuilder(); 374 | String line; 375 | while ((line = bufferedReader.readLine()) != null) { 376 | builder.append(line); 377 | } 378 | bufferedReader.close(); 379 | if (logResponseStatusText) { 380 | plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString()); 381 | } 382 | } 383 | 384 | /** 385 | * Gzips the given String. 386 | * 387 | * @param str The string to gzip. 388 | * @return The gzipped String. 389 | * @throws IOException If the compression failed. 390 | */ 391 | private static byte[] compress(final String str) throws IOException { 392 | if (str == null) { 393 | return null; 394 | } 395 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 396 | GZIPOutputStream gzip = new GZIPOutputStream(outputStream); 397 | gzip.write(str.getBytes(StandardCharsets.UTF_8)); 398 | gzip.close(); 399 | return outputStream.toByteArray(); 400 | } 401 | 402 | /** 403 | * Represents a custom chart. 404 | */ 405 | public static abstract class CustomChart { 406 | 407 | // The id of the chart 408 | final String chartId; 409 | 410 | /** 411 | * Class constructor. 412 | * 413 | * @param chartId The id of the chart. 414 | */ 415 | CustomChart(String chartId) { 416 | if (chartId == null || chartId.isEmpty()) { 417 | throw new IllegalArgumentException("ChartId cannot be null or empty!"); 418 | } 419 | this.chartId = chartId; 420 | } 421 | 422 | private JsonObject getRequestJsonObject() { 423 | JsonObject chart = new JsonObject(); 424 | chart.addProperty("chartId", chartId); 425 | try { 426 | JsonObject data = getChartData(); 427 | if (data == null) { 428 | // If the data is null we don't send the chart. 429 | return null; 430 | } 431 | chart.add("data", data); 432 | } catch (Throwable t) { 433 | if (logFailedRequests) { 434 | Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t); 435 | } 436 | return null; 437 | } 438 | return chart; 439 | } 440 | 441 | protected abstract JsonObject getChartData() throws Exception; 442 | 443 | } 444 | 445 | /** 446 | * Represents a custom simple pie. 447 | */ 448 | public static class SimplePie extends CustomChart { 449 | 450 | private final Callable callable; 451 | 452 | /** 453 | * Class constructor. 454 | * 455 | * @param chartId The id of the chart. 456 | * @param callable The callable which is used to request the chart data. 457 | */ 458 | public SimplePie(String chartId, Callable callable) { 459 | super(chartId); 460 | this.callable = callable; 461 | } 462 | 463 | @Override 464 | protected JsonObject getChartData() throws Exception { 465 | JsonObject data = new JsonObject(); 466 | String value = callable.call(); 467 | if (value == null || value.isEmpty()) { 468 | // Null = skip the chart 469 | return null; 470 | } 471 | data.addProperty("value", value); 472 | return data; 473 | } 474 | } 475 | 476 | /** 477 | * Represents a custom advanced pie. 478 | */ 479 | public static class AdvancedPie extends CustomChart { 480 | 481 | private final Callable> callable; 482 | 483 | /** 484 | * Class constructor. 485 | * 486 | * @param chartId The id of the chart. 487 | * @param callable The callable which is used to request the chart data. 488 | */ 489 | public AdvancedPie(String chartId, Callable> callable) { 490 | super(chartId); 491 | this.callable = callable; 492 | } 493 | 494 | @Override 495 | protected JsonObject getChartData() throws Exception { 496 | JsonObject data = new JsonObject(); 497 | JsonObject values = new JsonObject(); 498 | Map map = callable.call(); 499 | if (map == null || map.isEmpty()) { 500 | // Null = skip the chart 501 | return null; 502 | } 503 | boolean allSkipped = true; 504 | for (Map.Entry entry : map.entrySet()) { 505 | if (entry.getValue() == 0) { 506 | continue; // Skip this invalid 507 | } 508 | allSkipped = false; 509 | values.addProperty(entry.getKey(), entry.getValue()); 510 | } 511 | if (allSkipped) { 512 | // Null = skip the chart 513 | return null; 514 | } 515 | data.add("values", values); 516 | return data; 517 | } 518 | } 519 | 520 | /** 521 | * Represents a custom drilldown pie. 522 | */ 523 | public static class DrilldownPie extends CustomChart { 524 | 525 | private final Callable>> callable; 526 | 527 | /** 528 | * Class constructor. 529 | * 530 | * @param chartId The id of the chart. 531 | * @param callable The callable which is used to request the chart data. 532 | */ 533 | public DrilldownPie(String chartId, Callable>> callable) { 534 | super(chartId); 535 | this.callable = callable; 536 | } 537 | 538 | @Override 539 | public JsonObject getChartData() throws Exception { 540 | JsonObject data = new JsonObject(); 541 | JsonObject values = new JsonObject(); 542 | Map> map = callable.call(); 543 | if (map == null || map.isEmpty()) { 544 | // Null = skip the chart 545 | return null; 546 | } 547 | boolean reallyAllSkipped = true; 548 | for (Map.Entry> entryValues : map.entrySet()) { 549 | JsonObject value = new JsonObject(); 550 | boolean allSkipped = true; 551 | for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { 552 | value.addProperty(valueEntry.getKey(), valueEntry.getValue()); 553 | allSkipped = false; 554 | } 555 | if (!allSkipped) { 556 | reallyAllSkipped = false; 557 | values.add(entryValues.getKey(), value); 558 | } 559 | } 560 | if (reallyAllSkipped) { 561 | // Null = skip the chart 562 | return null; 563 | } 564 | data.add("values", values); 565 | return data; 566 | } 567 | } 568 | 569 | /** 570 | * Represents a custom single line chart. 571 | */ 572 | public static class SingleLineChart extends CustomChart { 573 | 574 | private final Callable callable; 575 | 576 | /** 577 | * Class constructor. 578 | * 579 | * @param chartId The id of the chart. 580 | * @param callable The callable which is used to request the chart data. 581 | */ 582 | public SingleLineChart(String chartId, Callable callable) { 583 | super(chartId); 584 | this.callable = callable; 585 | } 586 | 587 | @Override 588 | protected JsonObject getChartData() throws Exception { 589 | JsonObject data = new JsonObject(); 590 | int value = callable.call(); 591 | if (value == 0) { 592 | // Null = skip the chart 593 | return null; 594 | } 595 | data.addProperty("value", value); 596 | return data; 597 | } 598 | 599 | } 600 | 601 | /** 602 | * Represents a custom multi line chart. 603 | */ 604 | public static class MultiLineChart extends CustomChart { 605 | 606 | private final Callable> callable; 607 | 608 | /** 609 | * Class constructor. 610 | * 611 | * @param chartId The id of the chart. 612 | * @param callable The callable which is used to request the chart data. 613 | */ 614 | public MultiLineChart(String chartId, Callable> callable) { 615 | super(chartId); 616 | this.callable = callable; 617 | } 618 | 619 | @Override 620 | protected JsonObject getChartData() throws Exception { 621 | JsonObject data = new JsonObject(); 622 | JsonObject values = new JsonObject(); 623 | Map map = callable.call(); 624 | if (map == null || map.isEmpty()) { 625 | // Null = skip the chart 626 | return null; 627 | } 628 | boolean allSkipped = true; 629 | for (Map.Entry entry : map.entrySet()) { 630 | if (entry.getValue() == 0) { 631 | continue; // Skip this invalid 632 | } 633 | allSkipped = false; 634 | values.addProperty(entry.getKey(), entry.getValue()); 635 | } 636 | if (allSkipped) { 637 | // Null = skip the chart 638 | return null; 639 | } 640 | data.add("values", values); 641 | return data; 642 | } 643 | 644 | } 645 | 646 | /** 647 | * Represents a custom simple bar chart. 648 | */ 649 | public static class SimpleBarChart extends CustomChart { 650 | 651 | private final Callable> callable; 652 | 653 | /** 654 | * Class constructor. 655 | * 656 | * @param chartId The id of the chart. 657 | * @param callable The callable which is used to request the chart data. 658 | */ 659 | public SimpleBarChart(String chartId, Callable> callable) { 660 | super(chartId); 661 | this.callable = callable; 662 | } 663 | 664 | @Override 665 | protected JsonObject getChartData() throws Exception { 666 | JsonObject data = new JsonObject(); 667 | JsonObject values = new JsonObject(); 668 | Map map = callable.call(); 669 | if (map == null || map.isEmpty()) { 670 | // Null = skip the chart 671 | return null; 672 | } 673 | for (Map.Entry entry : map.entrySet()) { 674 | JsonArray categoryValues = new JsonArray(); 675 | categoryValues.add(entry.getValue()); 676 | values.add(entry.getKey(), categoryValues); 677 | } 678 | data.add("values", values); 679 | return data; 680 | } 681 | 682 | } 683 | 684 | /** 685 | * Represents a custom advanced bar chart. 686 | */ 687 | public static class AdvancedBarChart extends CustomChart { 688 | 689 | private final Callable> callable; 690 | 691 | /** 692 | * Class constructor. 693 | * 694 | * @param chartId The id of the chart. 695 | * @param callable The callable which is used to request the chart data. 696 | */ 697 | public AdvancedBarChart(String chartId, Callable> callable) { 698 | super(chartId); 699 | this.callable = callable; 700 | } 701 | 702 | @Override 703 | protected JsonObject getChartData() throws Exception { 704 | JsonObject data = new JsonObject(); 705 | JsonObject values = new JsonObject(); 706 | Map map = callable.call(); 707 | if (map == null || map.isEmpty()) { 708 | // Null = skip the chart 709 | return null; 710 | } 711 | boolean allSkipped = true; 712 | for (Map.Entry entry : map.entrySet()) { 713 | if (entry.getValue().length == 0) { 714 | continue; // Skip this invalid 715 | } 716 | allSkipped = false; 717 | JsonArray categoryValues = new JsonArray(); 718 | for (int categoryValue : entry.getValue()) { 719 | categoryValues.add(categoryValue); 720 | } 721 | values.add(entry.getKey(), categoryValues); 722 | } 723 | if (allSkipped) { 724 | // Null = skip the chart 725 | return null; 726 | } 727 | data.add("values", values); 728 | return data; 729 | } 730 | } 731 | } 732 | -------------------------------------------------------------------------------- /src/main/resources/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Block-Build/MusikBot/de9f60e55f3ecb88fa04627834d5983175050e21/src/main/resources/64.png -------------------------------------------------------------------------------- /src/main/resources/Sample_BotConfig.yml: -------------------------------------------------------------------------------- 1 | # MusikBot by Block-Build 2 | # +===================+ 3 | # | BOT CONFIGURATION | 4 | # +===================+ 5 | # 6 | # You have to insert the bot token and owner id. 7 | # Instructions on: `https://www.spigotmc.org/resources/the-discord-musikbot-on-minecraft.64277/` 8 | # Support/Suggestions/Bugs? Have a look on this site: `https://github.com/Block-Build/MusikBot` 9 | 10 | # The Bot token can be found on this site: "https://discordapp.com/developers/applications/". 11 | # Example Token: NTIzOTI3MzY3NDY3NjYzNDAx.D0G_Yg.L0v8GGJdMRVLhdujEizj6K37IjE 12 | Bot_Token: insert token here 13 | 14 | # The Discord user ID of the Bot, server or guild owner. 15 | # You could easy get the User ID from discord by right click after enableing the Developer Mode 16 | # Example ID: 012345678912345678 17 | Owner_ID: '12345' 18 | 19 | # The command trigger is a character the bot use to identify a command. 20 | # Example Trigger: '+' Example command: +play 21 | Command_Trigger: '!' 22 | 23 | # The game of the bot. 24 | # This will be shown under the name of the bot. "Playing ". 25 | Game: Ready for playing music. !Play 26 | 27 | # The emojis the bot will use to responce if a command was successfull. 28 | Emojis: 29 | Success: 😃 30 | Warning: 😮 31 | Error: 😦 32 | 33 | # You will need the invite URL to join the bot a discord guild. 34 | Invite_URL: '`https://discordapp.com/oauth2/authorize?scope=bot&client_id=012345678912345678&permissions=3234880`' 35 | -------------------------------------------------------------------------------- /src/main/resources/Sample_GuildConfig.yml: -------------------------------------------------------------------------------- 1 | # MusikBot by Block-Build 2 | # +=====================+ 3 | # | GUILD CONFIGURATION | 4 | # +=====================+ 5 | 6 | # The name of the guild 7 | Guild_Name: Guild_Name 8 | 9 | # Sound volume of the bot from 1 to 100. 10 | Volume: 100 11 | 12 | # The delay/time in Minutes after the command and bot responce get deleted. 13 | # The bot needs the 'Message_Manage' permission. 14 | # Set to 0 to disable. 15 | Delete_Command_Massages_Delay: 0 16 | 17 | # Enable or disable whitelist 18 | Whitelist_Enabled: false 19 | 20 | # List of whitelistet guild member 21 | # Example: 22 | # Whitelist: 23 | # - 0123456789012345678 24 | # - 1234567890123456789 25 | Whitelist: [] 26 | 27 | # List of blacklisted guild member 28 | # Example: 29 | # Blacklist: 30 | # - 0123456789012345678 31 | # - 1234567890123456789 32 | Blacklist: [] 33 | 34 | # Discord role you need to use the category of commands 35 | # If "Music_Commands:" is set to '' or '@everyone' everyone is able to use music commands 36 | # If "Music_Commands:" is set to 'dj' only member with a role called "dj" are able to use this commands 37 | # Example Music_Commands: 'dj' 38 | Command_Permission_Roles: 39 | Music_Commands: '' 40 | Radio_Commands: '' 41 | Connection_Commands: '' 42 | Setup_Commands: '' 43 | 44 | # Sould the bot disconnect automaticly if it is the last member in a channel? 45 | Auto_Disconnect_If_Alone: false 46 | 47 | # Sould the bot disconnect automaticly if the last track is finished? 48 | Auto_Disconnect_After_Last_Track: false 49 | 50 | # Should the bot automaticly join the guild after startup? 51 | Auto_Connect_On_Startup: 52 | # Enable or disable 53 | Enabled: false 54 | # The ID of the VoiceChannel the bot sould join. 55 | # Example: 259798211111726208 56 | VoiceChannelId: 0 57 | # Should the bot start a track after join? 58 | # Insert an URL. 59 | Track: '' 60 | 61 | # Send now playing Track title to textchannel on next track 62 | Message_Now_Playing_Track: 63 | # Enable or disable 64 | Enabled: false 65 | # The ID of the TextChannel to use. 66 | # Example: 259798211111726208 67 | TextChannelId: 0 68 | 69 | # A specific TextChannel the bot only listen to. 70 | Default_TextChannel: 71 | # Enable or disable 72 | Enabled: false 73 | # The ID of the TextChannel 74 | # Example: 259798211111726208 75 | TextChannelId: 0 76 | 77 | # A specific VoiceChannel the bot only can join. 78 | Default_VoiceChannel: 79 | # Enable or disable 80 | Enabled: false 81 | # The ID of the VoiceChannel 82 | # Example: 259798211111726208 83 | VoiceChannelId: 0 84 | -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: MusikBot 2 | version: 1.2.5 3 | author: BlockBuild 4 | description: Discord Music Bot 5 | 6 | main: de.blockbuild.musikbot.Main --------------------------------------------------------------------------------