diff --git a/pom.xml b/pom.xml
index 5ceabfe..21b6797 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,6 +21,10 @@
jar
+
+ 1.1.0
+
+
jcenter
@@ -43,6 +47,11 @@
lavaplayer
1.2.39
+
+ com.github.kennedyoliveira
+ pastebin4j
+ ${pastebin4j.version}
+
\ No newline at end of file
diff --git a/src/main/java/handiebot/HandieBot.java b/src/main/java/handiebot/HandieBot.java
index ec09d16..b285951 100644
--- a/src/main/java/handiebot/HandieBot.java
+++ b/src/main/java/handiebot/HandieBot.java
@@ -8,6 +8,7 @@ import handiebot.view.View;
import sx.blah.discord.api.ClientBuilder;
import sx.blah.discord.api.IDiscordClient;
import sx.blah.discord.api.events.EventSubscriber;
+import sx.blah.discord.handle.impl.events.ReadyEvent;
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
import sx.blah.discord.util.DiscordException;
import sx.blah.discord.util.RateLimitException;
@@ -26,17 +27,17 @@ public class HandieBot {
private static BotWindow window;
public static BotLog log;
- private CommandHandler commandHandler;
+ private static CommandHandler commandHandler;
public static MusicPlayer musicPlayer;
- private HandieBot() {
- this.commandHandler = new CommandHandler(this);
-
- }
-
@EventSubscriber
public void onMessageReceived(MessageReceivedEvent event) {
- this.commandHandler.handleCommand(event);
+ commandHandler.handleCommand(event);
+ }
+
+ @EventSubscriber
+ public void onReady(ReadyEvent event){
+ log.log(BotLog.TYPE.INFO, "HandieBot initialized.");
}
public static void main(String[] args) throws DiscordException, RateLimitException {
@@ -47,7 +48,7 @@ public class HandieBot {
log = new BotLog(view.getOutputArea());
window = new BotWindow(view);
- log.log(BotLog.TYPE.INFO, "Logging client in.");
+ log.log(BotLog.TYPE.INFO, "Logging client in...");
client = new ClientBuilder().withToken(TOKEN).build();
client.getDispatcher().registerListener(new HandieBot());
client.login();
diff --git a/src/main/java/handiebot/command/CommandHandler.java b/src/main/java/handiebot/command/CommandHandler.java
index 1b2b0d2..642682a 100644
--- a/src/main/java/handiebot/command/CommandHandler.java
+++ b/src/main/java/handiebot/command/CommandHandler.java
@@ -1,14 +1,21 @@
package handiebot.command;
import com.sun.istack.internal.NotNull;
-import handiebot.HandieBot;
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;
import java.awt.*;
+import static handiebot.HandieBot.log;
+
/**
* @author Andrew Lalis
* Class to process commands.
@@ -16,18 +23,11 @@ import java.awt.*;
public class CommandHandler {
public static String PREFIX = "!";
-
- private final HandieBot bot;
-
- public CommandHandler(HandieBot bot){
- this.bot = bot;
- }
-
/**
* Main method to handle user messages.
* @param event The event generated by the message.
*/
- public void handleCommand(MessageReceivedEvent event){
+ public static void handleCommand(MessageReceivedEvent event){
IMessage message = event.getMessage();
IUser user = event.getAuthor();
IChannel channel = event.getChannel();
@@ -38,29 +38,24 @@ public class CommandHandler {
DisappearingMessage.deleteMessageAfter(1000, message);
if (command.equals("play")){
//Play or queue a song.
- if (args.length == 1) {
- HandieBot.musicPlayer.loadToQueue(guild, args[0]);
- } else if (args.length == 0){
- HandieBot.musicPlayer.playQueue(guild);
- }
+ new PlayAction(guild, args).actionPerformed(null);
} else if (command.equals("skip") && args.length == 0){
//Skip the current song.
- HandieBot.musicPlayer.skipTrack(guild);
+ new SkipAction(guild).actionPerformed(null);
} else if (command.equals("help")){
//Send a PM to the user with help info.
- this.sendHelpInfo(user);//TODO finish the help command and fill in with new descriptions each time.
- } else if (command.equals("queue") && args.length == 0){
+ sendHelpInfo(user);//TODO finish the help command and fill in with new descriptions each time.
+ } else if (command.equals("queue")){
//Display the first few items of the queue.
- HandieBot.musicPlayer.showQueueList(guild);
+ new QueueListAction(guild, (args.length == 1) && args[0].equals("all")).actionPerformed(null);
} else if (command.equals("repeat")){
//Toggle repeat.
- HandieBot.musicPlayer.toggleRepeat(guild);
+ new ToggleRepeatAction(guild).actionPerformed(null);
} else if (command.equals("clear")){
//TODO clear command.
} else if (command.equals("quit")){
//Quit the application.
- channel.sendMessage("Quitting HandieBot functions.");
- HandieBot.musicPlayer.quit(guild);
+ new QuitAction(guild).actionPerformed(null);
} else if (command.equals("playlist")){
//Do playlist actions.
//TODO perform actions!
@@ -69,8 +64,12 @@ public class CommandHandler {
if (args[0].length() != 1){
new DisappearingMessage(channel, "You may only set the prefix to 1 character. To do otherwise is simply foolish.", 3000);
} else {
+ new DisappearingMessage(channel, "Command prefix set to "+PREFIX, 10000);
+ log.log(BotLog.TYPE.INFO, guild, "Prefix set to "+PREFIX);
setPrefix(args[0]);
}
+ } else {
+ log.log(BotLog.TYPE.ERROR, guild, "Invalid command: "+command+" issued by "+user.getName());
}
}
}
@@ -80,7 +79,7 @@ public class CommandHandler {
* @param message The message to get a command from.
* @return The command word, minus the prefix, or null.
*/
- private String extractCommand(IMessage message){
+ private static String extractCommand(IMessage message){
String[] words = message.getContent().split(" ");
if (words[0].startsWith(PREFIX)){
return words[0].replaceFirst(PREFIX, "").toLowerCase();
@@ -94,7 +93,7 @@ public class CommandHandler {
* @return A list of strings representing args.
*/
@NotNull
- private String[] extractArgs(IMessage message){
+ private static String[] extractArgs(IMessage message){
String[] words = message.getContent().split(" ");
if (words[0].startsWith(PREFIX)){
String[] args = new String[words.length-1];
@@ -110,7 +109,7 @@ public class CommandHandler {
* Method to send a useful list of commands to any user if they desire.
* @param user The user to send the message to.
*/
- private void sendHelpInfo(IUser user){
+ private static void sendHelpInfo(IUser user){
IPrivateChannel pm = user.getOrCreatePMChannel();
EmbedBuilder builder = new EmbedBuilder();
diff --git a/src/main/java/handiebot/lavaplayer/MusicPlayer.java b/src/main/java/handiebot/lavaplayer/MusicPlayer.java
index e4ffb5d..79296f6 100644
--- a/src/main/java/handiebot/lavaplayer/MusicPlayer.java
+++ b/src/main/java/handiebot/lavaplayer/MusicPlayer.java
@@ -31,7 +31,8 @@ import static handiebot.HandieBot.log;
public class MusicPlayer {
//Name for the message and voice channels dedicated to this bot.
- public static String CHANNEL_NAME = "HandieBotMusic";
+ static String CHANNEL_NAME = "HandieBotMusic";
+ private static String PASTEBIN_KEY = "769adc01154922ece448cabd7a33b57c";
private final AudioPlayerManager playerManager;
@@ -74,7 +75,7 @@ public class MusicPlayer {
* @param guild The guild to get the channel from.
* @return A message channel on a particular guild that is specifically for music.
*/
- private IChannel getChatChannel(IGuild guild){
+ public IChannel getChatChannel(IGuild guild){
if (!this.chatChannels.containsKey(guild)){
List channels = guild.getChannelsByName(CHANNEL_NAME.toLowerCase());
if (channels.isEmpty()){
@@ -93,7 +94,7 @@ public class MusicPlayer {
* @param guild The guild to get the channel from.
* @return The voice channel on a guild that is for this bot.
*/
- private IVoiceChannel getVoiceChannel(IGuild guild){
+ public IVoiceChannel getVoiceChannel(IGuild guild){
if (!this.voiceChannels.containsKey(guild)){
List channels = guild.getVoiceChannelsByName(CHANNEL_NAME);
if (channels.isEmpty()){
@@ -119,32 +120,56 @@ public class MusicPlayer {
/**
* Sends a formatted message to the guild about the first few items in a queue.
*/
- public void showQueueList(IGuild guild){
+ public void showQueueList(IGuild guild, boolean showAll){
List 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 {
- 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);
+ if (!showAll) {
+ 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);
+ }
+ 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);
+ }
+ //TODO: get pastebin working.
+ /*
+ PasteBin pasteBin = new PasteBin(new AccountCredentials(PASTEBIN_KEY));
+ Paste paste = new Paste(PASTEBIN_KEY);
+ paste.setTitle("Music Queue for Discord Server: "+guild.getName());
+ paste.setContent(sb.toString());
+ paste.setExpiration(PasteExpiration.ONE_HOUR);
+ paste.setVisibility(PasteVisibility.PUBLIC);
+ final String pasteURL = pasteBin.createPaste(paste);
+ log.log(BotLog.TYPE.INFO, guild, "Uploaded full queue to "+pasteURL);
+ new DisappearingMessage(getChatChannel(guild), "You may view the full queue here. "+pasteURL, 60000);
+ */
}
- 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);
}
}
@@ -188,7 +213,7 @@ public class MusicPlayer {
* Adds a track to the queue and sends a message to the appropriate channel notifying users.
* @param track The track to queue.
*/
- public void addToQueue(IGuild guild, AudioTrack track){
+ private void addToQueue(IGuild guild, AudioTrack track){
IVoiceChannel voiceChannel = getVoiceChannel(guild);
if (voiceChannel != null){
if (!voiceChannel.isConnected()) {
@@ -240,10 +265,6 @@ public class MusicPlayer {
*/
public void quit(IGuild guild){
getMusicManager(guild).scheduler.quit();
- IVoiceChannel vc = this.getVoiceChannel(guild);
- if (vc.isConnected()){
- vc.leave();
- }
}
/**
@@ -252,10 +273,6 @@ public class MusicPlayer {
public void quitAll(){
this.musicManagers.forEach((guild, musicManager) -> {
musicManager.scheduler.quit();
- IVoiceChannel vc = this.getVoiceChannel(guild);
- if (vc.isConnected()){
- vc.leave();
- }
});
this.playerManager.shutdown();
}
diff --git a/src/main/java/handiebot/lavaplayer/TrackScheduler.java b/src/main/java/handiebot/lavaplayer/TrackScheduler.java
index 6e42fdd..30d6d6b 100644
--- a/src/main/java/handiebot/lavaplayer/TrackScheduler.java
+++ b/src/main/java/handiebot/lavaplayer/TrackScheduler.java
@@ -6,10 +6,12 @@ import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter;
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.view.BotLog;
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.RequestBuffer;
import java.util.List;
@@ -113,11 +115,19 @@ public class TrackScheduler extends AudioEventAdapter {
* Starts the next track, stopping the current one if it's playing.
*/
public void nextTrack(){
+ AudioTrack currentTrack = this.player.getPlayingTrack();
+ if (currentTrack != null){
+ this.player.stopTrack();
+ }
AudioTrack track = (this.repeat ? this.activePlaylist.getNextTrackAndRequeue(this.shuffle) : this.activePlaylist.getNextTrackAndRemove(this.shuffle));
if (track != null) {
+ IVoiceChannel voiceChannel = HandieBot.musicPlayer.getVoiceChannel(this.guild);
+ if (!voiceChannel.isConnected()){
+ voiceChannel.join();
+ }
player.startTrack(track, false);
} else {
- player.stopTrack();
+ this.quit();
}
}
@@ -125,8 +135,11 @@ public class TrackScheduler extends AudioEventAdapter {
* If the user wishes to quit, stop the currently played track.
*/
public void quit(){
+ IVoiceChannel voiceChannel = HandieBot.musicPlayer.getVoiceChannel(this.guild);
+ if (voiceChannel.isConnected()){
+ voiceChannel.leave();
+ }
this.player.stopTrack();
- this.player.destroy();
}
@Override
@@ -134,7 +147,7 @@ public class TrackScheduler extends AudioEventAdapter {
log.log(BotLog.TYPE.MUSIC, this.guild, "Started audio track: "+track.getInfo().title);
List channels = this.guild.getChannelsByName(MusicPlayer.CHANNEL_NAME.toLowerCase());
if (channels.size() > 0){
- IMessage message = channels.get(0).sendMessage("Now playing: **"+track.getInfo().title+"**.");
+ IMessage message = channels.get(0).sendMessage("Now playing: **"+track.getInfo().title+"**\n"+track.getInfo().uri);
RequestBuffer.request(() -> {message.addReaction(":thumbsup:");}).get();
RequestBuffer.request(() -> {message.addReaction(":thumbsdown:");});
}
@@ -142,13 +155,10 @@ public class TrackScheduler extends AudioEventAdapter {
@Override
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
- System.out.println("Track ended.");
if (endReason.mayStartNext){
- System.out.println("Moving to next track.");
nextTrack();
} else {
- log.log(BotLog.TYPE.ERROR, this.guild, "Unable to go to the next track. Reason: "+endReason.name());
- System.out.println(endReason.toString());
+ log.log(BotLog.TYPE.MUSIC, this.guild, "Unable to go to the next track. Reason: "+endReason.name());
}
}
diff --git a/src/main/java/handiebot/view/CommandLineListener.java b/src/main/java/handiebot/view/CommandLineListener.java
index 56fcc4c..0179497 100644
--- a/src/main/java/handiebot/view/CommandLineListener.java
+++ b/src/main/java/handiebot/view/CommandLineListener.java
@@ -21,6 +21,7 @@ public class CommandLineListener implements KeyListener {
//user wishes to submit command.
JTextField commandLine = (JTextField) e.getSource();
String[] words = commandLine.getText().trim().split(" ");
+ commandLine.setText(null);
String command = words[0];
String[] args = new String[words.length-1];
for (int i = 1; i < words.length; i++) {
diff --git a/src/main/java/handiebot/view/actions/QuitAction.java b/src/main/java/handiebot/view/actions/QuitAction.java
index 267d522..23d9089 100644
--- a/src/main/java/handiebot/view/actions/QuitAction.java
+++ b/src/main/java/handiebot/view/actions/QuitAction.java
@@ -1,6 +1,7 @@
package handiebot.view.actions;
import handiebot.HandieBot;
+import sx.blah.discord.handle.obj.IGuild;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -10,8 +11,22 @@ import java.awt.event.ActionListener;
*/
public class QuitAction implements ActionListener {
+ private IGuild guild;
+
+ public QuitAction(){
+ }
+
+ public QuitAction(IGuild guild){
+ this.guild = guild;
+ }
+
@Override
public void actionPerformed(ActionEvent e) {
- HandieBot.quit();
+ if (guild != null){
+ HandieBot.musicPlayer.getChatChannel(this.guild).sendMessage("Quiting HandieBot");
+ HandieBot.musicPlayer.quit(this.guild);
+ } else {
+ HandieBot.quit();
+ }
}
}
diff --git a/src/main/java/handiebot/view/actions/music/MusicAction.java b/src/main/java/handiebot/view/actions/music/MusicAction.java
new file mode 100644
index 0000000..14b2e32
--- /dev/null
+++ b/src/main/java/handiebot/view/actions/music/MusicAction.java
@@ -0,0 +1,18 @@
+package handiebot.view.actions.music;
+
+import sx.blah.discord.handle.obj.IGuild;
+
+import java.awt.event.ActionListener;
+
+/**
+ * @author Andrew Lalis
+ */
+public abstract class MusicAction implements ActionListener {
+
+ protected IGuild guild;
+
+ public MusicAction(IGuild guild) {
+ this.guild = guild;
+ }
+
+}
diff --git a/src/main/java/handiebot/view/actions/music/PlayAction.java b/src/main/java/handiebot/view/actions/music/PlayAction.java
new file mode 100644
index 0000000..a0cdc9b
--- /dev/null
+++ b/src/main/java/handiebot/view/actions/music/PlayAction.java
@@ -0,0 +1,32 @@
+package handiebot.view.actions.music;
+
+import handiebot.HandieBot;
+import sx.blah.discord.handle.obj.IGuild;
+
+import java.awt.event.ActionEvent;
+
+/**
+ * @author Andrew Lalis
+ */
+public class PlayAction extends MusicAction {
+
+ private String[] args = null;
+
+ public PlayAction(IGuild guild) {
+ super(guild);
+ }
+
+ public PlayAction(IGuild guild, String[] args){
+ super(guild);
+ this.args = args;
+ }
+
+ @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]);
+ }
+ }
+}
diff --git a/src/main/java/handiebot/view/actions/music/QueueListAction.java b/src/main/java/handiebot/view/actions/music/QueueListAction.java
new file mode 100644
index 0000000..7e53e87
--- /dev/null
+++ b/src/main/java/handiebot/view/actions/music/QueueListAction.java
@@ -0,0 +1,24 @@
+package handiebot.view.actions.music;
+
+import handiebot.HandieBot;
+import sx.blah.discord.handle.obj.IGuild;
+
+import java.awt.event.ActionEvent;
+
+/**
+ * @author Andrew Lalis
+ */
+public class QueueListAction extends MusicAction {
+
+ private boolean showAll = false;
+
+ public QueueListAction(IGuild guild, boolean showAll){
+ super(guild);
+ this.showAll = showAll;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ HandieBot.musicPlayer.showQueueList(this.guild, this.showAll);
+ }
+}
diff --git a/src/main/java/handiebot/view/actions/music/SkipAction.java b/src/main/java/handiebot/view/actions/music/SkipAction.java
new file mode 100644
index 0000000..f7b3b57
--- /dev/null
+++ b/src/main/java/handiebot/view/actions/music/SkipAction.java
@@ -0,0 +1,21 @@
+package handiebot.view.actions.music;
+
+import handiebot.HandieBot;
+import sx.blah.discord.handle.obj.IGuild;
+
+import java.awt.event.ActionEvent;
+
+/**
+ * @author Andrew Lalis
+ */
+public class SkipAction extends MusicAction {
+
+ public SkipAction(IGuild guild) {
+ super(guild);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ HandieBot.musicPlayer.skipTrack(this.guild);
+ }
+}
diff --git a/src/main/java/handiebot/view/actions/music/ToggleRepeatAction.java b/src/main/java/handiebot/view/actions/music/ToggleRepeatAction.java
new file mode 100644
index 0000000..64ded13
--- /dev/null
+++ b/src/main/java/handiebot/view/actions/music/ToggleRepeatAction.java
@@ -0,0 +1,21 @@
+package handiebot.view.actions.music;
+
+import handiebot.HandieBot;
+import sx.blah.discord.handle.obj.IGuild;
+
+import java.awt.event.ActionEvent;
+
+/**
+ * @author Andrew Lalis
+ */
+public class ToggleRepeatAction extends MusicAction {
+
+ public ToggleRepeatAction(IGuild guild) {
+ super(guild);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ HandieBot.musicPlayer.toggleRepeat(this.guild);
+ }
+}