updated deps

updated logger
added repeat mode
added loading playlist from video
added more game types
stop command improved
This commit is contained in:
John Grosh
2017-12-18 10:33:08 -05:00
parent fbbb7bd3a7
commit 6148dc6a89
15 changed files with 354 additions and 100 deletions
@@ -22,19 +22,24 @@ import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import com.jagrosh.jdautilities.commandclient.Command;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jdautilities.waiter.EventWaiter;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.playlist.Playlist;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import java.util.concurrent.TimeUnit;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Emote;
import net.dv8tion.jda.core.entities.Message;
import net.dv8tion.jda.core.events.message.react.MessageReactionAddEvent;
import net.dv8tion.jda.core.exceptions.PermissionException;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class PlayCmd extends MusicCommand {
public class PlayCmd extends MusicCommand
{
public PlayCmd(Bot bot)
{
super(bot);
@@ -81,10 +86,12 @@ public class PlayCmd extends MusicCommand {
event.reply("\u231A Loading... `["+args+"]`", m -> bot.getAudioManager().loadItemOrdered(event.getGuild(), args, new ResultHandler(m,event,false)));
}
private class ResultHandler implements AudioLoadResultHandler {
private class ResultHandler implements AudioLoadResultHandler
{
final Message m;
final CommandEvent event;
final boolean ytsearch;
private ResultHandler(Message m, CommandEvent event, boolean ytsearch)
{
this.m = m;
@@ -92,8 +99,8 @@ public class PlayCmd extends MusicCommand {
this.ytsearch = ytsearch;
}
@Override
public void trackLoaded(AudioTrack track) {
private void loadSingle(AudioTrack track, AudioPlaylist playlist)
{
if(AudioHandler.isTooLong(track))
{
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" This track (**"+track.getInfo().title+"**) is longer than the allowed maximum: `"
@@ -101,38 +108,68 @@ public class PlayCmd extends MusicCommand {
return;
}
int pos = bot.queueTrack(event, track)+1;
m.editMessage(FormatUtil.filter(event.getClient().getSuccess()+" Added **"+track.getInfo().title
+"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0 ? "to begin playing"
: " to the queue at position "+pos))).queue();
String addMsg = FormatUtil.filter(event.getClient().getSuccess()+" Added **"+track.getInfo().title
+"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0?"to begin playing":" to the queue at position "+pos));
if(playlist==null)
m.editMessage(addMsg).queue();
else
{
m.editMessage(addMsg+"\n"+event.getClient().getWarning()+" This track has a playlist of **"+playlist.getTracks().size()+"** tracks attached. Load playlist?")
.queue(m ->
{
Emote emote = event.getJDA().getEmoteById(event.getClient().getSuccess().replaceAll("<:.+:(\\d+)>", "$1"));
if(emote == null)
m.addReaction(event.getClient().getSuccess()).queue();
else
m.addReaction(emote).queue();
bot.getWaiter().waitForEvent(MessageReactionAddEvent.class,
e -> e.getMessageIdLong()==m.getIdLong() && e.getUser().getIdLong()==event.getAuthor().getIdLong(),
e ->
{
m.editMessage(addMsg+"\n"+event.getClient().getSuccess()+" Loaded **"+loadPlaylist(playlist, track)+"** additional tracks!").queue();
try{m.clearReactions().queue();}catch(PermissionException ex){}
},
2, TimeUnit.MINUTES, () -> {try{m.clearReactions().queue();}catch(PermissionException e){}});
});
}
}
private int loadPlaylist(AudioPlaylist playlist, AudioTrack exclude)
{
int[] count = {0};
playlist.getTracks().stream().forEach((track) -> {
if(!AudioHandler.isTooLong(track) && !track.equals(exclude))
{
bot.queueTrack(event, track);
count[0]++;
}
});
return count[0];
}
@Override
public void trackLoaded(AudioTrack track)
{
loadSingle(track, null);
}
@Override
public void playlistLoaded(AudioPlaylist playlist) {
if(playlist.getTracks().size()==1 || playlist.isSearchResult() || playlist.getSelectedTrack()!=null)
public void playlistLoaded(AudioPlaylist playlist)
{
if(playlist.getTracks().size()==1 || playlist.isSearchResult())
{
AudioTrack single = playlist.getSelectedTrack()==null?playlist.getTracks().get(0):playlist.getSelectedTrack();
if(AudioHandler.isTooLong(single))
{
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" This track (**"+single.getInfo().title+"**) is longer than the allowed maximum: `"
+FormatUtil.formatTime(single.getDuration())+"` > `"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`")).queue();
return;
}
int pos = bot.queueTrack(event, single)+1;
m.editMessage(FormatUtil.filter(event.getClient().getSuccess()+" Added **"+single.getInfo().title
+"** (`"+FormatUtil.formatTime(single.getDuration())+"`) "+(pos==0 ? "to begin playing"
: " to the queue at position "+pos))).queue();
AudioTrack single = playlist.getSelectedTrack()==null ? playlist.getTracks().get(0) : playlist.getSelectedTrack();
loadSingle(single, null);
}
else if (playlist.getSelectedTrack()!=null)
{
AudioTrack single = playlist.getSelectedTrack();
loadSingle(single, playlist);
}
else
{
int[] count = {0};
playlist.getTracks().stream().forEach((track) -> {
if(!AudioHandler.isTooLong(track))
{
bot.queueTrack(event, track);
count[0]++;
}
});
if(count[0]==0)
int count = loadPlaylist(playlist, null);
if(count==0)
{
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" All entries in this playlist "+(playlist.getName()==null ? "" : "(**"+playlist.getName()
+"**) ")+"were longer than the allowed maximum (`"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`)")).queue();
@@ -142,14 +179,15 @@ public class PlayCmd extends MusicCommand {
m.editMessage(FormatUtil.filter(event.getClient().getSuccess()+" Found "
+(playlist.getName()==null?"a playlist":"playlist **"+playlist.getName()+"**")+" with `"
+ playlist.getTracks().size()+"` entries; added to the queue!"
+ (count[0]<playlist.getTracks().size() ? "\n"+event.getClient().getWarning()+" Tracks longer than the allowed maximum (`"
+ (count<playlist.getTracks().size() ? "\n"+event.getClient().getWarning()+" Tracks longer than the allowed maximum (`"
+ FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`) have been omitted." : ""))).queue();
}
}
}
@Override
public void noMatches() {
public void noMatches()
{
if(ytsearch)
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" No results found for `"+event.getArgs()+"`.")).queue();
else
@@ -157,7 +195,8 @@ public class PlayCmd extends MusicCommand {
}
@Override
public void loadFailed(FriendlyException throwable) {
public void loadFailed(FriendlyException throwable)
{
if(throwable.severity==Severity.COMMON)
m.editMessage(event.getClient().getError()+" Error loading: "+throwable.getMessage()).queue();
else
@@ -50,12 +50,12 @@ public class QueueCmd extends MusicCommand {
.useNumberedItems(true)
.showPageNumbers(true)
.setEventWaiter(bot.getWaiter())
.setTimeout(1, TimeUnit.MINUTES)
;
.setTimeout(1, TimeUnit.MINUTES);
}
@Override
public void doCommand(CommandEvent event) {
public void doCommand(CommandEvent event)
{
int pagenum = 1;
try{
pagenum = Integer.parseInt(event.getArgs());
@@ -76,7 +76,7 @@ public class QueueCmd extends MusicCommand {
songs[i] = list.get(i).toString();
}
long fintotal = total;
builder.setText((i1,i2) -> getQueueTitle(ah, event.getClient().getSuccess(), songs.length, fintotal))
builder.setText((i1,i2) -> getQueueTitle(ah, event.getClient().getSuccess(), songs.length, fintotal, bot.getSettings(event.getGuild()).getRepeatMode()))
.setItems(songs)
.setUsers(event.getAuthor())
.setColor(event.getSelfMember().getColor())
@@ -84,11 +84,13 @@ public class QueueCmd extends MusicCommand {
builder.build().paginate(event.getChannel(), pagenum);
}
private String getQueueTitle(AudioHandler ah, String success, int songslength, long total)
private String getQueueTitle(AudioHandler ah, String success, int songslength, long total, boolean repeatmode)
{
StringBuilder sb = new StringBuilder();
if(ah.getPlayer().getPlayingTrack()!=null)
sb.append("**").append(ah.getPlayer().getPlayingTrack().getInfo().title).append("**\n").append(FormatUtil.embedFormat(ah)).append("\n\n");
return FormatUtil.filter(sb.append(success).append(" Current Queue | ").append(songslength).append(" entries | `").append(FormatUtil.formatTime(total)).append("` ").toString());
return FormatUtil.filter(sb.append(success).append(" Current Queue | ").append(songslength)
.append(" entries | `").append(FormatUtil.formatTime(total)).append("` ")
.append(repeatmode ? "| \uD83D\uDD01" : "").toString());
}
}
@@ -44,16 +44,16 @@ public class RemoveCmd extends MusicCommand {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
if(handler.getQueue().isEmpty())
{
event.reply(event.getClient().getError()+" There is nothing in the queue!");
event.replyError("There is nothing in the queue!");
return;
}
if(event.getArgs().equalsIgnoreCase("all"))
{
int count = handler.getQueue().removeAll(event.getAuthor().getIdLong());
if(count==0)
event.reply(event.getClient().getWarning()+" You don't have any songs in the queue!");
event.replyWarning("You don't have any songs in the queue!");
else
event.reply(event.getClient().getSuccess()+" Successfully removed your "+count+" entries.");
event.replySuccess("Successfully removed your "+count+" entries.");
return;
}
int pos;
@@ -64,7 +64,7 @@ public class RemoveCmd extends MusicCommand {
}
if(pos<1 || pos>handler.getQueue().size())
{
event.reply(event.getClient().getError()+" Position must be a valid integer between 1 and "+handler.getQueue().size()+"!");
event.replyError("Position must be a valid integer between 1 and "+handler.getQueue().size()+"!");
return;
}
boolean isDJ = event.getMember().hasPermission(Permission.MANAGE_SERVER);
@@ -74,7 +74,7 @@ public class RemoveCmd extends MusicCommand {
if(qt.getIdentifier()==event.getAuthor().getIdLong())
{
handler.getQueue().remove(pos-1);
event.reply(event.getClient().getSuccess()+" Removed **"+qt.getTrack().getInfo().title+"** from the queue");
event.replySuccess("Removed **"+qt.getTrack().getInfo().title+"** from the queue");
}
else if(isDJ)
{
@@ -85,12 +85,12 @@ public class RemoveCmd extends MusicCommand {
} catch(Exception e) {
u = null;
}
event.reply(event.getClient().getSuccess()+" Removed **"+qt.getTrack().getInfo().title
event.replySuccess("Removed **"+qt.getTrack().getInfo().title
+"** from the queue (requested by "+(u==null ? "someone" : "**"+u.getName()+"**")+")");
}
else
{
event.reply(event.getClient().getError()+" You cannot remove **"+qt.getTrack().getInfo().title+"** because you didn't add it!");
event.replyError("You cannot remove **"+qt.getTrack().getInfo().title+"** because you didn't add it!");
}
}
@@ -0,0 +1,63 @@
/*
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jagrosh.jmusicbot.commands;
import com.jagrosh.jdautilities.commandclient.Command;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class RepeatCmd extends Command {
private final Bot bot;
public RepeatCmd(Bot bot)
{
this.bot = bot;
this.name = "repeat";
this.help = "re-adds music to the queue when finished";
this.arguments = "[on|off]";
this.guildOnly = true;
this.category = bot.DJ;
}
@Override
protected void execute(CommandEvent event) {
boolean value;
if(event.getArgs().isEmpty())
{
value = !bot.getSettings(event.getGuild()).getRepeatMode();
}
else if(event.getArgs().equalsIgnoreCase("true") || event.getArgs().equalsIgnoreCase("on"))
{
value = true;
}
else if(event.getArgs().equalsIgnoreCase("false") || event.getArgs().equalsIgnoreCase("off"))
{
value = false;
}
else
{
event.replyError("Valid options are `on` or `off` (or leave empty to toggle)");
return;
}
bot.setRepeatMode(event.getGuild(), value);
event.replySuccess("Repeat mode is now `"+(value ? "ON" : "OFF")+"`");
}
}
@@ -24,31 +24,39 @@ import net.dv8tion.jda.core.entities.Game;
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class SetgameCmd extends Command {
public class SetgameCmd extends Command
{
public SetgameCmd(Bot bot)
{
this.name = "setgame";
this.help = "sets the game the bot is playing";
this.arguments = "[game] OR stream <username> <game>";
this.arguments = "[action] [game]";
this.ownerCommand = true;
this.category = bot.OWNER;
this.children = new Command[]{new SetstreamCmd(bot)};
this.children = new Command[]{
new SetlistenCmd(bot),
new SetstreamCmd(bot),
new SetwatchCmd(bot)
};
}
@Override
protected void execute(CommandEvent event) {
try {
event.getJDA().getPresence().setGame(event.getArgs().isEmpty() ? null : Game.of(event.getArgs()));
String title = event.getArgs().toLowerCase().startsWith("playing") ? event.getArgs().substring(7).trim() : event.getArgs();
try
{
event.getJDA().getPresence().setGame(title.isEmpty() ? null : Game.playing(title));
event.reply(event.getClient().getSuccess()+" **"+event.getSelfUser().getName()
+"** is "+(event.getArgs().isEmpty() ? "no longer playing anything." : "now playing `"+event.getArgs()+"`"));
} catch(Exception e) {
+"** is "+(title.isEmpty() ? "no longer playing anything." : "now playing `"+title+"`"));
}
catch(Exception e)
{
event.reply(event.getClient().getError()+" The game could not be set!");
}
}
private class SetstreamCmd extends Command {
private class SetstreamCmd extends Command
{
private SetstreamCmd(Bot bot)
{
this.name = "stream";
@@ -60,17 +68,83 @@ public class SetgameCmd extends Command {
}
@Override
protected void execute(CommandEvent event) {
protected void execute(CommandEvent event)
{
String[] parts = event.getArgs().split("\\s+", 2);
if(parts.length<2)
{
event.replyError("Please include a twitch username and the name of the game to 'stream'");
return;
}
try {
event.getJDA().getPresence().setGame(Game.of(parts[1], "https://twitch.tv/"+parts[0]));
try
{
event.getJDA().getPresence().setGame(Game.streaming(parts[1], "https://twitch.tv/"+parts[0]));
event.replySuccess("**"+event.getSelfUser().getName()
+"** is now streaming `"+parts[1]+"`");
}
catch(Exception e)
{
event.reply(event.getClient().getError()+" The game could not be set!");
}
}
}
private class SetlistenCmd extends Command
{
private SetlistenCmd(Bot bot)
{
this.name = "listen";
this.aliases = new String[]{"listening"};
this.help = "sets the game the bot is listening to";
this.arguments = "<title>";
this.ownerCommand = true;
this.category = bot.OWNER;
}
@Override
protected void execute(CommandEvent event)
{
if(event.getArgs().isEmpty())
{
event.replyError("Please include a title to listen to!");
return;
}
String title = event.getArgs().toLowerCase().startsWith("to") ? event.getArgs().substring(2).trim() : event.getArgs();
try
{
event.getJDA().getPresence().setGame(Game.listening(title));
event.replySuccess("**"+event.getSelfUser().getName()+"** is now listening to `"+title+"`");
} catch(Exception e) {
event.reply(event.getClient().getError()+" The game could not be set!");
}
}
}
private class SetwatchCmd extends Command
{
private SetwatchCmd(Bot bot)
{
this.name = "watch";
this.aliases = new String[]{"watching"};
this.help = "sets the game the bot is watching";
this.arguments = "<title>";
this.ownerCommand = true;
this.category = bot.OWNER;
}
@Override
protected void execute(CommandEvent event)
{
if(event.getArgs().isEmpty())
{
event.replyError("Please include a title to watch!");
return;
}
String title = event.getArgs();
try
{
event.getJDA().getPresence().setGame(Game.watching(title));
event.replySuccess("**"+event.getSelfUser().getName()+"** is now watching `"+title+"`");
} catch(Exception e) {
event.reply(event.getClient().getError()+" The game could not be set!");
}
@@ -56,6 +56,7 @@ public class SettingsCmd extends Command {
.setDescription("Text Channel: "+(tchan==null ? "Any" : "**#"+tchan.getName()+"**")
+ "\nVoice Channel: "+(vchan==null ? "Any" : "**"+vchan.getName()+"**")
+ "\nDJ Role: "+(role==null ? "None" : "**"+role.getName()+"**")
+ "\nRepeat Mode: **"+(s.getRepeatMode() ? "On" : "Off")+"**"
+ "\nDefault Playlist: "+(s.getDefaultPlaylist()==null ? "None" : "**"+s.getDefaultPlaylist()+"**")
)
.setFooter(event.getJDA().getGuilds().size()+" servers | "
@@ -30,14 +30,15 @@ public class StopCmd extends MusicCommand {
super(bot);
this.name = "stop";
this.help = "stops the current song and clears the queue";
this.bePlaying = true;
this.bePlaying = false;
this.category = bot.DJ;
}
@Override
public void doCommand(CommandEvent event) {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
handler.stopAndClear();
if(handler!=null)
handler.stopAndClear();
event.getGuild().getAudioManager().closeAudioConnection();
event.reply(event.getClient().getSuccess()+" The player has stopped and the queue has been cleared.");
}