Version 1: Basic functionality #1
9
pom.xml
9
pom.xml
|
@ -21,6 +21,10 @@
|
|||
</build>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<pastebin4j.version>1.1.0</pastebin4j.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jcenter</id>
|
||||
|
@ -43,6 +47,11 @@
|
|||
<artifactId>lavaplayer</artifactId>
|
||||
<version>1.2.39</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kennedyoliveira</groupId>
|
||||
<artifactId>pastebin4j</artifactId>
|
||||
<version>${pastebin4j.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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<IChannel> 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<IVoiceChannel> channels = guild.getVoiceChannelsByName(CHANNEL_NAME);
|
||||
if (channels.isEmpty()){
|
||||
|
@ -119,11 +120,12 @@ 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<AudioTrack> 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) {
|
||||
EmbedBuilder builder = new EmbedBuilder();
|
||||
builder.withColor(255, 0, 0);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -145,6 +147,29 @@ public class MusicPlayer {
|
|||
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);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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<IChannel> 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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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) {
|
||||
if (guild != null){
|
||||
HandieBot.musicPlayer.getChatChannel(this.guild).sendMessage("Quiting HandieBot");
|
||||
HandieBot.musicPlayer.quit(this.guild);
|
||||
} else {
|
||||
HandieBot.quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue