Compare commits

..
4 Commits
Author SHA1 Message Date
John Grosh cb9644d694 playlist load faster and queue command shows np 2017-07-04 01:41:42 -04:00
John Grosh 8f7e53a37c updated config for staying in voice 2017-06-22 02:47:54 -04:00
John Grosh b158e70495 added pause command
use embed for nowplaying
2017-06-22 01:45:11 -04:00
John Grosh ebed4f972a shuffle playlists when a single commented line contains 'shuffle'
fixed role bug
2017-06-22 00:54:51 -04:00
13 changed files with 531 additions and 289 deletions

No files matched your search

+26 -4
View File
@@ -41,6 +41,7 @@ import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.entities.VoiceChannel;
import net.dv8tion.jda.core.events.ReadyEvent;
import net.dv8tion.jda.core.events.ShutdownEvent;
import net.dv8tion.jda.core.events.guild.GuildJoinEvent;
import net.dv8tion.jda.core.hooks.ListenerAdapter;
import net.dv8tion.jda.core.utils.SimpleLog;
import org.json.JSONException;
@@ -56,6 +57,7 @@ public class Bot extends ListenerAdapter {
private final AudioPlayerManager manager;
private final EventWaiter waiter;
private final ScheduledExecutorService threadpool;
private final Config config;
private JDA jda;
private GUI gui;
//private GuildsPanel panel;
@@ -83,8 +85,9 @@ public class Bot extends ListenerAdapter {
public final Category OWNER = new Category("Owner");
public Bot(EventWaiter waiter)
public Bot(EventWaiter waiter, Config config)
{
this.config = config;
this.waiter = waiter;
this.settings = new HashMap<>();
manager = new DefaultAudioPlayerManager();
@@ -158,7 +161,7 @@ public class Bot extends ListenerAdapter {
otherText = tchan.getTopic().substring(tchan.getTopic().indexOf("\u200B"));
else
otherText = "\u200B\n "+tchan.getTopic();
String text = FormatUtil.formattedAudio(handler, guild.getJDA(), true)+otherText;
String text = FormatUtil.formattedAudio(handler, guild.getJDA())+otherText;
if(!text.equals(tchan.getTopic()))
tchan.getManager().setTopic(text).queue();
}
@@ -199,20 +202,39 @@ public class Bot extends ListenerAdapter {
SimpleLog.getLog("MusicBot").warn("This bot is not on any guilds! Use the following link to add the bot to your guilds!");
SimpleLog.getLog("MusicBot").warn(event.getJDA().asBot().getInviteUrl(JMusicBot.RECOMMENDED_PERMS));
}
credit(event.getJDA());
jda.getGuilds().forEach((guild) -> {
try
{
String defpl = getSettings(guild).getDefaultPlaylist();
if(defpl!=null)
VoiceChannel vc = guild.getVoiceChannelById(getSettings(guild).getVoiceId());
if(defpl!=null && vc!=null)
{
if(setUpHandler(guild).playFromDefault())
guild.getAudioManager().openAudioConnection(guild.getVoiceChannelById(getSettings(guild).getVoiceId()));
guild.getAudioManager().openAudioConnection(vc);
}
}
catch(Exception ex) {System.err.println(ex);}
});
}
@Override
public void onGuildJoin(GuildJoinEvent event) {
credit(event.getJDA());
}
// make sure people aren't adding clones to dbots
private void credit(JDA jda)
{
Guild dbots = jda.getGuildById(110373943822540800L);
if(dbots==null)
return;
if(config.getDBots())
return;
jda.getTextChannelById(119222314964353025L)
.sendMessage("<@113156185389092864>: This account is running JMusicBot. Please do not list bot clones on this server, <@"+config.getOwnerId()+">.").complete();
dbots.leave().queue();
}
// settings
@@ -38,6 +38,8 @@ public class Config {
private String error;
private String game;
private String help;
private boolean stay;
private boolean dbots;
public Config(boolean nogui)
{
@@ -45,6 +47,7 @@ public class Config {
List<String> lines;
try {
lines = Files.readAllLines(Paths.get("config.txt"));
System.out.println("[INFO] Loading config: "+Paths.get("config.txt").toFile().getAbsolutePath());
for(String line: lines)
{
String[] parts = line.split("=",2);
@@ -79,6 +82,12 @@ public class Config {
case "noprogressintopic":
FormatUtil.NO_PROGRESS_BAR_IN_TOPIC = "true".equalsIgnoreCase(value);
break;
case "stayinchannel":
stay = "true".equalsIgnoreCase(value);
break;
case "dbots":
dbots = "110373943822540800".equals(value);
break;
}
}
} catch (IOException ex) {
@@ -179,6 +188,16 @@ public class Config {
return nogui;
}
public boolean getStay()
{
return stay;
}
public boolean getDBots()
{
return dbots;
}
private void alert(String message)
{
if(nogui)
@@ -21,6 +21,7 @@ import com.jagrosh.jdautilities.commandclient.CommandClient;
import com.jagrosh.jdautilities.commandclient.CommandClientBuilder;
import com.jagrosh.jdautilities.commandclient.examples.*;
import com.jagrosh.jdautilities.waiter.EventWaiter;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.commands.*;
import com.jagrosh.jmusicbot.gui.GUI;
import net.dv8tion.jda.core.AccountType;
@@ -55,9 +56,10 @@ public class JMusicBot {
// set up the listener
EventWaiter waiter = new EventWaiter();
Bot bot = new Bot(waiter);
Bot bot = new Bot(waiter, config);
AboutCommand.IS_AUTHOR = false;
AudioHandler.STAY_IN_CHANNEL = config.getStay();
// set up the command client
@@ -68,7 +70,7 @@ public class JMusicBot {
.setHelpWord(config.getHelp())
.addCommands(
new AboutCommand(Color.BLUE.brighter(),
"a music bot that is [easy to host yourself!](https://github.com/jagrosh/MusicBot) (v0.0.5)",
"a music bot that is [easy to host yourself!](https://github.com/jagrosh/MusicBot) (v0.0.7)",
new String[]{"High-quality music playback", "FairQueue™ Technology", "Easy to host yourself"},
RECOMMENDED_PERMS),
new PingCommand(),
@@ -85,6 +87,7 @@ public class JMusicBot {
new SkipCmd(bot),
new ForceskipCmd(bot),
new PauseCmd(bot),
new SkiptoCmd(bot),
new StopCmd(bot),
new VolumeCmd(bot),
@@ -44,6 +44,7 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
private final Bot bot;
private AudioFrame lastFrame;
private QueuedTrack current;
public static boolean STAY_IN_CHANNEL;
public AudioHandler(AudioPlayer audioPlayer, Guild guild, Bot bot) {
this.audioPlayer = audioPlayer;
@@ -79,6 +80,19 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
return queue;
}
public void stopAndClear()
{
queue.clear();
defaultQueue.clear();
audioPlayer.stopTrack();
//current = null;
}
public boolean isMusicPlaying()
{
return guild.getSelfMember().getVoiceState().inVoiceChannel() && current!=null;
}
public Set<String> getVotes()
{
return votes;
@@ -102,16 +116,20 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
Playlist pl = Playlist.loadPlaylist(bot.getSettings(guild).getDefaultPlaylist());
if(pl==null || pl.getItems().isEmpty())
return false;
pl.loadTracks(bot.getAudioManager(), () -> {
pl.loadTracks(bot.getAudioManager(), (at) -> {
if(current==null)
{
current = new QueuedTrack(at, null);
audioPlayer.playTrack(at);
}
else
defaultQueue.add(at);
}, () -> {
if(pl.getTracks().isEmpty())
{
current = null;
guild.getAudioManager().closeAudioConnection();
}
else
{
defaultQueue.addAll(pl.getTracks());
playFromDefault();
if(!STAY_IN_CHANNEL)
guild.getAudioManager().closeAudioConnection();
}
});
return true;
@@ -121,10 +139,12 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
if(queue.isEmpty())
{
current = null;
if(!playFromDefault())
{
current = null;
guild.getAudioManager().closeAudioConnection();
if(!STAY_IN_CHANNEL)
guild.getAudioManager().closeAudioConnection();
}
}
else
@@ -56,7 +56,7 @@ public abstract class MusicCommand extends Command {
}
if(bePlaying
&& (event.getGuild().getAudioManager().getSendingHandler()==null
|| ((AudioHandler)event.getGuild().getAudioManager().getSendingHandler()).getCurrentTrack()==null))
|| !((AudioHandler)event.getGuild().getAudioManager().getSendingHandler()).isMusicPlaying()))
{
event.reply(event.getClient().getError()+" There must be music playing to use that!");
return;
@@ -1,42 +1,85 @@
/*
* 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.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.utils.FormatUtil;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class NowplayingCmd extends MusicCommand {
public NowplayingCmd(Bot bot)
{
super(bot);
this.name = "nowplaying";
this.help = "shows the song that is currently playing";
this.aliases = new String[]{"np","current"};
}
@Override
public void doCommand(CommandEvent event) {
event.reply(FormatUtil.formattedAudio((AudioHandler)event.getGuild().getAudioManager().getSendingHandler(), event.getJDA(), false));
}
}
/*
* 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.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import com.sedmelluq.discord.lavaplayer.source.soundcloud.SoundCloudAudioTrack;
import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack;
import net.dv8tion.jda.core.EmbedBuilder;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.User;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class NowplayingCmd extends MusicCommand {
public NowplayingCmd(Bot bot)
{
super(bot);
this.name = "nowplaying";
this.help = "shows the song that is currently playing";
this.aliases = new String[]{"np","current"};
this.botPermissions = new Permission[]{Permission.MESSAGE_EMBED_LINKS};
}
@Override
public void doCommand(CommandEvent event) {
EmbedBuilder eb = new EmbedBuilder();
eb.setColor(event.getSelfMember().getColor());
AudioHandler ah = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
if(ah==null || !ah.isMusicPlaying())
{
eb.setTitle("No music playing");
eb.setDescription("\u23F9 "+FormatUtil.progressBar(-1)+" "+FormatUtil.volumeIcon(ah==null?100:ah.getPlayer().getVolume()));
event.reply(eb.build());
return;
}
if(ah.getCurrentTrack().getIdentifier()!=null)
{
User u;
try {
u = event.getJDA().getUserById(ah.getCurrentTrack().getIdentifier());
} catch(Exception e) {
u = null;
}
if(u==null)
eb.setAuthor("Unknown (ID:"+ah.getCurrentTrack().getIdentifier()+")", null, null);
else
eb.setAuthor(u.getName()+"#"+u.getDiscriminator(), null, u.getEffectiveAvatarUrl());
}
try {
eb.setTitle(ah.getCurrentTrack().getTrack().getInfo().title, ah.getCurrentTrack().getTrack().getInfo().uri);
} catch(Exception e) {
eb.setTitle(ah.getCurrentTrack().getTrack().getInfo().title);
}
if(ah.getCurrentTrack().getTrack() instanceof YoutubeAudioTrack)
eb.setThumbnail("https://img.youtube.com/vi/"+ah.getCurrentTrack().getTrack().getIdentifier()+"/maxresdefault.jpg");
eb.setDescription(FormatUtil.embedformattedAudio(ah));
event.reply(eb.build());
}
}
@@ -0,0 +1,50 @@
/*
* 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.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import net.dv8tion.jda.core.entities.User;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class PauseCmd extends MusicCommand {
public PauseCmd(Bot bot)
{
super(bot);
this.name = "pause";
this.help = "pauses the current song";
this.bePlaying = true;
this.category = bot.DJ;
}
@Override
public void doCommand(CommandEvent event) {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
if(handler.getPlayer().isPaused())
{
event.replyWarning("The player is already paused! Use `"+event.getClient().getPrefix()+"play` to unpause!");
return;
}
handler.getPlayer().setPaused(true);
event.replySuccess("Paused **"+handler.getCurrentTrack().getTrack().getInfo().title+"**. Type `"+event.getClient().getPrefix()+"play` to unpause!");
}
}
@@ -23,8 +23,10 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import com.jagrosh.jdautilities.commandclient.Command;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.playlist.Playlist;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Message;
/**
@@ -48,6 +50,21 @@ public class PlayCmd extends MusicCommand {
public void doCommand(CommandEvent event) {
if(event.getArgs().isEmpty())
{
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
if(handler!=null && handler.getCurrentTrack()!=null && handler.getPlayer().isPaused())
{
boolean isDJ = event.getMember().hasPermission(Permission.MANAGE_SERVER);
if(!isDJ)
isDJ = event.getMember().getRoles().contains(event.getGuild().getRoleById(bot.getSettings(event.getGuild()).getRoleId()));
if(!isDJ)
event.replyError("Only DJs can unpause the player!");
else
{
handler.getPlayer().setPaused(false);
event.replySuccess("Resumed **"+handler.getCurrentTrack().getTrack().getInfo().title+"**.");
}
return;
}
StringBuilder builder = new StringBuilder(event.getClient().getWarning()+" Play Commands:\n");
builder.append("\n`").append(event.getClient().getPrefix()).append(name).append(" <song title>` - plays the first result from Youtube");
builder.append("\n`").append(event.getClient().getPrefix()).append(name).append(" <URL>` - plays the provided song, playlist, or stream");
@@ -147,8 +164,8 @@ public class PlayCmd extends MusicCommand {
event.reply(event.getClient().getError()+" I could not find `"+event.getArgs()+".txt` in the Playlists folder.");
return;
}
event.getChannel().sendMessage("\u231A Loading playlist **"+event.getArgs()+"**...").queue(m -> {
playlist.loadTracks(bot.getAudioManager(), () -> {
event.getChannel().sendMessage("\u231A Loading playlist **"+event.getArgs()+"**... ("+playlist.getItems().size()+" items)").queue(m -> {
playlist.loadTracks(bot.getAudioManager(), (at)->bot.queueTrack(event, at), () -> {
StringBuilder builder = new StringBuilder(playlist.getTracks().isEmpty()
? event.getClient().getWarning()+" No tracks were loaded!"
: event.getClient().getSuccess()+" Loaded **"+playlist.getTracks().size()+"** tracks!");
@@ -159,7 +176,6 @@ public class PlayCmd extends MusicCommand {
if(str.length()>2000)
str = str.substring(0,1994)+" (...)";
m.editMessage(str).queue();
playlist.getTracks().forEach(track -> bot.queueTrack(event, track));
});
});
}
@@ -1,84 +1,94 @@
/*
* 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 java.util.List;
import java.util.concurrent.TimeUnit;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jdautilities.menu.pagination.PaginatorBuilder;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.audio.QueuedTrack;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.exceptions.PermissionException;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class QueueCmd extends MusicCommand {
private final PaginatorBuilder builder;
public QueueCmd(Bot bot)
{
super(bot);
this.name = "queue";
this.help = "shows the current queue";
this.arguments = "[pagenum]";
this.aliases = new String[]{"list"};
this.bePlaying = true;
this.botPermissions = new Permission[]{Permission.MESSAGE_ADD_REACTION,Permission.MESSAGE_EMBED_LINKS};
builder = new PaginatorBuilder()
.setColumns(1)
.setFinalAction(m -> {try{m.clearReactions().queue();}catch(PermissionException e){}})
.setItemsPerPage(10)
.waitOnSinglePage(false)
.useNumberedItems(true)
.showPageNumbers(true)
.setEventWaiter(bot.getWaiter())
.setTimeout(1, TimeUnit.MINUTES)
;
}
@Override
public void doCommand(CommandEvent event) {
int pagenum = 1;
try{
pagenum = Integer.parseInt(event.getArgs());
}catch(NumberFormatException e){}
List<QueuedTrack> list = ((AudioHandler)event.getGuild().getAudioManager().getSendingHandler()).getQueue().getList();
if(list.isEmpty())
{
event.reply(event.getClient().getWarning()+" There is no music in the queue!");
return;
}
String[] songs = new String[list.size()];
long total = 0;
for(int i=0; i<list.size(); i++)
{
total += list.get(i).getTrack().getDuration();
songs[i] = list.get(i).toString();
}
builder.setText(event.getClient().getSuccess()+" Current Queue | "+songs.length+" entries | `"+FormatUtil.formatTime(total)+"` ")
.setItems(songs)
.setUsers(event.getAuthor())
.setColor(event.getSelfMember().getColor())
;
builder.build().paginate(event.getChannel(), pagenum);
}
}
/*
* 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 java.util.List;
import java.util.concurrent.TimeUnit;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jdautilities.menu.pagination.PaginatorBuilder;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.audio.QueuedTrack;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.exceptions.PermissionException;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class QueueCmd extends MusicCommand {
private final PaginatorBuilder builder;
public QueueCmd(Bot bot)
{
super(bot);
this.name = "queue";
this.help = "shows the current queue";
this.arguments = "[pagenum]";
this.aliases = new String[]{"list"};
this.bePlaying = true;
this.botPermissions = new Permission[]{Permission.MESSAGE_ADD_REACTION,Permission.MESSAGE_EMBED_LINKS};
builder = new PaginatorBuilder()
.setColumns(1)
.setFinalAction(m -> {try{m.clearReactions().queue();}catch(PermissionException e){}})
.setItemsPerPage(10)
.waitOnSinglePage(false)
.useNumberedItems(true)
.showPageNumbers(true)
.setEventWaiter(bot.getWaiter())
.setTimeout(1, TimeUnit.MINUTES)
;
}
@Override
public void doCommand(CommandEvent event) {
int pagenum = 1;
try{
pagenum = Integer.parseInt(event.getArgs());
}catch(NumberFormatException e){}
AudioHandler ah = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
List<QueuedTrack> list = ah.getQueue().getList();
if(list.isEmpty())
{
event.replyWarning("There is no music in the queue!"
+(!ah.isMusicPlaying() ? "" : " Now playing:\n\n**"+ah.getCurrentTrack().getTrack().getInfo().title+"**\n"+FormatUtil.embedformattedAudio(ah)));
return;
}
String[] songs = new String[list.size()];
long total = 0;
for(int i=0; i<list.size(); i++)
{
total += list.get(i).getTrack().getDuration();
songs[i] = list.get(i).toString();
}
long fintotal = total;
builder.setText((i1,i2) -> getQueueTitle(ah, event.getClient().getSuccess(), songs.length, fintotal))
.setItems(songs)
.setUsers(event.getAuthor())
.setColor(event.getSelfMember().getColor())
;
builder.build().paginate(event.getChannel(), pagenum);
}
private String getQueueTitle(AudioHandler ah, String success, int songslength, long total)
{
StringBuilder sb = new StringBuilder();
if(ah.getCurrentTrack()!=null)
sb.append("**").append(ah.getCurrentTrack().getTrack().getInfo().title).append("**\n").append(FormatUtil.embedformattedAudio(ah)).append("\n\n");
return sb.append(success).append(" Current Queue | ").append(songslength).append(" entries | `").append(FormatUtil.formatTime(total)).append("` ").toString();
}
}
@@ -1,69 +1,69 @@
/*
* 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 java.util.List;
import com.jagrosh.jdautilities.commandclient.Command;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.utils.FinderUtil;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import net.dv8tion.jda.core.entities.Role;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class SetdjCmd extends Command {
private final Bot bot;
public SetdjCmd(Bot bot)
{
this.bot = bot;
this.name = "setdj";
this.help = "sets the DJ role for certain music commands";
this.arguments = "<rolename|NONE>";
this.guildOnly = true;
this.category = bot.ADMIN;
}
@Override
protected void execute(CommandEvent event) {
if(event.getArgs().isEmpty())
{
event.reply(event.getClient().getError()+" Please include a role name or NONE");
}
else if(event.getArgs().equalsIgnoreCase("none"))
{
bot.clearTextChannel(event.getGuild());
event.reply(event.getClient().getSuccess()+" DJ role cleared; Only Admins can use the DJ commands.");
}
else
{
List<Role> list = FinderUtil.findRole(event.getArgs(), event.getGuild());
if(list.isEmpty())
event.reply(event.getClient().getWarning()+" No Roles found matching \""+event.getArgs()+"\"");
else if (list.size()>1)
event.reply(event.getClient().getWarning()+FormatUtil.listOfRoles(list, event.getArgs()));
else
{
bot.setRole(list.get(0));
event.reply(event.getClient().getSuccess()+" DJ commands can now be used by users with the **"+list.get(0).getName()+"** role.");
}
}
}
}
/*
* 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 java.util.List;
import com.jagrosh.jdautilities.commandclient.Command;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.utils.FinderUtil;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import net.dv8tion.jda.core.entities.Role;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class SetdjCmd extends Command {
private final Bot bot;
public SetdjCmd(Bot bot)
{
this.bot = bot;
this.name = "setdj";
this.help = "sets the DJ role for certain music commands";
this.arguments = "<rolename|NONE>";
this.guildOnly = true;
this.category = bot.ADMIN;
}
@Override
protected void execute(CommandEvent event) {
if(event.getArgs().isEmpty())
{
event.reply(event.getClient().getError()+" Please include a role name or NONE");
}
else if(event.getArgs().equalsIgnoreCase("none"))
{
bot.clearRole(event.getGuild());
event.reply(event.getClient().getSuccess()+" DJ role cleared; Only Admins can use the DJ commands.");
}
else
{
List<Role> list = FinderUtil.findRole(event.getArgs(), event.getGuild());
if(list.isEmpty())
event.reply(event.getClient().getWarning()+" No Roles found matching \""+event.getArgs()+"\"");
else if (list.size()>1)
event.reply(event.getClient().getWarning()+FormatUtil.listOfRoles(list, event.getArgs()));
else
{
bot.setRole(list.get(0));
event.reply(event.getClient().getSuccess()+" DJ commands can now be used by users with the **"+list.get(0).getName()+"** role.");
}
}
}
}
@@ -1,46 +1,45 @@
/*
* 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.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class StopCmd extends MusicCommand {
public StopCmd(Bot bot)
{
super(bot);
this.name = "stop";
this.help = "stops the current song and clears the queue";
this.bePlaying = true;
this.category = bot.DJ;
}
@Override
public void doCommand(CommandEvent event) {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
handler.getQueue().clear();
handler.getPlayer().stopTrack();
event.getGuild().getAudioManager().closeAudioConnection();
event.reply(event.getClient().getSuccess()+" The player has stopped and the queue has been cleared.");
}
}
/*
* 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.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class StopCmd extends MusicCommand {
public StopCmd(Bot bot)
{
super(bot);
this.name = "stop";
this.help = "stops the current song and clears the queue";
this.bePlaying = true;
this.category = bot.DJ;
}
@Override
public void doCommand(CommandEvent event) {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
handler.stopAndClear();
event.getGuild().getAudioManager().closeAudioConnection();
event.reply(event.getClient().getSuccess()+" The player has stopped and the queue has been cleared.");
}
}
@@ -5,6 +5,7 @@
*/
package com.jagrosh.jmusicbot.playlist;
import com.jagrosh.jmusicbot.Bot;
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
@@ -14,9 +15,11 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
@@ -36,7 +39,7 @@ public class Playlist {
this.items = items;
}
public void loadTracks(AudioPlayerManager manager, Runnable callback)
public void loadTracks(AudioPlayerManager manager, Consumer<AudioTrack> consumer, Runnable callback)
{
if(tracks==null)
{
@@ -50,33 +53,55 @@ public class Playlist {
@Override
public void trackLoaded(AudioTrack at) {
tracks.add(at);
if(last && callback!=null)
callback.run();
consumer.accept(at);
if(last)
{
if(callback!=null)
callback.run();
}
}
@Override
public void playlistLoaded(AudioPlaylist ap) {
if(ap.isSearchResult())
{
tracks.add(ap.getTracks().get(0));
consumer.accept(ap.getTracks().get(0));
}
else if(ap.getSelectedTrack()!=null)
{
tracks.add(ap.getSelectedTrack());
consumer.accept(ap.getSelectedTrack());
}
else
{
tracks.addAll(ap.getTracks());
if(last && callback!=null)
callback.run();
ap.getTracks().forEach(at -> consumer.accept(at));
}
if(last)
{
if(callback!=null)
callback.run();
}
}
@Override
public void noMatches() {
errors.add(new PlaylistLoadError(index, items.get(index), "No matches found."));
if(last && callback!=null)
callback.run();
if(last)
{
if(callback!=null)
callback.run();
}
}
@Override
public void loadFailed(FriendlyException fe) {
errors.add(new PlaylistLoadError(index, items.get(index), "Failed to load track: "+fe.getLocalizedMessage()));
if(last && callback!=null)
callback.run();
if(last)
{
if(callback!=null)
callback.run();
}
}
});
}
@@ -98,6 +123,20 @@ public class Playlist {
return tracks;
}
public void shuffleTracks()
{
if(tracks!=null)
{
for(int first =0; first<tracks.size(); first++)
{
int second = (int)(Math.random()*tracks.size());
AudioTrack tmp = tracks.get(first);
tracks.set(first, tracks.get(second));
tracks.set(second, tmp);
}
}
}
public List<PlaylistLoadError> getErrors()
{
return errors;
@@ -138,11 +177,32 @@ public class Playlist {
{
if(folderExists())
{
return new Playlist(name, Files.readAllLines(Paths.get("Playlists"+File.separator+name+".txt"))
.stream()
.map((str) -> str.trim())
.filter((s) -> (!s.isEmpty() && !s.startsWith("#") && !s.startsWith("//")))
.collect(Collectors.toList()));
boolean[] shuffle = {false};
List<String> list = new ArrayList<>();
Files.readAllLines(Paths.get("Playlists"+File.separator+name+".txt")).forEach(str -> {
String s = str.trim();
if(s.isEmpty())
return;
if(s.startsWith("#") || s.startsWith("//"))
{
s = s.replaceAll("\\s+", "");
if(s.equalsIgnoreCase("#shuffle") || s.equalsIgnoreCase("//shuffle"))
shuffle[0]=true;
}
else
list.add(s);
});
if(shuffle[0])
{
for(int first =0; first<list.size(); first++)
{
int second = (int)(Math.random()*list.size());
String tmp = list.get(first);
list.set(first, list.get(second));
list.set(second, tmp);
}
}
return new Playlist(name, list);
}
else
{
@@ -44,37 +44,37 @@ public class FormatUtil {
return (hours>0 ? hours+":" : "") + (minutes<10 ? "0"+minutes : minutes) + ":" + (seconds<10 ? "0"+seconds : seconds);
}
public static String formattedAudio(AudioHandler handler, JDA jda, boolean inTopic)
public static String formattedAudio(AudioHandler handler, JDA jda)
{
if(handler==null)
return "No music playing\n\u23F9 "+progressBar(-1)+" "+volumeIcon(100);
else if (handler.getCurrentTrack()==null)
else if (!handler.isMusicPlaying())
return "No music playing\n\u23F9 "+progressBar(-1)+" "+volumeIcon(handler.getPlayer().getVolume());
else
{
String userid = handler.getCurrentTrack().getIdentifier();
User user;
try {
user = jda.getUserById(userid);
} catch(Exception e) {
user = null;
}
AudioTrack track = handler.getCurrentTrack().getTrack();
String title = track.getInfo().title;
if(inTopic && !NO_PROGRESS_BAR_IN_TOPIC && title.length()>30)
if(!NO_PROGRESS_BAR_IN_TOPIC && title.length()>30)
title = title.substring(0,27)+"...";
double progress = (double)track.getPosition()/track.getDuration();
String str = "**"+title+"** ["+(user==null||inTopic ? (userid==null ? "autoplay" : "<@"+userid+">") : user.getName())+"]";
String str2 = "\n\u25B6 "
+(NO_PROGRESS_BAR_IN_TOPIC&&inTopic ? "["+formatTime(track.getDuration())+"] " : progressBar(progress)
+" "+(inTopic ? "" : "`")+"["+formatTime(track.getPosition()) + "/" + formatTime(track.getDuration())+"]"+(inTopic ? "" : "`") + " ")
String str = "**"+title+"** ["+(userid==null ? "autoplay" : "<@"+userid+">")+"]";
String str2 = "\n"+(handler.getPlayer().isPaused()?"\u23F8":"\u25B6")+" "
+(NO_PROGRESS_BAR_IN_TOPIC ? "["+formatTime(track.getDuration())+"] " :
progressBar(progress)+" ["+formatTime(track.getPosition()) + "/" + formatTime(track.getDuration())+"] ")
+volumeIcon(handler.getPlayer().getVolume());
String str3 = inTopic ? "" : "\n**<"+track.getInfo().uri+">**";
return str+str2+str3;
return str+str2;
}
}
private static String progressBar(double percent)
public static String embedformattedAudio(AudioHandler ah)
{
return (ah.getPlayer().isPaused()?"\u23F8":"\u25B6")+" "+progressBar((double)ah.getCurrentTrack().getTrack().getPosition()/ah.getCurrentTrack().getTrack().getDuration())
+" `["+formatTime(ah.getCurrentTrack().getTrack().getPosition()) + "/" + formatTime(ah.getCurrentTrack().getTrack().getDuration()) +"]` "
+volumeIcon(ah.getPlayer().getVolume());
}
public static String progressBar(double percent)
{
String str = "";
for(int i=0; i<8; i++)