Release 1.1 #2
16
README.md
16
README.md
|
@ -43,17 +43,19 @@ Because the play command is defined as `play [URL]`, and the queue command is de
|
|||
* `shuffle [true|false]` - Sets the bot to shuffle the playlist, as in pull a random song from the playlist, with some filters to prevent repeating songs.
|
||||
|
||||
* `playlist <create|show|play|delete|add|remove|rename>` - Various commands to manipulate playlists. The specific sub-commands are explained below.
|
||||
* `create <NAME> [URL]...` - Creates a new playlist, optionally with some starting URLs.
|
||||
* `create <PLAYLIST> [URL]...` - Creates a new playlist, optionally with some starting URLs.
|
||||
|
||||
* `delete <NAME>` - Deletes a playlist with the given name.
|
||||
* `delete <PLAYLIST>` - Deletes a playlist with the given name.
|
||||
|
||||
* `show [NAME]` - If a name is given, shows the songs in a given playlist; otherwise it lists the names of the playlists.
|
||||
* `show [PLAYLIST]` - If a name is given, shows the songs in a given playlist; otherwise it lists the names of the playlists.
|
||||
|
||||
* `play <NAME>` - Loads and begins playing the specified playlist.
|
||||
* `play <PLAYLIST>` - Loads and begins playing the specified playlist.
|
||||
|
||||
* `add <NAME> <URL> [URL]...` - Adds the specified URL, or multiple URLs to the playlist given by `NAME`.
|
||||
* `add <PLAYLIST> <URL> [URL]...` - Adds the specified URL, or multiple URLs to the playlist given by `PLAYLIST`.
|
||||
|
||||
* `remove <NAME> <SONGNAME>` - Removes the specified song name, or the one that most closely matches the song name given, from the playlist given by `NAME`.
|
||||
* `remove <PLAYLIST> <SONGNUMBER>` - Removes the specified song name, or the one that most closely matches the song name given, from the playlist given by `PLAYLIST`.
|
||||
|
||||
* `rename <NAME> <NEWNAME>` - Renames the playlist to the new name.
|
||||
* `rename <PLAYLIST> <NEWNAME>` - Renames the playlist to the new name.
|
||||
|
||||
* `move <PLAYLIST> <SONGNUMBER> <NEWNUMBER>` - Moves a song from one index to another index, shifting other elements as necessary.
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package handiebot.command;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import handiebot.command.commands.music.PlayCommand;
|
||||
import handiebot.command.commands.music.PlaylistCommand;
|
||||
import handiebot.command.commands.music.RepeatCommand;
|
||||
import handiebot.command.commands.music.ShuffleCommand;
|
||||
import handiebot.utils.DisappearingMessage;
|
||||
import handiebot.view.BotLog;
|
||||
import handiebot.view.actions.QuitAction;
|
||||
import handiebot.view.actions.music.PlayAction;
|
||||
import handiebot.view.actions.music.QueueListAction;
|
||||
import handiebot.view.actions.music.SkipAction;
|
||||
import handiebot.view.actions.music.ToggleRepeatAction;
|
||||
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
|
||||
import sx.blah.discord.handle.obj.*;
|
||||
import sx.blah.discord.util.EmbedBuilder;
|
||||
|
@ -40,7 +41,7 @@ public class CommandHandler {
|
|||
DisappearingMessage.deleteMessageAfter(1000, message);
|
||||
if (command.equals("play")){
|
||||
//Play or queue a song.
|
||||
new PlayAction(guild, args).actionPerformed(null);
|
||||
new PlayCommand().execute(context);
|
||||
} else if (command.equals("skip") && args.length == 0){
|
||||
//Skip the current song.
|
||||
new SkipAction(guild).actionPerformed(null);
|
||||
|
@ -52,7 +53,9 @@ public class CommandHandler {
|
|||
new QueueListAction(guild, (args.length == 1) && args[0].equals("all")).actionPerformed(null);
|
||||
} else if (command.equals("repeat")) {
|
||||
//Toggle repeat.
|
||||
new ToggleRepeatAction(guild).actionPerformed(null);
|
||||
new RepeatCommand().execute(context);
|
||||
} else if (command.equals("shuffle")){
|
||||
new ShuffleCommand().execute(context);
|
||||
} else if (command.equals("clear")){
|
||||
//TODO clear command.
|
||||
} else if (command.equals("quit")){
|
||||
|
|
|
@ -3,6 +3,8 @@ package handiebot.command.commands.music;
|
|||
import handiebot.HandieBot;
|
||||
import handiebot.command.CommandContext;
|
||||
import handiebot.command.types.ContextCommand;
|
||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||
import handiebot.utils.DisappearingMessage;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
|
@ -19,7 +21,12 @@ public class PlayCommand extends ContextCommand {
|
|||
if (context.getArgs() == null || context.getArgs().length == 0){
|
||||
HandieBot.musicPlayer.playQueue(context.getGuild());
|
||||
} else {
|
||||
HandieBot.musicPlayer.loadToQueue(context.getGuild(), context.getArgs()[0]);
|
||||
try {
|
||||
HandieBot.musicPlayer.addToQueue(context.getGuild(), new UnloadedTrack(context.getArgs()[0]));
|
||||
} catch (Exception e) {
|
||||
new DisappearingMessage(context.getChannel(), "Unable to queue track: "+context.getArgs()[0], 3000);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package handiebot.command.commands.music;
|
||||
|
||||
import handiebot.HandieBot;
|
||||
import handiebot.command.CommandContext;
|
||||
import handiebot.command.CommandHandler;
|
||||
import handiebot.command.types.ContextCommand;
|
||||
import handiebot.lavaplayer.Playlist;
|
||||
import handiebot.lavaplayer.playlist.Playlist;
|
||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||
import handiebot.utils.DisappearingMessage;
|
||||
import handiebot.view.BotLog;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
@ -38,13 +41,19 @@ public class PlaylistCommand extends ContextCommand {
|
|||
show(context);
|
||||
break;
|
||||
case ("add"):
|
||||
|
||||
add(context);
|
||||
break;
|
||||
case ("play"):
|
||||
play(context);
|
||||
break;
|
||||
case ("remove"):
|
||||
|
||||
remove(context);
|
||||
break;
|
||||
case ("rename"):
|
||||
|
||||
rename(context);
|
||||
break;
|
||||
case ("move"):
|
||||
move(context);
|
||||
break;
|
||||
default:
|
||||
incorrectMainArg(context.getChannel());
|
||||
|
@ -69,14 +78,14 @@ public class PlaylistCommand extends ContextCommand {
|
|||
*/
|
||||
private void create(CommandContext context){
|
||||
if (context.getArgs().length >= 2) {
|
||||
Playlist playlist = new Playlist(context.getArgs()[1], context.getUser().getLongID());
|
||||
Playlist playlist = new Playlist(context.getArgs()[1]);
|
||||
playlist.save();
|
||||
for (int i = 2; i < context.getArgs().length; i++){
|
||||
String url = context.getArgs()[i];
|
||||
playlist.loadTrack(url);
|
||||
playlist.save();
|
||||
}
|
||||
log.log(BotLog.TYPE.INFO, "Created playlist: "+playlist.getName()+" with "+playlist.getTracks().size()+" new tracks.");
|
||||
playlist.save();
|
||||
log.log(BotLog.TYPE.INFO, "Created playlist: "+playlist.getName()+" with "+playlist.getTrackCount()+" new tracks.");
|
||||
new DisappearingMessage(context.getChannel(), "Your playlist *"+playlist.getName()+"* has been created.\nType `"+ CommandHandler.PREFIX+"playlist play "+playlist.getName()+"` to play it.", 5000);
|
||||
} else {
|
||||
new DisappearingMessage(context.getChannel(), "You must specify a name for the new playlist.", 3000);
|
||||
|
@ -93,6 +102,7 @@ public class PlaylistCommand extends ContextCommand {
|
|||
File f = new File(System.getProperty("user.home")+"/.handiebot/playlist/"+context.getArgs()[1].replace(" ", "_")+".txt");
|
||||
boolean success = f.delete();
|
||||
if (success){
|
||||
log.log(BotLog.TYPE.INFO, "The playlist ["+context.getArgs()[1]+"] has been deleted.");
|
||||
new DisappearingMessage(context.getChannel(), "The playlist *"+context.getArgs()[1]+"* has been deleted.", 5000);
|
||||
} else {
|
||||
log.log(BotLog.TYPE.ERROR, "Unable to delete playlist: "+context.getArgs()[1]);
|
||||
|
@ -112,14 +122,164 @@ public class PlaylistCommand extends ContextCommand {
|
|||
*/
|
||||
private void show(CommandContext context){
|
||||
if (context.getArgs().length > 1){
|
||||
|
||||
if (Playlist.playlistExists(context.getArgs()[1])){
|
||||
Playlist playlist = new Playlist(context.getArgs()[1]);
|
||||
playlist.load();
|
||||
IMessage message = context.getChannel().sendMessage(playlist.toString());
|
||||
DisappearingMessage.deleteMessageAfter(6000, message);
|
||||
} else {
|
||||
new DisappearingMessage(context.getChannel(), "The playlist you specified does not exist.\nUse `"+CommandHandler.PREFIX+"playlist show` to view available playlists.", 5000);
|
||||
}
|
||||
} else {
|
||||
List<String> playlists = Playlist.getAvailablePlaylists();
|
||||
StringBuilder sb = new StringBuilder("**Playlists:**\n");
|
||||
for (String playlist : playlists) {
|
||||
sb.append(playlist).append('\n');
|
||||
}
|
||||
context.getChannel().sendMessage(sb.toString());
|
||||
IMessage message = context.getChannel().sendMessage(sb.toString());
|
||||
DisappearingMessage.deleteMessageAfter(6000, message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to add a song or multiple songs to a playlist.
|
||||
* @param context The command context.
|
||||
*/
|
||||
private void add(CommandContext context){
|
||||
if (context.getArgs().length > 2){
|
||||
if (!Playlist.playlistExists(context.getArgs()[1])){
|
||||
new DisappearingMessage(context.getChannel(), "The playlist you entered does not exist.", 3000);
|
||||
return;
|
||||
}
|
||||
Playlist playlist = new Playlist(context.getArgs()[1]);
|
||||
playlist.load();
|
||||
for (int i = 2; i < context.getArgs().length; i++){
|
||||
playlist.loadTrack(context.getArgs()[i]);
|
||||
new DisappearingMessage(context.getChannel(), "Added track to *"+playlist.getName()+"*.", 3000);
|
||||
}
|
||||
playlist.save();
|
||||
IMessage message = context.getChannel().sendMessage(playlist.toString());
|
||||
log.log(BotLog.TYPE.INFO, "Added song(s) to playlist ["+playlist.getName()+"].");
|
||||
DisappearingMessage.deleteMessageAfter(6000, message);
|
||||
} else {
|
||||
if (context.getArgs().length == 1){
|
||||
new DisappearingMessage(context.getChannel(), "You must provide the name of a playlist to add a URL to.\nUse '"+CommandHandler.PREFIX+"playlist show` to view available playlists.", 5000);
|
||||
} else {
|
||||
new DisappearingMessage(context.getChannel(), "You must provide at least one URL to add.", 3000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shifts the named playlist to the active playlist and begins playback in accordance with the Music Player.
|
||||
* @param context The command context.
|
||||
*/
|
||||
private void play(CommandContext context){
|
||||
if (context.getArgs().length == 2){
|
||||
if (!Playlist.playlistExists(context.getArgs()[1])){
|
||||
new DisappearingMessage(context.getChannel(), "The playlist you entered does not exist.", 3000);
|
||||
return;
|
||||
}
|
||||
Playlist playlist = new Playlist(context.getArgs()[1]);
|
||||
playlist.load();
|
||||
HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.setPlaylist(playlist);
|
||||
HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.nextTrack();
|
||||
log.log(BotLog.TYPE.INFO, "Loaded playlist ["+playlist.getName()+"].");
|
||||
new DisappearingMessage(context.getChannel(), "Now playing from playlist: *"+playlist.getName()+"*.", 6000);
|
||||
} else {
|
||||
new DisappearingMessage(context.getChannel(), "You must provide a playlist to play.\nUse '"+CommandHandler.PREFIX+"playlist show` to view available playlists.", 3000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to rename a playlist.
|
||||
* @param context The command context.
|
||||
*/
|
||||
private void rename(CommandContext context){
|
||||
if (context.getArgs().length == 3){
|
||||
if (!Playlist.playlistExists(context.getArgs()[1])){
|
||||
new DisappearingMessage(context.getChannel(), "The playlist you entered does not exist.", 3000);
|
||||
return;
|
||||
}
|
||||
File f = new File(System.getProperty("user.home")+"/.handiebot/playlist/"+context.getArgs()[1].replace(" ", "_")+".txt");
|
||||
boolean success = f.renameTo(new File(System.getProperty("user.home")+"/.handiebot/playlist/"+context.getArgs()[2].replace(" ", "_")+".txt"));
|
||||
if (success){
|
||||
new DisappearingMessage(context.getChannel(), "The playlist *"+context.getArgs()[1]+"* has been renamed to *"+context.getArgs()[2]+"*.", 6000);
|
||||
log.log(BotLog.TYPE.INFO, "Playlist "+context.getArgs()[1]+" renamed to "+context.getArgs()[2]+".");
|
||||
} else {
|
||||
new DisappearingMessage(context.getChannel(), "Unable to rename playlist.", 3000);
|
||||
log.log(BotLog.TYPE.ERROR, "Unable to rename playlist "+context.getArgs()[1]+" to "+context.getArgs()[2]+".");
|
||||
}
|
||||
} else {
|
||||
new DisappearingMessage(context.getChannel(), "You must include the original playlist, and a new name for it.", 3000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempst to remove the song at a specified index of the playlist.
|
||||
* @param context The command context.
|
||||
*/
|
||||
private void remove(CommandContext context){
|
||||
if (context.getArgs().length == 3){
|
||||
if (!Playlist.playlistExists(context.getArgs()[1])){
|
||||
new DisappearingMessage(context.getChannel(), "The playlist you entered does not exist.", 3000);
|
||||
return;
|
||||
}
|
||||
Playlist playlist = new Playlist(context.getArgs()[1]);
|
||||
playlist.load();
|
||||
try{
|
||||
int index = Integer.parseInt(context.getArgs()[2]);
|
||||
UnloadedTrack track = playlist.getTracks().get(index);
|
||||
playlist.removeTrack(track);
|
||||
new DisappearingMessage(context.getChannel(), "Removed song: *"+track.getTitle()+"* from playlist **"+playlist.getName()+"**.", 6000);
|
||||
log.log(BotLog.TYPE.MUSIC, "Removed song: "+track.getTitle()+" from playlist ["+playlist.getName()+"].");
|
||||
DisappearingMessage.deleteMessageAfter(6000, context.getChannel().sendMessage(playlist.toString()));
|
||||
} catch (IndexOutOfBoundsException | NumberFormatException e){
|
||||
new DisappearingMessage(context.getChannel(), "Unable to remove the specified song.", 3000);
|
||||
log.log(BotLog.TYPE.ERROR, "Unable to remove song from playlist: ["+playlist.getName()+"].");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
} else {
|
||||
new DisappearingMessage(context.getChannel(), "You must provide a playlist name, followed by the index number of a song to remove.", 5000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a song from one index to another.
|
||||
* @param context The command context.
|
||||
*/
|
||||
private void move(CommandContext context){
|
||||
if (context.getArgs().length == 4){
|
||||
if (!Playlist.playlistExists(context.getArgs()[1])){
|
||||
new DisappearingMessage(context.getChannel(), "The playlist you entered does not exist.", 3000);
|
||||
return;
|
||||
}
|
||||
Playlist playlist = new Playlist(context.getArgs()[1]);
|
||||
playlist.load();
|
||||
int oldIndex = -1;
|
||||
int newIndex = -1;
|
||||
try {
|
||||
oldIndex = Integer.parseInt(context.getArgs()[2])-1;
|
||||
newIndex = Integer.parseInt(context.getArgs()[3])-1;
|
||||
} catch (NumberFormatException e){
|
||||
new DisappearingMessage(context.getChannel(), "You must enter two integer values for the song indices.", 5000);
|
||||
}
|
||||
UnloadedTrack track = null;
|
||||
if (oldIndex > -1 && oldIndex < playlist.getTrackCount()){
|
||||
track = playlist.getTracks().remove(oldIndex);
|
||||
if (newIndex > -1 && newIndex <= playlist.getTrackCount()){
|
||||
playlist.getTracks().add(newIndex, track);
|
||||
new DisappearingMessage(context.getChannel(), "Moved song *"+track.getTitle()+"* from position "+(oldIndex+1)+" to position "+(newIndex+1), 6000);
|
||||
log.log(BotLog.TYPE.MUSIC, "Moved song "+track.getTitle()+" from position "+(oldIndex+1)+" to position "+(newIndex+1));
|
||||
} else {
|
||||
new DisappearingMessage(context.getChannel(), "The index of the song's new position is invalid. You entered "+newIndex, 5000);
|
||||
}
|
||||
} else {
|
||||
new DisappearingMessage(context.getChannel(), "The index of the song is invalid. You entered "+oldIndex, 5000);
|
||||
}
|
||||
} else {
|
||||
new DisappearingMessage(context.getChannel(), "You must provide a playlist name, followed by the song index, and a new index for that song.", 5000);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@ package handiebot.command.commands.music;
|
|||
import handiebot.HandieBot;
|
||||
import handiebot.command.CommandContext;
|
||||
import handiebot.command.types.ContextCommand;
|
||||
import handiebot.utils.DisappearingMessage;
|
||||
import handiebot.view.BotLog;
|
||||
|
||||
import static handiebot.HandieBot.log;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
|
@ -22,5 +26,7 @@ public class RepeatCommand extends ContextCommand {
|
|||
} else {
|
||||
HandieBot.musicPlayer.toggleRepeat(context.getGuild());
|
||||
}
|
||||
log.log(BotLog.TYPE.MUSIC, context.getGuild(), "Set repeat to "+HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.isRepeating());
|
||||
new DisappearingMessage(context.getChannel(), "Set repeat to "+HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.isRepeating(), 3000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@ package handiebot.command.commands.music;
|
|||
import handiebot.HandieBot;
|
||||
import handiebot.command.CommandContext;
|
||||
import handiebot.command.types.ContextCommand;
|
||||
import handiebot.utils.DisappearingMessage;
|
||||
import handiebot.view.BotLog;
|
||||
|
||||
import static handiebot.HandieBot.log;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
|
@ -22,5 +26,7 @@ public class ShuffleCommand extends ContextCommand {
|
|||
} else {
|
||||
HandieBot.musicPlayer.toggleShuffle(context.getGuild());
|
||||
}
|
||||
log.log(BotLog.TYPE.MUSIC, context.getGuild(), "Set shuffle to "+Boolean.toString(HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.isShuffling()));
|
||||
new DisappearingMessage(context.getChannel(), "Set shuffle to "+Boolean.toString(HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.isShuffling()), 3000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,19 @@
|
|||
package handiebot.lavaplayer;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
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 handiebot.command.CommandHandler;
|
||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||
import handiebot.utils.DisappearingMessage;
|
||||
import handiebot.utils.Pastebin;
|
||||
import handiebot.view.BotLog;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IGuild;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
import sx.blah.discord.handle.obj.IVoiceChannel;
|
||||
import sx.blah.discord.util.EmbedBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -46,7 +30,6 @@ public class MusicPlayer {
|
|||
|
||||
//Name for the message and voice channels dedicated to this bot.
|
||||
static String CHANNEL_NAME = "HandieBotMusic";
|
||||
private static String PASTEBIN_KEY = "769adc01154922ece448cabd7a33b57c";
|
||||
|
||||
private final AudioPlayerManager playerManager;
|
||||
|
||||
|
@ -78,7 +61,7 @@ public class MusicPlayer {
|
|||
* @param guild The guild to get the music manager for.
|
||||
* @return The music manager for a guild.
|
||||
*/
|
||||
private GuildMusicManager getMusicManager(IGuild guild){
|
||||
public GuildMusicManager getMusicManager(IGuild guild){
|
||||
if (!this.musicManagers.containsKey(guild)){
|
||||
log.log(BotLog.TYPE.MUSIC, guild, "Creating new music manager and audio provider for guild: "+guild.getName());
|
||||
this.musicManagers.put(guild, new GuildMusicManager(this.playerManager, guild));
|
||||
|
@ -165,141 +148,39 @@ public class MusicPlayer {
|
|||
* Sends a formatted message to the guild about the first few items in a queue.
|
||||
*/
|
||||
public void showQueueList(IGuild guild, boolean showAll) {
|
||||
List<AudioTrack> tracks = getMusicManager(guild).scheduler.queueList();
|
||||
List<UnloadedTrack> tracks = getMusicManager(guild).scheduler.queueList();
|
||||
if (tracks.size() == 0) {
|
||||
new DisappearingMessage(getChatChannel(guild), "The queue is empty. Use **"+ CommandHandler.PREFIX+"play** *URL* to add songs.", 3000);
|
||||
} else {
|
||||
if (!showAll) {
|
||||
if (tracks.size() > 10 && showAll) {
|
||||
String result = Pastebin.paste("Current queue for discord server: "+guild.getName()+".", getMusicManager(guild).scheduler.getActivePlaylist().toString());
|
||||
if (result != null && result.startsWith("https://pastebin.com/")){
|
||||
log.log(BotLog.TYPE.INFO, guild, "Queue uploaded to pastebin: "+result);
|
||||
new DisappearingMessage(getChatChannel(guild), "You may view the full queue by following the link: "+result, 600000);
|
||||
} else {
|
||||
log.log(BotLog.TYPE.ERROR, guild, "Unable to upload to pastebin: "+result);
|
||||
}
|
||||
} else {
|
||||
EmbedBuilder builder = new EmbedBuilder();
|
||||
builder.withColor(255, 0, 0);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < (tracks.size() <= 10 ? tracks.size() : 10); i++) {
|
||||
sb.append(i + 1);
|
||||
sb.append(". ");
|
||||
sb.append('[');
|
||||
sb.append(tracks.get(i).getInfo().title);
|
||||
sb.append("](");
|
||||
sb.append(tracks.get(i).getInfo().uri);
|
||||
sb.append(")");
|
||||
int seconds = (int) (tracks.get(i).getInfo().length / 1000);
|
||||
int minutes = seconds / 60;
|
||||
seconds = seconds % 60;
|
||||
String time = String.format(" [%d:%02d]\n", minutes, seconds);
|
||||
sb.append(time);
|
||||
sb.append(i + 1).append(". [").append(tracks.get(i).getTitle()).append("](");
|
||||
sb.append(tracks.get(i).getURL()).append(")");
|
||||
sb.append(tracks.get(i).getFormattedDuration()).append('\n');
|
||||
}
|
||||
builder.withTimestamp(System.currentTimeMillis());
|
||||
builder.appendField("Showing " + (tracks.size() <= 10 ? tracks.size() : "the first 10") + " track" + (tracks.size() > 1 ? "s" : "") + ".", sb.toString(), false);
|
||||
IMessage message = getChatChannel(guild).sendMessage(builder.build());
|
||||
DisappearingMessage.deleteMessageAfter(6000, message);
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder("Queue for Discord Server: "+guild.getName()+"\n");
|
||||
for (int i = 0; i < tracks.size(); i++){
|
||||
sb.append(i+1).append(". ").append(tracks.get(i).getInfo().title);
|
||||
int seconds = (int) (tracks.get(i).getInfo().length / 1000);
|
||||
int minutes = seconds / 60;
|
||||
seconds = seconds % 60;
|
||||
String time = String.format(" [%d:%02d]\n", minutes, seconds);
|
||||
sb.append(time);
|
||||
}
|
||||
|
||||
HttpClient httpclient = HttpClients.createDefault();
|
||||
HttpPost httppost = new HttpPost("https://www.pastebin.com/api/api_post.php");
|
||||
|
||||
// Request parameters and other properties.
|
||||
List<NameValuePair> params = new ArrayList<NameValuePair>(2);
|
||||
params.add(new BasicNameValuePair("api_dev_key", PASTEBIN_KEY));
|
||||
params.add(new BasicNameValuePair("api_option", "paste"));
|
||||
params.add(new BasicNameValuePair("api_paste_code", sb.toString()));
|
||||
params.add(new BasicNameValuePair("api_paste_private", "0"));
|
||||
params.add(new BasicNameValuePair("api_paste_name", "Music Queue for Discord Server: "+guild.getName()));
|
||||
params.add(new BasicNameValuePair("api_paste_expire_date", "10M"));
|
||||
//params.add(new BasicNameValuePair("api_paste_format", "text"));
|
||||
params.add(new BasicNameValuePair("api_user_key", ""));
|
||||
|
||||
try {
|
||||
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//Execute and get the response.
|
||||
HttpResponse response = null;
|
||||
try {
|
||||
response = httpclient.execute(httppost);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
HttpEntity entity = response.getEntity();
|
||||
|
||||
if (entity != null) {
|
||||
InputStream instream = null;
|
||||
try {
|
||||
instream = entity.getContent();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
IOUtils.copy(instream, writer, "UTF-8");
|
||||
String pasteURL = writer.toString();
|
||||
log.log(BotLog.TYPE.INFO, guild, "Uploaded full queue to "+pasteURL);
|
||||
new DisappearingMessage(getChatChannel(guild), "You may view the full queue here. "+pasteURL, 60000);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
instream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a URL to the queue, or outputs an error message if it fails.
|
||||
* @param trackURL A string representing a youtube/soundcloud URL.
|
||||
*/
|
||||
public void loadToQueue(IGuild guild, String trackURL){
|
||||
this.playerManager.loadItemOrdered(getMusicManager(guild), trackURL, new AudioLoadResultHandler() {
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack audioTrack) {
|
||||
addToQueue(guild, audioTrack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playlistLoaded(AudioPlaylist audioPlaylist) {
|
||||
if (audioPlaylist.getTracks().size() > 0){
|
||||
AudioTrack firstTrack = audioPlaylist.getSelectedTrack();
|
||||
if (firstTrack == null){
|
||||
firstTrack = audioPlaylist.getTracks().get(0);
|
||||
}
|
||||
addToQueue(guild, firstTrack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMatches() {
|
||||
log.log(BotLog.TYPE.ERROR, guild, "No matches found for: "+trackURL);
|
||||
new DisappearingMessage(getChatChannel(guild), "Unable to find a result for: "+trackURL, 3000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException e) {
|
||||
log.log(BotLog.TYPE.ERROR, guild, "Unable to load song: "+trackURL+". "+e.getMessage());
|
||||
new DisappearingMessage(getChatChannel(guild), "Unable to load. "+e.getMessage(), 3000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a track to the queue and sends a message to the appropriate channel notifying users.
|
||||
* @param track The track to queue.
|
||||
*/
|
||||
private void addToQueue(IGuild guild, AudioTrack track){
|
||||
public void addToQueue(IGuild guild, UnloadedTrack track){
|
||||
IVoiceChannel voiceChannel = getVoiceChannel(guild);
|
||||
if (voiceChannel != null){
|
||||
if (!voiceChannel.isConnected()) {
|
||||
|
@ -310,7 +191,7 @@ public class MusicPlayer {
|
|||
//Build message.
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (timeUntilPlay > 0) {
|
||||
sb.append("Added **").append(track.getInfo().title).append("** to the queue.");
|
||||
sb.append("Added **").append(track.getTitle()).append("** to the queue.");
|
||||
}
|
||||
//If there's some tracks in the queue, get the time until this one plays.
|
||||
if (timeUntilPlay > 0){
|
||||
|
|
|
@ -6,6 +6,8 @@ import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
|||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
|
||||
import handiebot.HandieBot;
|
||||
import handiebot.lavaplayer.playlist.Playlist;
|
||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||
import handiebot.view.BotLog;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IGuild;
|
||||
|
@ -36,10 +38,23 @@ public class TrackScheduler extends AudioEventAdapter {
|
|||
* @param player The audio player this scheduler uses.
|
||||
*/
|
||||
public TrackScheduler(AudioPlayer player, IGuild guild){
|
||||
super();
|
||||
this.player = player;
|
||||
this.guild = guild;
|
||||
//this.activePlaylist = new Playlist("HandieBot Active Playlist", 283652989212688384L);
|
||||
this.activePlaylist = new Playlist("HandieBot Active Playlist");
|
||||
//this.activePlaylist = new Playlist("HandieBot Active Playlist");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the playlist with the tracks from a given playlist, or if null,
|
||||
* @param playlist the playlist to load from.
|
||||
*/
|
||||
public void setPlaylist(Playlist playlist){
|
||||
this.activePlaylist = playlist;
|
||||
}
|
||||
|
||||
public Playlist getActivePlaylist(){
|
||||
return this.activePlaylist;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,7 +99,7 @@ public class TrackScheduler extends AudioEventAdapter {
|
|||
if (currentTrack != null){
|
||||
t += currentTrack.getDuration() - currentTrack.getPosition();
|
||||
}
|
||||
for (AudioTrack track : this.queueList()){
|
||||
for (UnloadedTrack track : this.queueList()){
|
||||
t += track.getDuration();
|
||||
}
|
||||
return t;
|
||||
|
@ -94,7 +109,7 @@ public class TrackScheduler extends AudioEventAdapter {
|
|||
* Returns a list of tracks in the queue.
|
||||
* @return A list of tracks in the queue.
|
||||
*/
|
||||
public List<AudioTrack> queueList(){
|
||||
public List<UnloadedTrack> queueList(){
|
||||
return this.activePlaylist.getTracks();
|
||||
}
|
||||
|
||||
|
@ -102,9 +117,9 @@ public class TrackScheduler extends AudioEventAdapter {
|
|||
* Add the next track to the queue or play right away if nothing is in the queue.
|
||||
* @param track The track to play or add to the queue.
|
||||
*/
|
||||
public void queue(AudioTrack track){
|
||||
public void queue(UnloadedTrack track){
|
||||
if (player.getPlayingTrack() == null){
|
||||
player.startTrack(track, false);
|
||||
player.startTrack(track.loadAudioTrack(), false);
|
||||
} else {
|
||||
this.activePlaylist.addTrack(track);
|
||||
}
|
||||
|
@ -118,7 +133,7 @@ public class TrackScheduler extends AudioEventAdapter {
|
|||
if (currentTrack != null){
|
||||
this.player.stopTrack();
|
||||
}
|
||||
AudioTrack track = (this.repeat ? this.activePlaylist.getNextTrackAndRequeue(this.shuffle) : this.activePlaylist.getNextTrackAndRemove(this.shuffle));
|
||||
AudioTrack track = this.activePlaylist.loadNextTrack(this.shuffle);
|
||||
if (track != null) {
|
||||
IVoiceChannel voiceChannel = HandieBot.musicPlayer.getVoiceChannel(this.guild);
|
||||
if (!voiceChannel.isConnected()){
|
||||
|
@ -154,6 +169,9 @@ public class TrackScheduler extends AudioEventAdapter {
|
|||
|
||||
@Override
|
||||
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
|
||||
if (this.repeat){
|
||||
this.activePlaylist.addTrack(new UnloadedTrack(track));
|
||||
}
|
||||
if (endReason.mayStartNext){
|
||||
nextTrack();
|
||||
} else {
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
package handiebot.lavaplayer;
|
||||
package handiebot.lavaplayer.playlist;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import handiebot.HandieBot;
|
||||
import handiebot.view.BotLog;
|
||||
|
||||
import java.io.*;
|
||||
|
@ -14,13 +10,12 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static handiebot.HandieBot.log;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
* A Playlist is a list of AudioTracks which a track scheduler can pull from to create a queue filled with songs. The
|
||||
* A Playlist is a list of Tracks which a track scheduler can pull from to create a queue filled with songs. The
|
||||
* playlist is persistent, i.e. it is saved into a file.
|
||||
* Be careful, though, as the playlist is not saved in this class, but must be saved manually by whoever is operating
|
||||
* on the playlist.
|
||||
|
@ -28,127 +23,66 @@ import static handiebot.HandieBot.log;
|
|||
public class Playlist {
|
||||
|
||||
private String name;
|
||||
private long creatorUID;
|
||||
|
||||
private List<AudioTrack> tracks;
|
||||
private List<UnloadedTrack> tracks;
|
||||
|
||||
/**
|
||||
* Creates an empty playlist template.
|
||||
* Depending on the circumstances, you may need to call {@code load()} to fill the playlist from a file.
|
||||
* @param name The name of the playlist.
|
||||
* @param creatorUID The ID of the user who created it.
|
||||
*/
|
||||
public Playlist(String name, long creatorUID){
|
||||
this.name = name;
|
||||
this.creatorUID = creatorUID;
|
||||
this.tracks = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a playlist from a file with the given name.
|
||||
* @param name The name of the file.
|
||||
*/
|
||||
public Playlist(String name){
|
||||
this.name = name;
|
||||
this.load();
|
||||
this.tracks = new ArrayList<>();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public long getCreatorUID(){
|
||||
return this.creatorUID;
|
||||
public int getTrackCount(){
|
||||
return this.tracks.size();
|
||||
}
|
||||
|
||||
public List<AudioTrack> getTracks(){
|
||||
public List<UnloadedTrack> getTracks(){
|
||||
return this.tracks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a track to the end of the playlist.
|
||||
* @param track The track to add.
|
||||
*/
|
||||
public void addTrack(AudioTrack track){
|
||||
public void addTrack(UnloadedTrack track){
|
||||
this.tracks.add(track);
|
||||
}
|
||||
|
||||
public void removeTrack(UnloadedTrack track){
|
||||
this.tracks.remove(track);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and returns the audio track that's first on the list.
|
||||
* This removes that track from the playlist.
|
||||
* @param shouldShuffle If this is true, the track returned will be chosen randomly.
|
||||
* @return The AudioTrack corresponding to the next UnloadedTrack in the list.
|
||||
*/
|
||||
public AudioTrack loadNextTrack(boolean shouldShuffle){
|
||||
if (shouldShuffle){
|
||||
return this.tracks.remove(getShuffledIndex(this.tracks.size())).loadAudioTrack();
|
||||
} else {
|
||||
return this.tracks.remove(0).loadAudioTrack();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to load a track or playlist from a URL, and add it to the tracks list.
|
||||
* @param url The URL to get the song/playlist from.
|
||||
*/
|
||||
public void loadTrack(String url){
|
||||
try {
|
||||
HandieBot.musicPlayer.getPlayerManager().loadItem(url, new AudioLoadResultHandler() {
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack audioTrack) {
|
||||
tracks.add(audioTrack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playlistLoaded(AudioPlaylist audioPlaylist) {
|
||||
tracks.addAll(audioPlaylist.getTracks());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMatches() {
|
||||
log.log(BotLog.TYPE.ERROR, "No matches found for: "+url+".");
|
||||
//Do nothing. This should not happen.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException e) {
|
||||
log.log(BotLog.TYPE.ERROR, "Unable to load song from URL: "+url+". "+e.getMessage());
|
||||
//Do nothing. This should not happen.
|
||||
}
|
||||
}).get();
|
||||
} catch (InterruptedException e) {
|
||||
log.log(BotLog.TYPE.ERROR, "Loading of playlist ["+this.name+"] interrupted. "+e.getMessage());
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
log.log(BotLog.TYPE.ERROR, "Execution exception while loading playlist ["+this.name+"]. "+e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a track from the playlist.
|
||||
* @param track The track to remove.
|
||||
*/
|
||||
public void removeTrack(AudioTrack track){
|
||||
this.tracks.remove(track);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies all tracks from a specified playlist to this one.
|
||||
* @param other The other playlist to make a copy of.
|
||||
*/
|
||||
public void copyFrom(Playlist other){
|
||||
this.tracks.clear();
|
||||
other.getTracks().forEach(track -> this.tracks.add(track.makeClone()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next track, i.e. the first one in the list, and removes it from the internal list.
|
||||
* @return The AudioTrack that should be played next.
|
||||
*/
|
||||
public AudioTrack getNextTrackAndRemove(boolean shouldShuffle){
|
||||
if (this.tracks.isEmpty()){
|
||||
return null;
|
||||
}
|
||||
return this.tracks.remove((shouldShuffle ? getShuffledIndex(this.tracks.size()) : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next track to be played, and re-adds it to the end of the playlist, as it would do in a loop.
|
||||
* @return The next track to be played.
|
||||
*/
|
||||
public AudioTrack getNextTrackAndRequeue(boolean shouldShuffle){
|
||||
if (this.tracks.isEmpty()){
|
||||
return null;
|
||||
}
|
||||
AudioTrack track = this.tracks.remove((shouldShuffle ? getShuffledIndex(this.tracks.size()) : 0));
|
||||
UnloadedTrack track = new UnloadedTrack(url);
|
||||
this.tracks.add(track);
|
||||
return track;
|
||||
log.log(BotLog.TYPE.MUSIC, "Added "+track.getTitle()+" to playlist ["+this.name+"].");
|
||||
} catch (Exception e) {
|
||||
log.log(BotLog.TYPE.ERROR, "Unable to add "+url+" to the playlist ["+this.name+"].");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -182,11 +116,9 @@ public class Playlist {
|
|||
File playlistFile = new File(playlistDir.getPath()+"/"+this.name.replace(" ", "_")+".txt");
|
||||
log.log(BotLog.TYPE.INFO, "Saving playlist to: "+playlistFile.getAbsolutePath());
|
||||
try(Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(playlistFile)))){
|
||||
writer.write(this.name+'\n');
|
||||
writer.write(Long.toString(this.creatorUID)+'\n');
|
||||
writer.write(Integer.toString(this.tracks.size())+'\n');
|
||||
for (AudioTrack track : this.tracks){
|
||||
writer.write(track.getInfo().uri);
|
||||
for (UnloadedTrack track : this.tracks){
|
||||
writer.write(track.toString());
|
||||
writer.write('\n');
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
|
@ -201,19 +133,18 @@ public class Playlist {
|
|||
* Loads the playlist from a file with the playlist's name.
|
||||
*/
|
||||
public void load(){
|
||||
String path = System.getProperty("user.home")+"/.handiebot/playlist/"+this.name.replace(" ", "_")+".txt";
|
||||
String path = System.getProperty("user.home")+"/.handiebot/playlist/"+name.replace(" ", "_")+".txt";
|
||||
log.log(BotLog.TYPE.INFO, "Loading playlist from: "+path);
|
||||
File playlistFile = new File(path);
|
||||
if (playlistFile.exists()){
|
||||
try {
|
||||
List<String> lines = Files.readAllLines(Paths.get(playlistFile.toURI()));
|
||||
this.name = lines.remove(0);
|
||||
this.creatorUID = Long.parseLong(lines.remove(0));
|
||||
int trackCount = Integer.parseInt(lines.remove(0));
|
||||
this.name = name;
|
||||
this.tracks = new ArrayList<>(trackCount);
|
||||
for (int i = 0; i < trackCount; i++){
|
||||
String url = lines.remove(0);
|
||||
loadTrack(url);
|
||||
String[] words = lines.remove(0).split(" / ");
|
||||
this.tracks.add(new UnloadedTrack(words[0], words[1], Long.parseLong(words[2])));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.log(BotLog.TYPE.ERROR, "IOException while loading playlist ["+this.name+"]. "+e.getMessage());
|
||||
|
@ -231,7 +162,12 @@ public class Playlist {
|
|||
public static List<String> getAvailablePlaylists(){
|
||||
File playlistFolder = new File(System.getProperty("user.home")+"/.handiebot/playlist");
|
||||
List<String> names = new ArrayList<String>(Arrays.asList(playlistFolder.list()));
|
||||
names.forEach(name -> name = name.replace("_", " "));
|
||||
for (int i = 0; i < names.size(); i++){
|
||||
String name = names.get(i);
|
||||
name = name.replace(".txt", "");
|
||||
name = name.replace("_", " ");
|
||||
names.set(i, name);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
|
@ -250,4 +186,13 @@ public class Playlist {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder sb = new StringBuilder("HandieBot Playlist: "+this.getName()+'\n');
|
||||
for (int i = 0; i < this.getTrackCount(); i++){
|
||||
sb.append(i+1).append(". ").append(this.tracks.get(i).getTitle()).append(" ").append(this.tracks.get(i).getFormattedDuration()).append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
package handiebot.lavaplayer.playlist;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import handiebot.HandieBot;
|
||||
import handiebot.view.BotLog;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static handiebot.HandieBot.log;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
* Class for describing a track without the actual audio track.
|
||||
* This is useful for quickly loading playlists and only loading a track when it is needed.
|
||||
*/
|
||||
public class UnloadedTrack implements Cloneable {
|
||||
|
||||
private String title;
|
||||
private String url;
|
||||
private long duration;
|
||||
|
||||
/**
|
||||
* Constructs a new unloaded track.
|
||||
* This assumes that the url is known to be error free, so it will avoid a time consuming validation check.
|
||||
* @param title The title of the track.
|
||||
* @param url The url of the track, used when loading.
|
||||
* @param duration The duration, in milliseconds(ms) of the song.
|
||||
*/
|
||||
public UnloadedTrack(String title, String url, long duration){
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new unloaded track from a given url.
|
||||
* Therefore, this method will take time to query youtube/soundcloud to receive a valid audio track.
|
||||
* This is meant to ensure that this unloaded track is reliable.
|
||||
* @param songURL The url to load from.
|
||||
*/
|
||||
public UnloadedTrack(String songURL) throws Exception {
|
||||
this.title = null;
|
||||
this.url = null;
|
||||
this.duration = 0;
|
||||
try {
|
||||
HandieBot.musicPlayer.getPlayerManager().loadItem(songURL, new AudioLoadResultHandler() {
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack audioTrack) {
|
||||
title = audioTrack.getInfo().title;
|
||||
url = audioTrack.getInfo().uri;
|
||||
duration = audioTrack.getDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playlistLoaded(AudioPlaylist audioPlaylist) {
|
||||
log.log(BotLog.TYPE.ERROR, "Attempt to load playlist to create unloaded track.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMatches() {
|
||||
log.log(BotLog.TYPE.ERROR, "No matches found for " + songURL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException e) {
|
||||
log.log(BotLog.TYPE.ERROR, "Loading track failed for " + songURL);
|
||||
}
|
||||
}).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
log.log(BotLog.TYPE.ERROR, "Exception occurred while loading item from URL: "+songURL);
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (this.title == null){
|
||||
throw new Exception("Invalid URL: "+songURL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new unloaded track from an already existing audio track.
|
||||
* @param track The track to use.
|
||||
*/
|
||||
public UnloadedTrack(AudioTrack track){
|
||||
this.title = track.getInfo().title;
|
||||
this.url = track.getInfo().uri;
|
||||
this.duration = track.getDuration();
|
||||
}
|
||||
|
||||
public String getTitle(){
|
||||
return this.title;
|
||||
}
|
||||
|
||||
public String getURL(){
|
||||
return this.url;
|
||||
}
|
||||
|
||||
public long getDuration(){
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the real audio track from the internet, and returns it.
|
||||
* @return an AudioTrack representing this track.
|
||||
*/
|
||||
public AudioTrack loadAudioTrack(){
|
||||
final AudioTrack[] track = {null};
|
||||
try {
|
||||
HandieBot.musicPlayer.getPlayerManager().loadItem(this.url, new AudioLoadResultHandler() {
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack audioTrack) {
|
||||
track[0] = audioTrack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playlistLoaded(AudioPlaylist audioPlaylist) {
|
||||
log.log(BotLog.TYPE.ERROR, "Attempt to load playlist to create unloaded track.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMatches() {
|
||||
log.log(BotLog.TYPE.ERROR, "No matches found for " + url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException e) {
|
||||
log.log(BotLog.TYPE.ERROR, "Loading track failed for " + url);
|
||||
}
|
||||
}).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
log.log(BotLog.TYPE.ERROR, "Exception occurred while loading item from URL: "+url);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return track[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the duration of the track in an aesthetically pleasing way.
|
||||
* Format is as follows: [mm:ss]
|
||||
* @return A string representation of the duration of a track.
|
||||
*/
|
||||
public String getFormattedDuration(){
|
||||
int seconds = (int) (this.duration / 1000);
|
||||
int minutes = seconds / 60;
|
||||
seconds = seconds % 60;
|
||||
return String.format("[%d:%02d]", minutes, seconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return this.title + " / " + this.url + " / " + Long.toString(this.duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a clone of this track.
|
||||
* @return A clone of this track.
|
||||
*/
|
||||
public UnloadedTrack clone(){
|
||||
try {
|
||||
super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new UnloadedTrack(this.title, this.url, this.duration);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package handiebot.utils;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
* Class to easily paste to pastebin.
|
||||
*/
|
||||
public class Pastebin {
|
||||
|
||||
private static String PASTEBIN_KEY = "769adc01154922ece448cabd7a33b57c";
|
||||
|
||||
public static String paste(String title, String content){
|
||||
HttpClient client = HttpClients.createDefault();
|
||||
HttpPost post = new HttpPost("https://www.pastebin.com/api/api_post.php");
|
||||
|
||||
List<NameValuePair> params = new ArrayList<>();
|
||||
params.add(new BasicNameValuePair("api_dev_key", PASTEBIN_KEY));
|
||||
params.add(new BasicNameValuePair("api_option", "paste"));
|
||||
params.add(new BasicNameValuePair("api_paste_code", content));
|
||||
params.add(new BasicNameValuePair("api_paste_private", "0"));
|
||||
params.add(new BasicNameValuePair("api_paste_name", title));
|
||||
params.add(new BasicNameValuePair("api_paste_expire_date", "10M"));
|
||||
params.add(new BasicNameValuePair("api_user_key", ""));
|
||||
|
||||
try {
|
||||
post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
|
||||
HttpResponse response = client.execute(post);
|
||||
HttpEntity entity = response.getEntity();
|
||||
if (entity != null){
|
||||
try (InputStream in = entity.getContent()){
|
||||
StringWriter writer = new StringWriter();
|
||||
IOUtils.copy(in, writer, "UTF-8");
|
||||
return writer.toString();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -2,10 +2,12 @@ package handiebot.view;
|
|||
|
||||
import handiebot.HandieBot;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
|
@ -27,6 +29,11 @@ public class BotWindow extends JFrame {
|
|||
}
|
||||
}
|
||||
});
|
||||
try {
|
||||
setIconImage(ImageIO.read(getClass().getClassLoader().getResourceAsStream("avatarIcon.png")));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
setContentPane(view.mainPanel);
|
||||
setJMenuBar(new MenuBar());
|
||||
setPreferredSize(new Dimension(800, 600));
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package handiebot.view.actions.music;
|
||||
|
||||
import handiebot.HandieBot;
|
||||
import sx.blah.discord.handle.obj.IGuild;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
|
@ -23,10 +22,6 @@ public class PlayAction extends MusicAction {
|
|||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (this.args == null || this.args.length < 1){
|
||||
HandieBot.musicPlayer.playQueue(this.guild);
|
||||
} else {
|
||||
HandieBot.musicPlayer.loadToQueue(this.guild, this.args[0]);
|
||||
}
|
||||
System.out.println("Play action.");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue