aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/Main.java13
-rw-r--r--src/main/java/audio/Music.java348
-rw-r--r--src/main/java/audio/TrackScheduler.java2
-rw-r--r--src/main/java/commands/CommandManager.java92
-rw-r--r--src/main/java/commands/UIPusher.java64
-rw-r--r--src/main/java/utility/EmbedMaker.java21
-rw-r--r--src/main/java/utility/SpotifyAPI.java19
-rw-r--r--src/main/java/utility/YouTubeAPI.java28
8 files changed, 427 insertions, 160 deletions
diff --git a/src/main/java/Main.java b/src/main/java/Main.java
index fde7ac4..0446a86 100644
--- a/src/main/java/Main.java
+++ b/src/main/java/Main.java
@@ -36,16 +36,19 @@ public class Main extends ListenerAdapter {
public static void setSlashCommands(){
- //jda.updateCommands();
+ // jda.updateCommands().queue();
jda.upsertCommand(new CommandData("play","Adds a song to the queue with a URL or search terms").
addOption(OptionType.STRING,"term","The link or search terms of the music to queue")
).queue();
jda.upsertCommand(new CommandData("leave","Clears the queue and disconnects the bot from voice channel")).queue();
jda.upsertCommand(new CommandData("showqueue","Shows the current queue")).queue();
jda.upsertCommand(new CommandData("pause","Pauses the player")).queue();
+ jda.upsertCommand(new CommandData("controls","Show an interface to control the player")).queue();
jda.upsertCommand(new CommandData("skip","Skips the current song")).queue();
jda.upsertCommand(new CommandData("nowplaying","Shows a detailed view of the current song playing")).queue();
jda.upsertCommand(new CommandData("stop","Stops the player and clears the queue")).queue();
+ jda.upsertCommand(new CommandData("remove","Remove a track in queue")).queue();
+ jda.upsertCommand(new CommandData("shuffle","Shuffle the current queue")).queue();
jda.upsertCommand(new CommandData("vtmusic","Queues a set number of random VTuber songs and covers").
addOption(OptionType.INTEGER,"number","Number of songs to queue")
).queue();
@@ -53,6 +56,7 @@ public class Main extends ListenerAdapter {
addOption(OptionType.INTEGER,"volume","Volume from 0-100")
).queue();
+
}
public static String readSetting(String parameter){
Object obj = null;
@@ -70,7 +74,12 @@ public class Main extends ListenerAdapter {
JDA jda = e.getJDA();
Message message = e.getMessage();
String msg = message.getContentDisplay();
- }
+ if(msg.startsWith("!maintenance") && e.getAuthor().getId().equals("246787839570739211")){
+ jda.getPresence().setActivity(net.dv8tion.jda.api.entities.Activity.watching("Maintenance Mode!"));
+ }
+
+ }
+
@Override
public void onReady(ReadyEvent event) {
System.out.println("Loading Complete");
diff --git a/src/main/java/audio/Music.java b/src/main/java/audio/Music.java
index 4b301b7..d85a4bc 100644
--- a/src/main/java/audio/Music.java
+++ b/src/main/java/audio/Music.java
@@ -1,4 +1,5 @@
package audio;
+
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
@@ -7,46 +8,51 @@ import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
+import commands.UIPusher;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
-import net.dv8tion.jda.api.entities.*;
+import net.dv8tion.jda.api.entities.Guild;
+import net.dv8tion.jda.api.entities.TextChannel;
+import net.dv8tion.jda.api.entities.VoiceChannel;
+import net.dv8tion.jda.api.events.interaction.ButtonClickEvent;
+import net.dv8tion.jda.api.events.interaction.SelectionMenuEvent;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.managers.AudioManager;
import org.jetbrains.annotations.NotNull;
-import org.json.JSONArray;
-import org.json.JSONObject;
-import org.jsoup.Jsoup;
+import se.michaelthelin.spotify.model_objects.specification.PlaylistTrack;
+import utility.EmbedMaker;
import utility.SpotifyAPI;
import utility.URLChecker;
-
+import utility.YouTubeAPI;
import java.awt.*;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Queue;
import java.util.*;
import java.util.concurrent.BlockingQueue;
-
+import java.util.concurrent.LinkedBlockingQueue;
public class Music extends ListenerAdapter {
- ArrayList<String> hololiveMusicURL = new ArrayList<String>();
- String ytapiKey = "";
- String spotifyapiKey = "";
- static String append = "!";
- private URLChecker urlCheck = new URLChecker();
+ ArrayList<String> currentlyLoadedPlaylist = new ArrayList<>();
+ String ytapiKey;
+ private final YouTubeAPI youtubeAPI = new YouTubeAPI(ytapiKey);
+ static String append = "$";
+ private final URLChecker urlCheck = new URLChecker();
+ UIPusher uiPusher = new UIPusher();
private final AudioPlayerManager playerManager;
private final Map<Long, GuildMusicManager> musicManagers;
- private SpotifyAPI spotifyAPI = new SpotifyAPI();
+ private final SpotifyAPI spotifyAPI = new SpotifyAPI();
+ private final EmbedMaker embedMaker = new EmbedMaker();
public Music(String append, String ytapiKey) {
this.musicManagers = new HashMap<>();
this.ytapiKey = ytapiKey;
- this.spotifyapiKey = spotifyapiKey;
- this.append = append;
+ Music.append = append;
this.playerManager = new DefaultAudioPlayerManager();
AudioSourceManagers.registerRemoteSources(playerManager);
AudioSourceManagers.registerLocalSource(playerManager);
- System.out.println("Filling Music List");
}
private synchronized GuildMusicManager getGuildAudioPlayer(Guild guild) {
long guildId = Long.parseLong(guild.getId());
@@ -60,12 +66,21 @@ public class Music extends ListenerAdapter {
return musicManager;
}
- private void populateVTuberMusic(){
+
+ private void populateFileFromURL(String link,String fileName){
try {
- URL url = new URL("https://pinapelz.github.io/vTuberDiscordBot/hololiveMusic.txt");
+ URL url = new URL(link);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
- FileWriter writer = new FileWriter("data//hololiveMusic.txt");
+ File f = new File(fileName);
+ if(!f.exists()){ //if file doesn't exist, create it
+ f.createNewFile();
+ }else{//if file exists, delete it
+ f.delete();
+ f.createNewFile();
+ }
+
+ FileWriter writer = new FileWriter("data//"+fileName);
while ((line = in.readLine()) != null) {
writer.write(line+"\n");
}
@@ -79,51 +94,39 @@ public class Music extends ListenerAdapter {
System.out.println("I/O Error: " + e.getMessage());
}
}
- private void fillVTuberMusic(){
- populateVTuberMusic();
+ private void fillLoadedPlaylist(String url,String fileName){
+ populateFileFromURL(url,fileName);
Scanner s = null;
try {
- s = new Scanner(new File("data//hololiveMusic.txt"));
+ s = new Scanner(new File("data//"+fileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
- while (s.hasNext()){
- hololiveMusicURL.add(s.nextLine());
+ while (true){
+ assert s != null;
+ if (!s.hasNext()) break;
+ currentlyLoadedPlaylist.add(s.nextLine());
}
s.close();
}
+ public void queueTrackFromLoadedList(SlashCommandEvent event, int songsToQueue,String fileName,String url){
+ fillLoadedPlaylist(url,fileName);
+ Collections.shuffle(currentlyLoadedPlaylist);
+ for (int i = 0;i<songsToQueue;i++){
+ loadAndPlay((TextChannel) event.getChannel(), currentlyLoadedPlaylist.get(i),false);
+ }
+ }
+
@Override
public void onGuildMessageReceived(GuildMessageReceivedEvent event) {
- Guild guild = event.getGuild();
- GuildMusicManager mng = getGuildAudioPlayer(guild);
- TrackScheduler scheduler = mng.scheduler;
String[] command = event.getMessage().getContentRaw().split(" ", 2);
- if ((append+"play").equals(command[0]) && command.length == 2) {
- loadAndPlay(event.getChannel(), command[1],true);
- }
- else if((append+"refreshlist").equals(command[0])){
- event.getChannel().sendMessage("Refreshing songs database").queue();
- fillVTuberMusic();
- event.getChannel().sendMessage("Refresh Complete!").queue();
- }
- else if ((append+"shuffle").equals(command[0]))
- {
- if (scheduler.queue.isEmpty())
- {
- event.getChannel().sendMessage("The queue is currently empty!").queue();
- return;
- }
-
- scheduler.shuffle();
- event.getChannel().sendMessage("The queue has been shuffled!").queue();
- }
- else if("!holoadd".equals(command[0])){
+ if((append+"holoadd").equals(command[0])){
event.getChannel().sendMessage("The url has been successfully added to the database").queue();
}
else if("!dev".equals(command[0])){
try {
- spotifyAPI.clientCredentials_Sync();
+ System.out.println("Attempting to play");
}
catch (Exception e){
@@ -132,29 +135,59 @@ public class Music extends ListenerAdapter {
super.onGuildMessageReceived(event);
}
+ public void showQueueMenu(SlashCommandEvent event, String param, String instruction){
+ uiPusher.showQueueMenu(event,param,instruction,getGuildAudioPlayer(event.getGuild()));
+ }
+ public void showControls(SlashCommandEvent event){
+ uiPusher.showControls(event);
+ }
+ public void shuffleQueue(SlashCommandEvent event){
+ Guild guild = event.getGuild();
+ GuildMusicManager mng = getGuildAudioPlayer(guild);
+ Queue<AudioTrack> queue = getGuildAudioPlayer(event.getGuild()).scheduler.queue;
+ if (queue.isEmpty())
+ {
+ event.reply("The queue is currently empty!").queue();
+ return;
+ }
+ else{
+
+ ArrayList<Object> currentQueue = new ArrayList(queue); //Conversion of queue to arraylist to allow for shuffling
+ Collections.shuffle(currentQueue);
+ BlockingQueue<AudioTrack> newQueue = new LinkedBlockingQueue<>();
+ for (Object track : currentQueue) {
+ newQueue.add((AudioTrack) track);
+ }
+ mng.scheduler.queue = newQueue;
+ }
+ event.reply("The queue has been shuffled!").queue();
+ }
+
public void playMusic(SlashCommandEvent event){
try {
String userQuery = event.getOption("term").getAsString();
if (urlCheck.isURL(userQuery) && !urlCheck.getURLType(userQuery).equals("spotify")&&!urlCheck.getURLType(userQuery).equals("spotify-playlist")) { //The term is a URL
event.reply("Found Video: " + userQuery).queue();
loadAndPlay((TextChannel) event.getChannel(), userQuery, false);
- } else {
+ }
+ else { //Run checks if its not a directly playable URL
try {
if (urlCheck.getURLType(userQuery).equals("spotify")){
event.deferReply().queue();
- event.getHook().sendMessage("Matched Video From Spotify: " + returnTopVideoURL(spotifyAPI.getSearchTerm_sync(urlCheck.getSpotifyTrackID(userQuery)))).queue();
- loadAndPlay((TextChannel) event.getChannel(), returnTopVideoURL(spotifyAPI.getSearchTerm_sync(urlCheck.getSpotifyTrackID(userQuery))), true);
+ event.getHook().sendMessage("Matched Video From Spotify: " + youtubeAPI.returnTopVideoURL(spotifyAPI.getSearchTerm_sync(urlCheck.getSpotifyTrackID(userQuery)))).queue();
+ loadAndPlay((TextChannel) event.getChannel(), youtubeAPI.returnTopVideoURL(spotifyAPI.getSearchTerm_sync(urlCheck.getSpotifyTrackID(userQuery))), true);
}
else if(urlCheck.getURLType(userQuery).equals("spotify-playlist")){
event.deferReply().queue();
- String randomSong = spotifyAPI.getPlaylist_Sync(urlCheck.getSpotifyPlaylistID(userQuery));
- event.getHook().sendMessage("Matched Video From Spotify Playlist: " + returnTopVideoURL(spotifyAPI.getSearchTerm_sync(randomSong))).queue();
- loadAndPlay((TextChannel) event.getChannel(), returnTopVideoURL(spotifyAPI.getSearchTerm_sync(randomSong)), true);
+ //TODO: Add playlist support using selection menu
+ String randomSong = spotifyAPI.getRandomPlaylistTrack_Sync(urlCheck.getSpotifyPlaylistID(userQuery));
+ event.getHook().sendMessage("Matched Video From Spotify Playlist: " + youtubeAPI.returnTopVideoURL(spotifyAPI.getSearchTerm_sync(randomSong))).queue();
+ loadAndPlay((TextChannel) event.getChannel(), youtubeAPI.returnTopVideoURL(spotifyAPI.getSearchTerm_sync(randomSong)), true);
}
else {
- event.reply("Found Video: " + returnTopVideoURL(userQuery)).queue();
- loadAndPlay((TextChannel) event.getChannel(), returnTopVideoURL(userQuery), true);
+ event.reply("Found Video: " + youtubeAPI.returnTopVideoURL(userQuery)).queue();
+ loadAndPlay((TextChannel) event.getChannel(), youtubeAPI.returnTopVideoURL(userQuery), true);
}
} catch (IOException e) {
e.printStackTrace();
@@ -163,12 +196,31 @@ public class Music extends ListenerAdapter {
}
catch(Exception e){
- event.reply("Error! Hazukashii! " + e.toString());
+ event.reply("Error! Hazukashii! " + e);
+ }
+ }
+
+ //TODO: Finish the feature of showing spotify menu
+ public void showSpotifyMenu(String playlistID, SlashCommandEvent event){
+ PlaylistTrack[] tracks = spotifyAPI.getPlaylist_Sync(playlistID);
+ ArrayList<PlaylistTrack[]> trackPages = new ArrayList<PlaylistTrack[]>();
+ int chunk = 25; // chunk size to divide
+ for(int i=0;i<tracks.length;i+=chunk){
+ System.out.println(Arrays.toString(Arrays.copyOfRange(tracks, i, Math.min(tracks.length,i+chunk))));
+ trackPages.add(Arrays.copyOfRange(tracks, i, Math.min(tracks.length,i+chunk)));
+ }
+ for(int i = 0;i < trackPages.size();i++){
+ for(int j = 0; j < trackPages.get(i).length; j++){
+ // SelectOption option = SelectOption.of(trackPages.get(i)[j].getTrack().getName(),param+" "+track.getInfo().title);
+ //trackMenuOptions.add(option);
+
+ }
}
}
- public void setVolume( SlashCommandEvent event, String command){
+ public void setVolume(SlashCommandEvent event, String command){
Guild guild = event.getGuild();
+ assert guild != null;
GuildMusicManager mng = getGuildAudioPlayer(guild);
AudioPlayer player = mng.player;
if (command.equals("CHECK"))
@@ -190,6 +242,7 @@ public class Music extends ListenerAdapter {
}
}
}
+
public void stopPlayer(SlashCommandEvent event){
Guild guild = event.getGuild();
GuildMusicManager mng = getGuildAudioPlayer(guild);
@@ -200,7 +253,8 @@ public class Music extends ListenerAdapter {
player.setPaused(false);
event.reply("Playback has been completely stopped and the queue has been cleared.").queue();
}
- public void pausePlayer(final TextChannel channel, SlashCommandEvent event){
+
+ public void pausePlayer(SlashCommandEvent event){
Guild guild = event.getGuild();
GuildMusicManager mng = getGuildAudioPlayer(guild);
AudioPlayer player = mng.player;
@@ -215,15 +269,7 @@ public class Music extends ListenerAdapter {
else
event.reply("The player has resumed playing.").queue();
}
- public void queueVTMusic(final TextChannel channel, int songsToQueue){
- fillVTuberMusic();
- Collections.shuffle(hololiveMusicURL);
- System.out.println("Requesting to queue " + songsToQueue + " songs");
- System.out.println("Queueing all Hololive Music");
- for (int i = 0;i<songsToQueue;i++){
- loadAndPlay(channel, hololiveMusicURL.get(i),false);
- }
- }
+
public void showNowPlaying(SlashCommandEvent event){
Guild guild = event.getGuild();
GuildMusicManager mng = getGuildAudioPlayer(guild);
@@ -233,40 +279,30 @@ public class Music extends ListenerAdapter {
{
String currentTrackUrl = currentTrack.getInfo().uri;
String currentTrackUrlType = urlCheck.getURLType(currentTrackUrl);
- String title = currentTrack.getInfo().title;
System.out.println(currentTrack.getInfo().uri);
String position = getTimestamp(currentTrack.getPosition());
String duration = getTimestamp(currentTrack.getDuration());
if(currentTrackUrlType=="yt") { //YOUTUBE EMBED
- EmbedBuilder embed = new EmbedBuilder()
- .setColor(new Color(0xFD0001))
- .setTitle("Now Playing: " + title)
- .setDescription(currentTrack.getInfo().author)
- .setImage("https://img.youtube.com/vi/" + currentTrack.getIdentifier() + "/hqdefault.jpg");
- embed.addField("Timestamp: ", "**[" + position + "/" + duration + "]**", false);
- embed.addField("", "https://www.youtube.com/watch?v=" + currentTrack.getIdentifier(), false);
+ EmbedBuilder embed = embedMaker.makeNowPlayingEmbed(currentTrack,position,duration,
+ "https://img.youtube.com/vi/" + currentTrack.getIdentifier() + "/hqdefault.jpg",
+ "https://www.youtube.com/watch?v=" + currentTrack.getIdentifier(),new Color(0xFD0001));
MessageBuilder messageBuilder = (MessageBuilder) new MessageBuilder().setEmbeds(embed.build());
event.reply(messageBuilder.build()).queue();
}
else if(currentTrackUrlType=="snd") { //SOUNDCLOUD EMBED
- EmbedBuilder embed = new EmbedBuilder()
- .setColor(new Color(0xFD5401))
- .setTitle("Now Playing: " + title)
- .setDescription(currentTrack.getInfo().author);
- embed.addField("Timestamp: ", "**[" + position + "/" + duration + "]**", false);
- embed.addField("", currentTrack.getInfo().uri, false);
+ EmbedBuilder embed = embedMaker.makeNowPlayingEmbed(currentTrack,position,duration,
+ "https://1000logos.net/wp-content/uploads/2021/04/Soundcloud-logo.png",
+ currentTrack.getInfo().uri,new Color(0xFD5401));
MessageBuilder messageBuilder = (MessageBuilder) new MessageBuilder().setEmbeds(embed.build());
+
event.reply(messageBuilder.build()).queue();
}
else if(currentTrackUrlType=="twitch"){ //TWITCH EMBED
- System.out.println("https://static-cdn.jtvnw.net/previews-ttv/live_user_" + currentTrack.getIdentifier() + "-440x248.jpg");
- EmbedBuilder embed = new EmbedBuilder()
- .setColor(new Color(0xA86FFE))
- .setTitle("Now Playing: " + title)
- .setDescription(currentTrack.getInfo().author)//https://static-cdn.jtvnw.net/previews-ttv/live_user_cdawgva-440x248.jpg
- .setImage("https://static-cdn.jtvnw.net/previews-ttv/live_user_" + currentTrack.getIdentifier().replaceAll("https://www.twitch.tv/","") + "-440x248.jpg");
- embed.addField("Timestamp: ", "Currently Live!", false);
- embed.addField("", currentTrack.getIdentifier(), false);
+ EmbedBuilder embed = embedMaker.makeNowPlayingEmbed(currentTrack,"Currently","Live",
+ "https://static-cdn.jtvnw.net/previews-ttv/live_user_" +
+ currentTrack.getIdentifier().replaceAll("https://www.twitch.tv/","") + "-440x248.jpg",
+ currentTrack.getIdentifier(),
+ new Color(0xA86FFE));
MessageBuilder messageBuilder = (MessageBuilder) new MessageBuilder().setEmbeds(embed.build());
event.reply(messageBuilder.build()).queue();
}
@@ -275,13 +311,14 @@ public class Music extends ListenerAdapter {
event.reply("The player is not currently playing anything!").queue();
}
}
- public void showQueue(final TextChannel channel, @NotNull SlashCommandEvent event){
+
+ public void showQueue(SlashCommandEvent event){
Queue<AudioTrack> queue = getGuildAudioPlayer(event.getGuild()).scheduler.queue;
synchronized (queue)
{
if (queue.isEmpty())
{
- channel.sendMessage("The queue is currently empty!").queue();
+ event.reply("The queue is currently empty!").queue();
}
else
{
@@ -301,9 +338,118 @@ public class Music extends ListenerAdapter {
}
sb.append("\n").append("Total Queue Time Length: ").append(getTimestamp(queueLength)+"```");
event.reply(sb.toString()).queue();
+
+ }
+ }
+ }
+
+
+ @Override
+ public void onSelectionMenu(SelectionMenuEvent event){
+ if(event.getValues().get(0).contains("remove-queue")) {
+ boolean deletedSong = false;
+ Queue<AudioTrack> queue = getGuildAudioPlayer(event.getGuild()).scheduler.queue;
+ BlockingQueue<AudioTrack> newQueue = new LinkedBlockingQueue<>();
+ String trackName = event.getValues().get(0).replaceAll("remove-queue ", "");
+ synchronized (queue) {
+ if (queue.isEmpty())
+ {
+ event.reply("The queue is currently empty!").queue();
+ }
+ else {
+ for (AudioTrack track : queue) {
+ if (!track.getInfo().title.equals(trackName)) {
+ newQueue.add(track);
+ }
+ else{
+ deletedSong = true;
+ }
+ }
+ getGuildAudioPlayer(event.getGuild()).scheduler.queue = newQueue;
+ if(deletedSong){
+ event.reply("Removed " + trackName + " from the queue!").queue();
+ }
+ else{
+ event.reply("Could not find " + trackName + " in the queue!").queue();
+ }
+
+ }
+
+ }
+ }
+
+ else if(event.getValues().get(0).contains("inspect-queue")) { //THIS FEAUTURE IS NOT FINISHED
+ //TODO: FINISH THE INSPECT QUEUE FEATURE
+ Queue<AudioTrack> queue = getGuildAudioPlayer(event.getGuild()).scheduler.queue;
+ BlockingQueue<AudioTrack> newQueue = new LinkedBlockingQueue<>();
+ String trackName = event.getValues().get(0).replaceAll("inspect-queue ", "");
+ synchronized (queue) {
+ if (queue.isEmpty())
+ {
+ event.reply("The queue is currently empty!").queue();
+
+ }
+ else {
+ for (AudioTrack track : queue) {
+ if (!track.getInfo().title.equals(trackName)) {
+ newQueue.add(track);
+ }
+ else{
+
+ }
+ }
+ getGuildAudioPlayer(event.getGuild()).scheduler.queue = newQueue;
+ }
+
}
}
}
+ @Override
+ public void onButtonClick(ButtonClickEvent event){
+ Guild guild = event.getGuild();
+ GuildMusicManager mng = getGuildAudioPlayer(guild);
+ AudioPlayer player = mng.player;
+ if(event.getComponentId().equals("action-volumedown")){
+ int newVolume = Math.max(10, Math.min(100, player.getVolume()-5));
+ int oldVolume = player.getVolume();
+ player.setVolume(newVolume);
+ event.reply("Player volume changed from `" + oldVolume + "` to `" + newVolume + "`").queue();
+
+ }
+ else if(event.getComponentId().equals("action-volumeup")){
+ int newVolume = Math.max(10, Math.min(100, player.getVolume()+5));
+ int oldVolume = player.getVolume();
+ player.setVolume(newVolume);
+ event.reply("Player volume changed from `" + oldVolume + "` to `" + newVolume + "`").queue();
+
+ }
+ else if(event.getComponentId().equals("action-pause")){
+ if (player.getPlayingTrack() == null)
+ {
+ event.reply("Cannot pause or resume player because no track is loaded for playing.").queue();
+ return;
+ }
+ player.setPaused(!player.isPaused());
+ if (player.isPaused())
+ event.reply("The player has been paused.").queue();
+ else
+ event.reply("The player has resumed playing.").queue();
+ }
+ else if(event.getComponentId().equals("action-stop")){
+ TrackScheduler scheduler = mng.scheduler;
+ scheduler.queue.clear();
+ player.stopTrack();
+ player.setPaused(false);
+ event.reply("Playback has been completely stopped and the queue has been cleared.").queue();
+ }
+ else if(event.getComponentId().equals("action-skip")){
+ GuildMusicManager musicManager = getGuildAudioPlayer(event.getGuild());
+ musicManager.scheduler.nextTrack();
+ event.reply("Skipped to next track.").queue();
+ }
+
+
+ }
public void loadAndPlay(final @NotNull TextChannel channel, final String trackUrl, boolean returnMessage) {
GuildMusicManager musicManager = getGuildAudioPlayer(channel.getGuild());
playerManager.loadItemOrdered(musicManager, trackUrl, new AudioLoadResultHandler() {
@@ -357,8 +503,8 @@ public class Music extends ListenerAdapter {
}
- public void skipTrack(TextChannel channel,SlashCommandEvent event) {
- GuildMusicManager musicManager = getGuildAudioPlayer(channel.getGuild());
+ public void skipTrack(SlashCommandEvent event) {
+ GuildMusicManager musicManager = getGuildAudioPlayer(event.getGuild());
musicManager.scheduler.nextTrack();
event.reply("Skipped to next track.").queue();
@@ -384,22 +530,6 @@ public class Music extends ListenerAdapter {
return String.format("%02d:%02d", minutes, seconds);
}
- public String returnTopVideoURL(String keyword) throws IOException {
- String url = "https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q="+keyword+"&type=video&key="+ytapiKey;
- url = url.replaceAll(" ", "%20");
- String data = Jsoup.connect(url).ignoreContentType(true).execute().body();
- JSONObject obj = new JSONObject(data);
- JSONArray arr = obj.getJSONArray("items");
- String videoID = "";
- for (int i = 0; i < arr.length(); i++)
- {
- videoID = arr.getJSONObject(i).getJSONObject("id").getString("videoId");
- System.out.println("Parsed ID "+ videoID);
- }
- return "https://www.youtube.com/watch?v="+videoID;
- }
-
-
diff --git a/src/main/java/audio/TrackScheduler.java b/src/main/java/audio/TrackScheduler.java
index b5886c4..8377e7a 100644
--- a/src/main/java/audio/TrackScheduler.java
+++ b/src/main/java/audio/TrackScheduler.java
@@ -15,7 +15,7 @@ import java.util.concurrent.LinkedBlockingQueue;
*/
public class TrackScheduler extends AudioEventAdapter {
public final AudioPlayer player;
- public final BlockingQueue<AudioTrack> queue;
+ public BlockingQueue<AudioTrack> queue;
/**
* @param player The audio player this scheduler uses
diff --git a/src/main/java/commands/CommandManager.java b/src/main/java/commands/CommandManager.java
index 65500ef..05e501a 100644
--- a/src/main/java/commands/CommandManager.java
+++ b/src/main/java/commands/CommandManager.java
@@ -1,65 +1,73 @@
package commands;
import audio.Music;
-import net.dv8tion.jda.api.entities.TextChannel;
-import net.dv8tion.jda.api.events.guild.GuildReadyEvent;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
-import net.dv8tion.jda.api.interactions.commands.build.CommandData;
-import utility.URLChecker;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Objects;
public class CommandManager extends ListenerAdapter {
Music music;
+ String vTuberSongDatabase = "https://pinapelz.github.io/vTuberDiscordBot/hololiveMusic.txt";
public CommandManager(Music music){
this.music = music;
}
@Override
public void onSlashCommand(SlashCommandEvent event) {
String command = event.getName(); //test
- if (command.equals("play")) {
- music.playMusic(event);
- }
- else if(command.equals("leave")){
- event.getGuild().getAudioManager().setSendingHandler(null);
- event.getGuild().getAudioManager().closeAudioConnection();
- event.reply("OtsuRose! See you later!").queue();
- }
- else if(command.equals("vtmusic")){
- event.deferReply().queue();
- music.queueVTMusic((TextChannel) event.getChannel(),Integer.parseInt(event.getOption("number").getAsString()));
- event.getHook().sendMessage("Queued up " + Integer.parseInt(event.getOption("number").getAsString())+" songs!").queue();
- }
- else if(command.equals("showqueue")){
- music.showQueue((TextChannel) event.getChannel(), event);
- }
- else if(command.equals("skip")){
- music.skipTrack((TextChannel) event.getChannel(),event);
+ switch (command) {
+ case "play":
+ music.playMusic(event);
+ break;
+ case "leave":
+ Objects.requireNonNull(event.getGuild()).getAudioManager().setSendingHandler(null);
+ event.getGuild().getAudioManager().closeAudioConnection();
+ event.reply("OtsuRose! See you later!").queue();
+ break;
+ case "vtmusic":
+ event.deferReply().queue();
+ music.queueTrackFromLoadedList(event, Integer.parseInt(Objects.requireNonNull(event.getOption("number")).getAsString()), "VTubermusic.txt",vTuberSongDatabase);
+ event.getHook().sendMessage("Queued up " + Integer.parseInt(Objects.requireNonNull(event.getOption("number")).getAsString()) + " songs!").queue();
+ break;
+ case "showqueue":
+ music.showQueue(event);
+ break;
+ case "skip":
+ music.skipTrack(event);
- }
- else if(command.equals("pause")){
- music.pausePlayer((TextChannel) event.getChannel(),event);
+ break;
+ case "pause":
+ music.pausePlayer(event);
- }
- else if(command.equals("nowplaying")){
- music.showNowPlaying(event);
+ break;
+ case "controls":
+ music.showControls(event);
- }
- else if(command.equals("stop")){
- music.stopPlayer(event);
+ break;
+ case "shuffle":
+ music.shuffleQueue(event);
- }
- else if(command.equals("volume")){
- music.setVolume(event,event.getOption("volume").getAsString());
+ break;
+ case "nowplaying":
+ music.showNowPlaying(event);
+
+ break;
+ case "stop":
+ music.stopPlayer(event);
+
+ break;
+ case "volume":
+ music.setVolume(event, Objects.requireNonNull(event.getOption("volume")).getAsString());
+ break;
+ case "remove":
+ music.showQueueMenu(event, "remove-queue", "Select a track to remove below");
+
+ break;
+ case "inspect":
+ music.showQueueMenu(event, "inspect-queue", "Select a track to inspect below");
+ break;
}
super.onSlashCommand(event);
}
- @Override
- public void onGuildReady(GuildReadyEvent event){
- List<CommandData> commandData = new ArrayList<>();
- }
+
}
diff --git a/src/main/java/commands/UIPusher.java b/src/main/java/commands/UIPusher.java
new file mode 100644
index 0000000..6ebe61a
--- /dev/null
+++ b/src/main/java/commands/UIPusher.java
@@ -0,0 +1,64 @@
+package commands;
+
+import audio.GuildMusicManager;
+import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
+import net.dv8tion.jda.api.entities.Emoji;
+import net.dv8tion.jda.api.entities.TextChannel;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import net.dv8tion.jda.api.interactions.components.Button;
+import net.dv8tion.jda.api.interactions.components.selections.SelectOption;
+import net.dv8tion.jda.api.interactions.components.selections.SelectionMenu;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Queue;
+
+public class UIPusher {
+
+ public void showControls(SlashCommandEvent event){
+ event.reply("Controls for the player:")
+ .addActionRow(
+ Button.primary("action-volumedown", Emoji.fromUnicode("U+1F509")),
+ Button.primary("action-skip", Emoji.fromUnicode("U+23E9")),
+ Button.primary("action-pause", Emoji.fromUnicode("U+23EF")),
+ Button.primary("action-stop", Emoji.fromUnicode("U+23F9")),
+ Button.primary("action-volumeup", Emoji.fromUnicode("U+1F50A"))
+ )
+ .queue();
+ }
+ public void showQueueMenu(SlashCommandEvent event, String param, String instruction,GuildMusicManager musicManager){
+ Queue<AudioTrack> queue = musicManager.scheduler.queue;
+ List<SelectOption> trackMenuOptions = new ArrayList<SelectOption>();
+ synchronized (queue)
+ {
+ if (queue.isEmpty())
+ {
+ event.reply("The queue is currently empty!").queue();
+ }
+ else
+ {
+ int trackCount = 0;
+ for (AudioTrack track : queue)
+ {
+ if (trackCount != 25)
+ {
+ SelectOption option = SelectOption.of(track.getInfo().title,param+" "+track.getInfo().title);
+ trackMenuOptions.add(option);
+ trackCount++;
+ }
+ }
+ SelectionMenu menu = SelectionMenu.create("menu:class")
+ .setPlaceholder("-Select a track-") // shows the placeholder indicating what this menu is for
+ .setRequiredRange(1,1)// only one can be selected
+ .addOptions(trackMenuOptions)
+ .build();
+ event.reply(instruction)
+ .setEphemeral(true)
+ .addActionRow(menu)
+ .queue();
+
+ }
+ }
+ }
+}
diff --git a/src/main/java/utility/EmbedMaker.java b/src/main/java/utility/EmbedMaker.java
new file mode 100644
index 0000000..23df4ab
--- /dev/null
+++ b/src/main/java/utility/EmbedMaker.java
@@ -0,0 +1,21 @@
+package utility;
+
+import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
+import net.dv8tion.jda.api.EmbedBuilder;
+
+import java.awt.*;
+
+public class EmbedMaker {
+ public EmbedBuilder makeNowPlayingEmbed(AudioTrack currentTrack, String position, String duration,
+ String thumbnailUrl, String url,Color color) {
+ EmbedBuilder embed = new EmbedBuilder()
+ .setColor(color)
+ .setTitle("Now Playing: " + currentTrack.getInfo().title)
+ .setDescription(currentTrack.getInfo().author)
+ .setImage(thumbnailUrl);
+ embed.addField("Timestamp: ", "**[" + position + "/" + duration + "]**", false);
+ embed.addField("", url, false);
+ return embed;
+ }
+
+}
diff --git a/src/main/java/utility/SpotifyAPI.java b/src/main/java/utility/SpotifyAPI.java
index 74b792e..b4bcac1 100644
--- a/src/main/java/utility/SpotifyAPI.java
+++ b/src/main/java/utility/SpotifyAPI.java
@@ -13,9 +13,6 @@ import se.michaelthelin.spotify.requests.data.playlists.GetPlaylistRequest;
import se.michaelthelin.spotify.requests.data.tracks.GetTrackRequest;
import java.io.FileReader;
import java.time.Instant;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionException;
public class SpotifyAPI {
private static final String clientId = readSetting("spotifyClientID");
private static final String clientSecret = readSetting("spotifyClientSecret");
@@ -38,7 +35,6 @@ public class SpotifyAPI {
String searchQuery = "";
try {
GetTrackRequest getTrackRequest = spotifyApi.getTrack(trackid)
-// .market(CountryCode.SE)
.build();
final Track track = getTrackRequest.execute();
searchQuery = track.getName();
@@ -53,13 +49,12 @@ public class SpotifyAPI {
return searchQuery;
}
- public static String getPlaylist_Sync(String playlistId) {
+ public static String getRandomPlaylistTrack_Sync(String playlistId) {
checkRefreshToken();
GetPlaylistRequest getPlaylistRequest = spotifyApi.getPlaylist(playlistId).build();
try {
Playlist playlist = getPlaylistRequest.execute();
PlaylistTrack[] tracks = playlist.getTracks().getItems();
- //pick a random track and return it
int randomTrack = (int) (Math.random() * tracks.length);
System.out.println(tracks[randomTrack].getTrack().getId());
return tracks[randomTrack].getTrack().getId();
@@ -68,6 +63,18 @@ public class SpotifyAPI {
}
return "";
}
+ public static PlaylistTrack[] getPlaylist_Sync(String playlistId) {
+ checkRefreshToken();
+ GetPlaylistRequest getPlaylistRequest = spotifyApi.getPlaylist(playlistId).build();
+ try {
+ Playlist playlist = getPlaylistRequest.execute();
+ PlaylistTrack[] tracks = playlist.getTracks().getItems();
+ return tracks;
+ } catch (Exception e) {
+ System.out.println("Error: " + e.getMessage());
+ }
+ return null;
+ }
public static void clientCredentials_Sync() {
try {
final ClientCredentials clientCredentials = clientCredentialsRequest.execute();
diff --git a/src/main/java/utility/YouTubeAPI.java b/src/main/java/utility/YouTubeAPI.java
new file mode 100644
index 0000000..ea3896b
--- /dev/null
+++ b/src/main/java/utility/YouTubeAPI.java
@@ -0,0 +1,28 @@
+package utility;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.jsoup.Jsoup;
+
+import java.io.IOException;
+
+public class YouTubeAPI {
+ private String ytapiKey = "";
+ public YouTubeAPI(String ytapiKey){
+ this.ytapiKey = ytapiKey;
+ }
+ public String returnTopVideoURL(String keyword )throws IOException {
+ String url = "https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q="+keyword+"&type=video&key="+ytapiKey;
+ url = url.replaceAll(" ", "%20");
+ String data = Jsoup.connect(url).ignoreContentType(true).execute().body();
+ JSONObject obj = new JSONObject(data);
+ JSONArray arr = obj.getJSONArray("items");
+ String videoID = "";
+ for (int i = 0; i < arr.length(); i++)
+ {
+ videoID = arr.getJSONObject(i).getJSONObject("id").getString("videoId");
+ System.out.println("Parsed ID "+ videoID);
+ }
+ return "https://www.youtube.com/watch?v="+videoID;
+ }
+}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage