mirror of
https://github.com/JonasunderscoreJones/ZtereoMUSIC.git
synced 2025-10-24 13:09:18 +02:00
Initial commit with base
This commit is contained in:
commit
6d7addc22d
20 changed files with 810 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
build/
|
||||
.idea/
|
||||
.gradle/
|
||||
24
README.md
Normal file
24
README.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# ZtereoMUSIC
|
||||
### Is a discord music bot written in java using JDA. The name is prone to be changed in the future.
|
||||
|
||||
## How to use:
|
||||
To be determined
|
||||
|
||||
## To Dos:
|
||||
- Play command
|
||||
- Pause command
|
||||
- Skip command
|
||||
- Disconnect command
|
||||
- Help command
|
||||
- Queue commands:
|
||||
- Queue to view the queue
|
||||
- Queue remove [index] to remove an element
|
||||
- Queue clear to clear queue
|
||||
- Toggleable permissions system based on DJ role and based on server
|
||||
- Ability to search the song name
|
||||
- Spotify URLs/playlists support
|
||||
- Fancy embeds for everything!
|
||||
- Slash commands? idk
|
||||
- Proper database for server preferences (prefix etc)
|
||||
- Various listeners if there's nobody in vc for a while or if it gets disconnected or if last disconnects (stop playin)
|
||||
- Other TBA...
|
||||
25
build.gradle
Normal file
25
build.gradle
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
plugins {
|
||||
id 'application'
|
||||
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
||||
id "io.freefair.lombok" version "6.2.0"
|
||||
}
|
||||
|
||||
mainClassName = 'codes.ztereohype.ztereomusic.Bot'
|
||||
|
||||
version '0.0.1'
|
||||
|
||||
sourceCompatibility = targetCompatibility = 16
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://maven.shadew.net/" }
|
||||
maven { url "https://m2.dv8tion.net/releases" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "net.dv8tion:JDA:4.3.0_277"
|
||||
implementation "com.sedmelluq:lavaplayer:1.3.77"
|
||||
implementation "net.shadew:json:0.1"
|
||||
}
|
||||
|
||||
compileJava.options.encoding = 'UTF-8'
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
185
gradlew
vendored
Executable file
185
gradlew
vendored
Executable file
|
|
@ -0,0 +1,185 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MSYS* | MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
89
gradlew.bat
vendored
Normal file
89
gradlew.bat
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
1
settings.gradle
Normal file
1
settings.gradle
Normal file
|
|
@ -0,0 +1 @@
|
|||
rootProject.name = 'ZtereoMUSIC'
|
||||
61
src/main/java/codes/ztereohype/ztereomusic/Bot.java
Normal file
61
src/main/java/codes/ztereohype/ztereomusic/Bot.java
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package codes.ztereohype.ztereomusic;
|
||||
|
||||
import codes.ztereohype.ztereomusic.audio.TrackScheduer;
|
||||
import codes.ztereohype.ztereomusic.command.Command;
|
||||
import codes.ztereohype.ztereomusic.command.commands.Ping;
|
||||
import codes.ztereohype.ztereomusic.command.commands.Playtest;
|
||||
import codes.ztereohype.ztereomusic.database.Config;
|
||||
import codes.ztereohype.ztereomusic.listeners.CommandListener;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
||||
import lombok.Getter;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.JDABuilder;
|
||||
import net.dv8tion.jda.api.entities.VoiceChannel;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Bot {
|
||||
private static @Getter Config config;
|
||||
private static @Getter JDA bot;
|
||||
|
||||
private static @Getter final Map<String, Command> commandMap = new HashMap<>();
|
||||
private static @Getter final Map<String, String> commandAliases = new HashMap<>();
|
||||
|
||||
public static AudioPlayerManager playerManager;
|
||||
public static Map<VoiceChannel, TrackScheduer> trackScheduerMap = new HashMap<>();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
config = new Config("./config.json5");
|
||||
bot = JDABuilder.createDefault(config.getPropreties().get("token")).build().awaitReady();
|
||||
|
||||
setCommands();
|
||||
setupAudio();
|
||||
setListeners();
|
||||
}
|
||||
|
||||
public static void setCommands() {
|
||||
Ping ping = new Ping();
|
||||
commandMap.put(ping.getMeta().getName(), ping);
|
||||
|
||||
Playtest playtest = new Playtest();
|
||||
commandMap.put(playtest.getMeta().getName(), playtest);
|
||||
|
||||
for (String commandName : commandMap.keySet()) {
|
||||
for (String aliasName : commandMap.get(commandName).getMeta().getAliases()) {
|
||||
commandAliases.put(aliasName, commandName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupAudio() {
|
||||
playerManager = new DefaultAudioPlayerManager();
|
||||
AudioSourceManagers.registerRemoteSources(playerManager);
|
||||
}
|
||||
|
||||
public static void setListeners() {
|
||||
bot.addEventListener(new CommandListener());
|
||||
}
|
||||
}
|
||||
14
src/main/java/codes/ztereohype/ztereomusic/api/Search.java
Normal file
14
src/main/java/codes/ztereohype/ztereomusic/api/Search.java
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package codes.ztereohype.ztereomusic.api;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Search {
|
||||
public String getVideoUrl(String title) throws IOException {
|
||||
return "WIP";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package codes.ztereohype.ztereomusic.audio;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame;
|
||||
import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager;
|
||||
import net.dv8tion.jda.api.audio.AudioSendHandler;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class AudioPlayerSendHandler implements AudioSendHandler {
|
||||
private final AudioPlayer audioPlayer;
|
||||
private AudioFrame lastFrame;
|
||||
|
||||
public AudioPlayerSendHandler(AudioPlayer audioPlayer) {
|
||||
this.audioPlayer = audioPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProvide() {
|
||||
lastFrame = audioPlayer.provide();
|
||||
return lastFrame != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer provide20MsAudio() {
|
||||
return ByteBuffer.wrap(lastFrame.getData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpus() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
package codes.ztereohype.ztereomusic.audio;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.player.event.AudioEvent;
|
||||
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter;
|
||||
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventListener;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
|
||||
import net.dv8tion.jda.api.entities.Invite;
|
||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TrackScheduer extends AudioEventAdapter {
|
||||
|
||||
private final AudioPlayer player;
|
||||
private final List<AudioTrack> trackQueue = new ArrayList<AudioTrack>();
|
||||
private AudioTrack currentTrack;
|
||||
private final MessageChannel infoChannel;
|
||||
|
||||
public TrackScheduer(AudioPlayer player, MessageChannel infoChannel) {
|
||||
this.player = player;
|
||||
this.infoChannel = infoChannel;
|
||||
}
|
||||
|
||||
public void queue(AudioTrack track) {
|
||||
// change this to add to queue and call onTrackEnd!
|
||||
if (this.currentTrack == null) {
|
||||
System.out.println("Playing song directly as there is no song playing rn");
|
||||
this.currentTrack = track;
|
||||
player.playTrack(track);
|
||||
} else {
|
||||
trackQueue.add(track);
|
||||
System.out.println("Added song to queue");
|
||||
}
|
||||
}
|
||||
|
||||
public AudioPlayer getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerPause(AudioPlayer player) {
|
||||
infoChannel.sendMessage("Pausing...").queue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerResume(AudioPlayer player) {
|
||||
infoChannel.sendMessage("Resuming...").queue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackStart(AudioPlayer player, AudioTrack track) {
|
||||
infoChannel.sendMessage("Starting track: " + track.getInfo().title).queue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
|
||||
currentTrack = null;
|
||||
|
||||
if (endReason.mayStartNext) {
|
||||
if (trackQueue.isEmpty()) {
|
||||
System.out.println("track finishd, no more tracks in queue!");
|
||||
infoChannel.sendMessage("no more tracks in queue!").queue();
|
||||
} else {
|
||||
System.out.println("track finishd, trying next track");
|
||||
AudioTrack nextTrack = trackQueue.get(0);
|
||||
trackQueue.remove(0);
|
||||
currentTrack = nextTrack;
|
||||
infoChannel.sendMessage("Playing next track: " + nextTrack.getInfo().title).queue();
|
||||
player.playTrack(currentTrack);
|
||||
}
|
||||
} else {
|
||||
System.out.println("track finishd, cant start next, bye");
|
||||
infoChannel.sendMessage("oopsie woopsie byebye").queue();
|
||||
}
|
||||
|
||||
// endReason == FINISHED: A track finished or died by an exception (mayStartNext = true).
|
||||
// endReason == LOAD_FAILED: Loading of a track failed (mayStartNext = true).
|
||||
// endReason == STOPPED: The player was stopped.
|
||||
// endReason == REPLACED: Another track started playing while this had not finished
|
||||
// endReason == CLEANUP: Player hasn't been queried for a while, if you want you can put a
|
||||
// clone of this back to your queue
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackException(AudioPlayer player, AudioTrack track, FriendlyException exception) {
|
||||
// An already playing track threw an exception (track end event will still be received separately)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackStuck(AudioPlayer player, AudioTrack track, long thresholdMs) {
|
||||
// Audio track has been unable to provide us any audio, might want to just start a new track
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package codes.ztereohype.ztereomusic.command;
|
||||
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
|
||||
// TODO: add categories/groups and perms but in a smart way pls
|
||||
public interface Command {
|
||||
CommandMeta getMeta();
|
||||
void execute(MessageReceivedEvent messageRecievedEvent, String[] args);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package codes.ztereohype.ztereomusic.command;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class CommandMeta {
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final String[] aliases;
|
||||
private final boolean isNsfw;
|
||||
private final boolean isHidden;
|
||||
|
||||
public CommandMeta(String name, String description, String[] aliases, boolean isNsfw, boolean isHidden) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.aliases = aliases;
|
||||
this.isNsfw = isNsfw;
|
||||
this.isHidden = isHidden;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package codes.ztereohype.ztereomusic.command.commands;
|
||||
|
||||
import codes.ztereohype.ztereomusic.command.Command;
|
||||
import codes.ztereohype.ztereomusic.command.CommandMeta;
|
||||
import lombok.Getter;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Ping implements Command {
|
||||
CommandMeta meta = new CommandMeta("ping", "A command to get pinged", new String[]{"pong", "pog"}, false, false);
|
||||
private List<String> list;
|
||||
|
||||
@Override
|
||||
public CommandMeta getMeta() {
|
||||
return this.meta;
|
||||
}
|
||||
|
||||
public void execute(MessageReceivedEvent messageEvent, String[] args) {
|
||||
messageEvent.getMessage().reply("get ping'd lolmao").queue();
|
||||
list.add("owo");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
package codes.ztereohype.ztereomusic.command.commands;
|
||||
|
||||
import codes.ztereohype.ztereomusic.Bot;
|
||||
import codes.ztereohype.ztereomusic.audio.AudioPlayerSendHandler;
|
||||
import codes.ztereohype.ztereomusic.audio.TrackScheduer;
|
||||
import codes.ztereohype.ztereomusic.command.Command;
|
||||
import codes.ztereohype.ztereomusic.command.CommandMeta;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.managers.AudioManager;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Playtest implements Command {
|
||||
CommandMeta meta = new CommandMeta("playtest", "A command to test music commands", new String[]{"play"}, false, false);
|
||||
|
||||
@Override
|
||||
public CommandMeta getMeta() {
|
||||
return this.meta;
|
||||
}
|
||||
|
||||
public void execute(MessageReceivedEvent messageEvent, String[] args) {
|
||||
Member author = Objects.requireNonNull(messageEvent.getMember());
|
||||
|
||||
if (author.getVoiceState() == null) {
|
||||
messageEvent.getChannel().sendMessage("I was unable to access your information... strange...").queue();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!author.getVoiceState().inVoiceChannel()) {
|
||||
messageEvent.getMessage().reply("You are not in a voice channel!").queue();
|
||||
return;
|
||||
}
|
||||
|
||||
Guild guild = messageEvent.getGuild();
|
||||
VoiceChannel voiceChannel = author.getVoiceState().getChannel();
|
||||
MessageChannel messageChannel = messageEvent.getChannel();
|
||||
AudioManager manager = guild.getAudioManager();
|
||||
AudioPlayerManager playerManager = Bot.playerManager;
|
||||
|
||||
// check if args merged are/have url, if so try to feed it into lava, else try to youtube api the fuck out of it.
|
||||
String mergedArgs = String.join(" ", args);
|
||||
|
||||
//todo find better one
|
||||
Pattern urlPattern = Pattern.compile("^(http|https)://([a-z]+\\.[a-z]+)+/\\S+$", Pattern.CASE_INSENSITIVE);
|
||||
Matcher matchedUrls = urlPattern.matcher(mergedArgs);
|
||||
boolean urlFound = matchedUrls.find();
|
||||
|
||||
String identifier;
|
||||
if (!urlFound) {
|
||||
// youtube api shit
|
||||
messageEvent.getMessage().reply("please send a link").queue();
|
||||
return;
|
||||
} else {
|
||||
// set identifier to the parsed url
|
||||
identifier = mergedArgs;
|
||||
}
|
||||
|
||||
|
||||
/* Generally you would want to create a player per every
|
||||
different target you might want to separately stream audio to.
|
||||
It is totally fine to create them even if they are unlikely to be used,
|
||||
as they do not use any resources on their own without an active track. */
|
||||
AudioPlayer player;
|
||||
TrackScheduer trackScheduler;
|
||||
|
||||
boolean isInVC = manager.isConnected();
|
||||
boolean isInSameVC = isInVC && Objects.equals(manager.getConnectedChannel(), voiceChannel);
|
||||
|
||||
if (isInSameVC && Bot.trackScheduerMap.containsKey(voiceChannel)) {
|
||||
System.out.println("Found a trackScheduler for this VC already! reusing...");
|
||||
|
||||
trackScheduler = Bot.trackScheduerMap.get(voiceChannel);
|
||||
player = trackScheduler.getPlayer();
|
||||
|
||||
player.addListener(trackScheduler);
|
||||
|
||||
} else {
|
||||
// Maybe we don't wanna clear the whole queue when he gets kicked out?
|
||||
// idk
|
||||
if (Bot.trackScheduerMap.containsKey(voiceChannel)) {
|
||||
System.out.println("Found old trackScheduler for this channel. Cleaning it up...");
|
||||
Bot.trackScheduerMap.remove(voiceChannel);
|
||||
}
|
||||
|
||||
System.out.println("Creating a new trackScheduler...");
|
||||
|
||||
player = playerManager.createPlayer();
|
||||
trackScheduler = new TrackScheduer(player, messageChannel);
|
||||
|
||||
player.addListener(trackScheduler);
|
||||
manager.setSendingHandler(new AudioPlayerSendHandler(player));
|
||||
manager.openAudioConnection(voiceChannel);
|
||||
|
||||
Bot.trackScheduerMap.put(voiceChannel, trackScheduler);
|
||||
}
|
||||
|
||||
playerManager.loadItem(identifier, new AudioLoadResultHandler() {
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack track) {
|
||||
trackScheduler.queue(track);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playlistLoaded(AudioPlaylist playlist) {
|
||||
for (AudioTrack track : playlist.getTracks()) {
|
||||
trackScheduler.queue(track);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMatches() {
|
||||
messageEvent.getMessage().reply("I found no matches for that song!").queue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException throwable) {
|
||||
messageEvent.getMessage().reply("everything blew up and died. i'm sorry.").queue();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package codes.ztereohype.ztereomusic.database;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.shadew.json.Json;
|
||||
import net.shadew.json.JsonNode;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Config {
|
||||
private @Getter final Map<String, String> propreties = new HashMap<>();
|
||||
private final String path;
|
||||
|
||||
public Config(String pathname) throws Exception {
|
||||
Json json5 = Json.json5();
|
||||
JsonNode tree = json5.parse(new File(pathname));
|
||||
this.path = pathname;
|
||||
|
||||
for (String key : tree.keys()) {
|
||||
propreties.put(key, tree.get(key).asString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
//package codes.ztereohype.ztereomusic.listeners;
|
||||
//
|
||||
//import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
//
|
||||
//public class AloneInVcListener extends ListenerAdapter {
|
||||
// @Override
|
||||
// public void on
|
||||
//}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package codes.ztereohype.ztereomusic.listeners;
|
||||
|
||||
import codes.ztereohype.ztereomusic.Bot;
|
||||
import codes.ztereohype.ztereomusic.command.Command;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
public class CommandListener extends ListenerAdapter {
|
||||
// TODO: load prefix from a config
|
||||
private static final String PREFIX = Bot.getConfig().getPropreties().get("prefix");
|
||||
private static final Map<String, Command> COMMAND_MAP = Bot.getCommandMap();
|
||||
private static final Map<String, String> COMMAND_ALIASES = Bot.getCommandAliases();
|
||||
|
||||
@Override
|
||||
public void onMessageReceived(@Nonnull MessageReceivedEvent event) {
|
||||
Message message = event.getMessage();
|
||||
String content = message.getContentRaw();
|
||||
|
||||
// ignore messages from bots, dms, and that don't start with the prefix
|
||||
if (!content.startsWith(PREFIX)) return;
|
||||
if (event.getAuthor().isBot()) return;
|
||||
if (!event.isFromGuild()) return;
|
||||
|
||||
// parse the message
|
||||
String[] parsed = content.substring(PREFIX.length()).split(" +");
|
||||
String commandName = parsed[0].toLowerCase();
|
||||
String[] args = Arrays.copyOfRange(parsed, 1, parsed.length);
|
||||
|
||||
// check if the command exists
|
||||
Command command;
|
||||
if (COMMAND_MAP.containsKey(commandName)) {
|
||||
command = COMMAND_MAP.get(commandName);
|
||||
} else if (COMMAND_ALIASES.containsKey(commandName)) {
|
||||
command = COMMAND_MAP.get(COMMAND_ALIASES.get(commandName));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// try to execute the command
|
||||
try {
|
||||
command.execute(event, args);
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
message.getChannel().sendMessage("uh oh something really bad happened and yeah so yeah everything is aborted and cancelled i give up this is too hard kthxbye").queue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
//package codes.ztereohype.ztereomusic.listeners;
|
||||
//
|
||||
//public class onVcDisconnect {
|
||||
//}
|
||||
Loading…
Add table
Add a link
Reference in a new issue