From 5deb41c6511db35af25a6af45162fed928b7181b Mon Sep 17 00:00:00 2001 From: John Grosh Date: Sat, 2 Sep 2017 16:39:08 -0400 Subject: [PATCH] updated libs fixed internal bugs lots of other things (see 0.0.9 release) --- pom.xml | 6 +- src/main/java/com/jagrosh/jmusicbot/Bot.java | 75 ++++++++-- .../java/com/jagrosh/jmusicbot/Config.java | 46 ++++++- .../java/com/jagrosh/jmusicbot/JMusicBot.java | 22 ++- .../jagrosh/jmusicbot/audio/AudioHandler.java | 32 +++-- .../jmusicbot/commands/AutoplaylistCmd.java | 70 ++++++++++ .../jagrosh/jmusicbot/commands/EvalCmd.java | 56 ++++++++ .../jmusicbot/commands/NowplayingCmd.java | 38 +----- .../jagrosh/jmusicbot/commands/PlayCmd.java | 37 ++++- .../jagrosh/jmusicbot/commands/QueueCmd.java | 4 +- .../jmusicbot/commands/SCSearchCmd.java | 13 ++ .../jagrosh/jmusicbot/commands/SearchCmd.java | 13 ++ .../jmusicbot/commands/SetgameCmd.java | 128 +++++++++++------- .../jmusicbot/commands/SetstatusCmd.java | 2 +- .../jagrosh/jmusicbot/playlist/Playlist.java | 29 +++- .../jagrosh/jmusicbot/utils/FormatUtil.java | 77 ++++++++--- 16 files changed, 500 insertions(+), 148 deletions(-) create mode 100644 src/main/java/com/jagrosh/jmusicbot/commands/AutoplaylistCmd.java create mode 100644 src/main/java/com/jagrosh/jmusicbot/commands/EvalCmd.java diff --git a/pom.xml b/pom.xml index 1efc204a6..8fbbf7074 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.jagrosh JMusicBot - 0.0.8 + 0.0.9 jar @@ -23,7 +23,7 @@ net.dv8tion JDA - 3.2.0_242 + 3.2.0_258 com.sedmelluq @@ -33,7 +33,7 @@ com.jagrosh JDA-Utilities - 1.5 + 1.6 org.json diff --git a/src/main/java/com/jagrosh/jmusicbot/Bot.java b/src/main/java/com/jagrosh/jmusicbot/Bot.java index ce22c5861..c08e4248b 100644 --- a/src/main/java/com/jagrosh/jmusicbot/Bot.java +++ b/src/main/java/com/jagrosh/jmusicbot/Bot.java @@ -33,16 +33,21 @@ import com.jagrosh.jmusicbot.audio.AudioHandler; import com.jagrosh.jmusicbot.gui.GUI; import com.jagrosh.jmusicbot.utils.FormatUtil; +import java.util.Objects; +import javafx.util.Pair; import net.dv8tion.jda.core.JDA; import net.dv8tion.jda.core.Permission; import net.dv8tion.jda.core.entities.Game; import net.dv8tion.jda.core.entities.Guild; +import net.dv8tion.jda.core.entities.Message; import net.dv8tion.jda.core.entities.Role; 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.events.message.MessageDeleteEvent; +import net.dv8tion.jda.core.exceptions.PermissionException; import net.dv8tion.jda.core.hooks.ListenerAdapter; import net.dv8tion.jda.core.utils.SimpleLog; import org.json.JSONException; @@ -55,6 +60,7 @@ public class Bot extends ListenerAdapter { private final HashMap settings; + private final HashMap> lastNP; // guild -> channel,message private final AudioPlayerManager manager; private final EventWaiter waiter; private final ScheduledExecutorService threadpool; @@ -91,6 +97,7 @@ public Bot(EventWaiter waiter, Config config) this.config = config; this.waiter = waiter; this.settings = new HashMap<>(); + this.lastNP = new HashMap<>(); manager = new DefaultAudioPlayerManager(); threadpool = Executors.newSingleThreadScheduledExecutor(); AudioSourceManagers.registerRemoteSources(manager); @@ -112,6 +119,11 @@ public Bot(EventWaiter waiter, Config config) } } + public JDA getJDA() + { + return jda; + } + public EventWaiter getWaiter() { return waiter; @@ -143,7 +155,8 @@ public AudioHandler setUpHandler(Guild guild) handler = new AudioHandler(player, guild, this); player.addListener(handler); guild.getAudioManager().setSendingHandler(handler); - threadpool.scheduleWithFixedDelay(() -> updateTopic(guild,handler), 0, 5, TimeUnit.SECONDS); + if(AudioHandler.USE_NP_REFRESH) + threadpool.scheduleWithFixedDelay(() -> updateLastNP(guild.getIdLong()), 0, 5, TimeUnit.SECONDS); } else handler = (AudioHandler)guild.getAudioManager().getSendingHandler(); @@ -152,14 +165,54 @@ public AudioHandler setUpHandler(Guild guild) public void resetGame() { - if(config.getGame()==null || config.getGame().equalsIgnoreCase("none")) - jda.getPresence().setGame(null); - else - jda.getPresence().setGame(Game.of(config.getGame())); + Game game = config.getGame()==null || config.getGame().equalsIgnoreCase("none") ? null : Game.of(config.getGame()); + if(!Objects.equals(jda.getPresence().getGame(), game)) + jda.getPresence().setGame(game); + } + + public void setLastNP(Message m) + { + lastNP.put(m.getGuild().getIdLong(), new Pair<>(m.getTextChannel().getIdLong(), m.getIdLong())); + } + + @Override + public void onMessageDelete(MessageDeleteEvent event) { + if(lastNP.containsKey(event.getGuild().getIdLong())) + { + Pair pair = lastNP.get(event.getGuild().getIdLong()); + if(pair.getValue()==event.getMessageIdLong()) + lastNP.remove(event.getGuild().getIdLong()); + } } - private void updateTopic(Guild guild, AudioHandler handler) + private void updateLastNP(long guildId) { + Guild guild = jda.getGuildById(guildId); + if(guild==null) + return; + if(!lastNP.containsKey(guildId)) + return; + Pair pair = lastNP.get(guildId); + if(pair==null) + return; + TextChannel tc = guild.getTextChannelById(pair.getKey()); + if(tc==null) + { + lastNP.remove(guildId); + return; + } + try { + tc.editMessageById(pair.getValue(), FormatUtil.nowPlayingMessage(guild, config.getSuccess())).queue(m->{}, t -> lastNP.remove(guildId)); + } catch(Exception e) { + lastNP.remove(guildId); + } + } + + public void updateTopic(long guildId, AudioHandler handler) + { + Guild guild = jda.getGuildById(guildId); + if(guild==null) + return; TextChannel tchan = guild.getTextChannelById(getSettings(guild).getTextId()); if(tchan!=null && guild.getSelfMember().hasPermission(tchan, Permission.MANAGE_CHANNEL)) { @@ -167,12 +220,14 @@ private void updateTopic(Guild guild, AudioHandler handler) if(tchan.getTopic()==null || tchan.getTopic().isEmpty()) otherText = "\u200B"; else if(tchan.getTopic().contains("\u200B")) - otherText = tchan.getTopic().substring(tchan.getTopic().indexOf("\u200B")); + otherText = tchan.getTopic().substring(tchan.getTopic().lastIndexOf("\u200B")); else otherText = "\u200B\n "+tchan.getTopic(); - String text = FormatUtil.formattedAudio(handler, guild.getJDA())+otherText; + String text = FormatUtil.topicFormat(handler, guild.getJDA())+otherText; if(!text.equals(tchan.getTopic())) - tchan.getManager().setTopic(text).queue(); + try { + tchan.getManager().setTopic(text).queue(); + } catch(PermissionException e){} } } @@ -186,7 +241,7 @@ public void shutdown(){ { ah.getQueue().clear(); ah.getPlayer().destroy(); - updateTopic(g, ah); + updateTopic(g.getIdLong(), ah); } }); jda.shutdown(); diff --git a/src/main/java/com/jagrosh/jmusicbot/Config.java b/src/main/java/com/jagrosh/jmusicbot/Config.java index a31b37230..7580779fa 100644 --- a/src/main/java/com/jagrosh/jmusicbot/Config.java +++ b/src/main/java/com/jagrosh/jmusicbot/Config.java @@ -15,14 +15,15 @@ */ package com.jagrosh.jmusicbot; -import com.jagrosh.jmusicbot.utils.FormatUtil; import java.io.IOException; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.util.LinkedList; import java.util.List; import java.util.Scanner; import javax.swing.JOptionPane; +import net.dv8tion.jda.core.OnlineStatus; /** * @@ -42,13 +43,17 @@ public class Config { private boolean stay; private boolean dbots; private boolean songingame; + private boolean useEval; + private boolean npimages; + private long maxSeconds; + private OnlineStatus status = OnlineStatus.UNKNOWN; public Config(boolean nogui) { this.nogui = nogui; List lines; try { - lines = Files.readAllLines(Paths.get("config.txt")); + lines = Files.readAllLines(Paths.get("config.txt"), Charset.forName("ISO-8859-1")); System.out.println("[INFO] Loading config: "+Paths.get("config.txt").toFile().getAbsolutePath()); for(String line: lines) { @@ -84,18 +89,29 @@ public Config(boolean nogui) case "help": help = value; break; - case "noprogressintopic": - FormatUtil.NO_PROGRESS_BAR_IN_TOPIC = "true".equalsIgnoreCase(value); - break; case "songinstatus": songingame = "true".equalsIgnoreCase(value); break; case "stayinchannel": stay = "true".equalsIgnoreCase(value); break; + case "eval": + useEval = "true".equalsIgnoreCase(value); + break; case "dbots": dbots = "110373943822540800".equals(value); break; + case "npimages": + npimages = "true".equalsIgnoreCase(value); + break; + case "maxtime": + try{ + maxSeconds = Long.parseLong(value); + }catch(NumberFormatException e){} + break; + case "status": + status = OnlineStatus.fromKey(value); + break; } } } catch (IOException ex) { @@ -216,6 +232,26 @@ public boolean getDBots() return dbots; } + public boolean useEval() + { + return useEval; + } + + public boolean useNPImages() + { + return npimages; + } + + public long getMaxSeconds() + { + return maxSeconds; + } + + public OnlineStatus getStatus() + { + return status; + } + private void alert(String message) { if(nogui) diff --git a/src/main/java/com/jagrosh/jmusicbot/JMusicBot.java b/src/main/java/com/jagrosh/jmusicbot/JMusicBot.java index f53ab3d8b..3d2a584e0 100644 --- a/src/main/java/com/jagrosh/jmusicbot/JMusicBot.java +++ b/src/main/java/com/jagrosh/jmusicbot/JMusicBot.java @@ -58,10 +58,16 @@ public static void main(String[] args){ EventWaiter waiter = new EventWaiter(); Bot bot = new Bot(waiter, config); - AboutCommand.IS_AUTHOR = false; - AboutCommand.REPLACEMENT_ICON = "\uD83C\uDFB6"; + AboutCommand ab = new AboutCommand(Color.BLUE.brighter(), + "a music bot that is [easy to host yourself!](https://github.com/jagrosh/MusicBot) (v0.0.9)", + new String[]{"High-quality music playback", "FairQueue™ Technology", "Easy to host yourself"}, + RECOMMENDED_PERMS); + ab.setIsAuthor(false); + ab.setReplacementCharacter("\uD83C\uDFB6"); AudioHandler.STAY_IN_CHANNEL = config.getStay(); AudioHandler.SONG_IN_STATUS = config.getSongInStatus(); + AudioHandler.MAX_SECONDS = config.getMaxSeconds(); + AudioHandler.USE_NP_REFRESH = !config.useNPImages(); // set up the command client @@ -72,10 +78,7 @@ public static void main(String[] args){ .setEmojis(config.getSuccess(), config.getWarning(), config.getError()) .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.8)", - new String[]{"High-quality music playback", "FairQueue™ Technology", "Easy to host yourself"}, - RECOMMENDED_PERMS), + ab, new PingCommand(), new SettingsCmd(bot), @@ -100,6 +103,7 @@ public static void main(String[] args){ new SetvcCmd(bot), //new GuildlistCommand(waiter), + new AutoplaylistCmd(bot), new PlaylistCmd(bot), new SetavatarCmd(bot), new SetgameCmd(bot), @@ -107,7 +111,11 @@ public static void main(String[] args){ new SetstatusCmd(bot), new ShutdownCmd(bot) ); + if(config.useEval()) + cb.addCommand(new EvalCmd(bot)); boolean nogame = false; + if(config.getStatus()!=OnlineStatus.UNKNOWN) + cb.setStatus(config.getStatus()); if(config.getGame()==null) cb.useDefaultGame(); else if(config.getGame().equalsIgnoreCase("none")) @@ -138,7 +146,7 @@ else if(config.getGame().equalsIgnoreCase("none")) .setToken(config.getToken()) .setAudioEnabled(true) .setGame(nogame ? null : Game.of("loading...")) - .setStatus(OnlineStatus.DO_NOT_DISTURB) + .setStatus(config.getStatus()==OnlineStatus.INVISIBLE||config.getStatus()==OnlineStatus.OFFLINE ? OnlineStatus.INVISIBLE : OnlineStatus.DO_NOT_DISTURB) .addEventListener(client) .addEventListener(waiter) .addEventListener(bot) diff --git a/src/main/java/com/jagrosh/jmusicbot/audio/AudioHandler.java b/src/main/java/com/jagrosh/jmusicbot/audio/AudioHandler.java index 330a1a648..5f4e7e27a 100644 --- a/src/main/java/com/jagrosh/jmusicbot/audio/AudioHandler.java +++ b/src/main/java/com/jagrosh/jmusicbot/audio/AudioHandler.java @@ -38,7 +38,7 @@ */ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler { private final AudioPlayer audioPlayer; - private final Guild guild; + private final long guildId; private final FairQueue queue; private final Set votes; private final List defaultQueue; @@ -47,10 +47,12 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler private long requester; public static boolean STAY_IN_CHANNEL; public static boolean SONG_IN_STATUS; + public static long MAX_SECONDS = -1; + public static boolean USE_NP_REFRESH; public AudioHandler(AudioPlayer audioPlayer, Guild guild, Bot bot) { this.audioPlayer = audioPlayer; - this.guild = guild; + this.guildId = guild.getIdLong(); this.bot = bot; queue = new FairQueue<>(); votes = new HashSet<>(); @@ -59,7 +61,7 @@ public AudioHandler(AudioPlayer audioPlayer, Guild guild, Bot bot) { public int addTrack(AudioTrack track, User user) { - if(requester==0) + if(audioPlayer.getPlayingTrack()==null) { requester = user.getIdLong(); audioPlayer.playTrack(track); @@ -84,7 +86,7 @@ public void stopAndClear() public boolean isMusicPlaying() { - return guild.getSelfMember().getVoiceState().inVoiceChannel() && audioPlayer.getPlayingTrack()!=null; + return bot.getJDA().getGuildById(guildId).getSelfMember().getVoiceState().inVoiceChannel() && audioPlayer.getPlayingTrack()!=null; } public Set getVotes() @@ -109,6 +111,7 @@ public boolean playFromDefault() audioPlayer.playTrack(defaultQueue.remove(0)); return true; } + Guild guild = bot.getJDA().getGuildById(guildId); if(bot.getSettings(guild)==null || bot.getSettings(guild).getDefaultPlaylist()==null) return false; Playlist pl = Playlist.loadPlaylist(bot.getSettings(guild).getDefaultPlaylist()); @@ -133,9 +136,11 @@ public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason { if(!playFromDefault()) { - bot.resetGame(); + if(SONG_IN_STATUS) + bot.resetGame(); if(!STAY_IN_CHANNEL) - guild.getAudioManager().closeAudioConnection(); + bot.getJDA().getGuildById(guildId).getAudioManager().closeAudioConnection(); + bot.updateTopic(guildId, this); } } else @@ -149,10 +154,14 @@ public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason @Override public void onTrackStart(AudioPlayer player, AudioTrack track) { votes.clear(); - if(SONG_IN_STATUS && guild.getJDA().getGuilds().size()==1) + if(SONG_IN_STATUS) { - guild.getJDA().getPresence().setGame(Game.of(track.getInfo().title)); + if(bot.getJDA().getGuilds().stream().filter(g -> g.getSelfMember().getVoiceState().inVoiceChannel()).count()<=1) + bot.getJDA().getPresence().setGame(Game.of(track.getInfo().title)); + else + bot.resetGame(); } + bot.updateTopic(guildId, this); } @Override @@ -170,4 +179,11 @@ public byte[] provide20MsAudio() { public boolean isOpus() { return true; } + + public static boolean isTooLong(AudioTrack track) + { + if(MAX_SECONDS<=0) + return false; + return Math.round(track.getDuration()/1000.0) > MAX_SECONDS; + } } diff --git a/src/main/java/com/jagrosh/jmusicbot/commands/AutoplaylistCmd.java b/src/main/java/com/jagrosh/jmusicbot/commands/AutoplaylistCmd.java new file mode 100644 index 000000000..c107f4ae8 --- /dev/null +++ b/src/main/java/com/jagrosh/jmusicbot/commands/AutoplaylistCmd.java @@ -0,0 +1,70 @@ +/* + * Copyright 2016 John Grosh . + * + * 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.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +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.playlist.Playlist; + +/** + * + * @author John Grosh + */ +public class AutoplaylistCmd extends Command { + + private final Bot bot; + public AutoplaylistCmd(Bot bot) + { + this.bot = bot; + this.category = bot.OWNER; + this.ownerCommand = true; + this.guildOnly = true; + this.name = "autoplaylist"; + this.arguments = ""; + this.help = "sets the default playlist for the server"; + } + + @Override + public void execute(CommandEvent event) { + if(event.getArgs().isEmpty()) + { + event.reply(event.getClient().getError()+" Please include a playlist name or NONE"); + return; + } + if(event.getArgs().equalsIgnoreCase("none")) + { + bot.setDefaultPlaylist(event.getGuild(), null); + event.reply(event.getClient().getSuccess()+" Cleared the default playlist for **"+event.getGuild().getName()+"**"); + return; + } + String pname = event.getArgs().replaceAll("\\s+", "_"); + if(Playlist.loadPlaylist(pname)==null) + { + event.reply(event.getClient().getError()+" Could not find `"+pname+".txt`!"); + } + else + { + bot.setDefaultPlaylist(event.getGuild(), pname); + event.reply(event.getClient().getSuccess()+" The default playlist for **"+event.getGuild().getName()+"** is now `"+pname+"`"); + } + } +} diff --git a/src/main/java/com/jagrosh/jmusicbot/commands/EvalCmd.java b/src/main/java/com/jagrosh/jmusicbot/commands/EvalCmd.java new file mode 100644 index 000000000..bbfaedd32 --- /dev/null +++ b/src/main/java/com/jagrosh/jmusicbot/commands/EvalCmd.java @@ -0,0 +1,56 @@ +/* + * Copyright 2016 John Grosh (jagrosh). + * + * 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 javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import com.jagrosh.jdautilities.commandclient.Command; +import com.jagrosh.jdautilities.commandclient.CommandEvent; +import com.jagrosh.jmusicbot.Bot; + +/** + * + * @author John Grosh (jagrosh) + */ +public class EvalCmd extends Command { + + public EvalCmd(Bot bot) + { + this.name = "eval"; + this.help = "evaluates nashorn code"; + this.ownerCommand = true; + this.guildOnly = false; + this.category = bot.OWNER; + } + + @Override + protected void execute(CommandEvent event) { + ScriptEngine se = new ScriptEngineManager().getEngineByName("Nashorn"); + se.put("event", event); + se.put("jda", event.getJDA()); + se.put("guild", event.getGuild()); + se.put("channel", event.getChannel()); + try + { + event.reply(event.getClient().getSuccess()+" Evaluated Successfully:\n```\n"+se.eval(event.getArgs())+" ```"); + } + catch(Exception e) + { + event.reply(event.getClient().getError()+" An exception was thrown:\n```\n"+e+" ```"); + } + } + +} diff --git a/src/main/java/com/jagrosh/jmusicbot/commands/NowplayingCmd.java b/src/main/java/com/jagrosh/jmusicbot/commands/NowplayingCmd.java index ebe401b59..47ad0ad2d 100644 --- a/src/main/java/com/jagrosh/jmusicbot/commands/NowplayingCmd.java +++ b/src/main/java/com/jagrosh/jmusicbot/commands/NowplayingCmd.java @@ -17,12 +17,8 @@ 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.youtube.YoutubeAudioTrack; -import net.dv8tion.jda.core.EmbedBuilder; import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.entities.User; /** * @@ -41,39 +37,7 @@ public NowplayingCmd(Bot bot) @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.getRequester()!=0) - { - User u = event.getJDA().getUserById(ah.getRequester()); - if(u==null) - eb.setAuthor("Unknown (ID:"+ah.getRequester()+")", null, null); - else - eb.setAuthor(u.getName()+"#"+u.getDiscriminator(), null, u.getEffectiveAvatarUrl()); - } - - try { - eb.setTitle(ah.getPlayer().getPlayingTrack().getInfo().title, ah.getPlayer().getPlayingTrack().getInfo().uri); - } catch(Exception e) { - eb.setTitle(ah.getPlayer().getPlayingTrack().getInfo().title); - } - - if(ah.getPlayer().getPlayingTrack() instanceof YoutubeAudioTrack) - eb.setThumbnail("https://img.youtube.com/vi/"+ah.getPlayer().getPlayingTrack().getIdentifier()+"/maxresdefault.jpg"); - - eb.setDescription(FormatUtil.embedformattedAudio(ah)); - - event.reply(eb.build()); + event.reply(FormatUtil.nowPlayingMessage(event.getGuild(), event.getClient().getSuccess()), m->bot.setLastNP(m)); } } diff --git a/src/main/java/com/jagrosh/jmusicbot/commands/PlayCmd.java b/src/main/java/com/jagrosh/jmusicbot/commands/PlayCmd.java index 9e14a3dd5..251adf762 100644 --- a/src/main/java/com/jagrosh/jmusicbot/commands/PlayCmd.java +++ b/src/main/java/com/jagrosh/jmusicbot/commands/PlayCmd.java @@ -54,6 +54,8 @@ public void doCommand(CommandEvent event) { if(handler!=null && handler.getPlayer().getPlayingTrack()!=null && handler.getPlayer().isPaused()) { boolean isDJ = event.getMember().hasPermission(Permission.MANAGE_SERVER); + if(!isDJ) + isDJ = event.isOwner() || event.isCoOwner(); if(!isDJ) isDJ = event.getMember().getRoles().contains(event.getGuild().getRoleById(bot.getSettings(event.getGuild()).getRoleId())); if(!isDJ) @@ -94,6 +96,12 @@ private ResultHandler(Message m, CommandEvent event, boolean ytsearch) @Override public void trackLoaded(AudioTrack track) { + if(AudioHandler.isTooLong(track)) + { + m.editMessage(event.getClient().getWarning()+" This track (**"+track.getInfo().title+"**) is longer than the allowed maximum: `" + +FormatUtil.formatTime(track.getDuration())+"` > `"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`").queue(); + return; + } int pos = bot.queueTrack(event, track)+1; m.editMessage(event.getClient().getSuccess()+" Added **"+track.getInfo().title +"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0 ? "to begin playing" @@ -105,6 +113,12 @@ public void playlistLoaded(AudioPlaylist playlist) { if(playlist.getTracks().size()==1 || playlist.isSearchResult() || playlist.getSelectedTrack()!=null) { AudioTrack single = playlist.getSelectedTrack()==null?playlist.getTracks().get(0):playlist.getSelectedTrack(); + if(AudioHandler.isTooLong(single)) + { + m.editMessage(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(event.getClient().getSuccess()+" Added **"+single.getInfo().title +"** (`"+FormatUtil.formatTime(single.getDuration())+"`) "+(pos==0 ? "to begin playing" @@ -112,12 +126,27 @@ public void playlistLoaded(AudioPlaylist playlist) { } else { - m.editMessage(event.getClient().getSuccess()+" Found " - +(playlist.getName()==null?"a playlist":"playlist **"+playlist.getName()+"**")+" with `" - +playlist.getTracks().size()+"` entries; added to the queue!").queue(); + int[] count = {0}; playlist.getTracks().stream().forEach((track) -> { - bot.queueTrack(event, track); + if(!AudioHandler.isTooLong(track)) + { + bot.queueTrack(event, track); + count[0]++; + } }); + if(count[0]==0) + { + m.editMessage(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(); + } + else + { + m.editMessage(event.getClient().getSuccess()+" Found " + +(playlist.getName()==null?"a playlist":"playlist **"+playlist.getName()+"**")+" with `" + + playlist.getTracks().size()+"` entries; added to the queue!" + + (count[0] `"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`").queue(); + return; + } int pos = bot.queueTrack(event, track)+1; m.editMessage(event.getClient().getSuccess()+" Added **"+track.getInfo().title +"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0 ? "to begin playing" @@ -88,6 +95,12 @@ public void playlistLoaded(AudioPlaylist playlist) { .setChoices(new String[0]) .setAction(i -> { AudioTrack track = playlist.getTracks().get(i-1); + if(AudioHandler.isTooLong(track)) + { + event.getChannel().sendMessage(event.getClient().getWarning()+" This track (**"+track.getInfo().title+"**) is longer than the allowed maximum: `" + +FormatUtil.formatTime(track.getDuration())+"` > `"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`").queue(); + return; + } int pos = bot.queueTrack(event, track)+1; event.getChannel().sendMessage(event.getClient().getSuccess()+" Added **"+track.getInfo().title +"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0 ? "to begin playing" diff --git a/src/main/java/com/jagrosh/jmusicbot/commands/SearchCmd.java b/src/main/java/com/jagrosh/jmusicbot/commands/SearchCmd.java index f93d17808..ffb356838 100644 --- a/src/main/java/com/jagrosh/jmusicbot/commands/SearchCmd.java +++ b/src/main/java/com/jagrosh/jmusicbot/commands/SearchCmd.java @@ -24,6 +24,7 @@ import com.jagrosh.jdautilities.commandclient.CommandEvent; import com.jagrosh.jdautilities.menu.orderedmenu.OrderedMenuBuilder; import com.jagrosh.jmusicbot.Bot; +import com.jagrosh.jmusicbot.audio.AudioHandler; import com.jagrosh.jmusicbot.utils.FormatUtil; import net.dv8tion.jda.core.Permission; import net.dv8tion.jda.core.entities.Message; @@ -76,6 +77,12 @@ private ResultHandler(Message m, CommandEvent event) @Override public void trackLoaded(AudioTrack track) { + if(AudioHandler.isTooLong(track)) + { + m.editMessage(event.getClient().getWarning()+" This track (**"+track.getInfo().title+"**) is longer than the allowed maximum: `" + +FormatUtil.formatTime(track.getDuration())+"` > `"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`").queue(); + return; + } int pos = bot.queueTrack(event, track)+1; m.editMessage(event.getClient().getSuccess()+" Added **"+track.getInfo().title +"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0 ? "to begin playing" @@ -89,6 +96,12 @@ public void playlistLoaded(AudioPlaylist playlist) { .setChoices(new String[0]) .setAction(i -> { AudioTrack track = playlist.getTracks().get(i-1); + if(AudioHandler.isTooLong(track)) + { + event.getChannel().sendMessage(event.getClient().getWarning()+" This track (**"+track.getInfo().title+"**) is longer than the allowed maximum: `" + +FormatUtil.formatTime(track.getDuration())+"` > `"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`").queue(); + return; + } int pos = bot.queueTrack(event, track)+1; event.getChannel().sendMessage(event.getClient().getSuccess()+" Added **"+track.getInfo().title +"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0 ? "to begin playing" diff --git a/src/main/java/com/jagrosh/jmusicbot/commands/SetgameCmd.java b/src/main/java/com/jagrosh/jmusicbot/commands/SetgameCmd.java index cee416df0..66ffa317e 100644 --- a/src/main/java/com/jagrosh/jmusicbot/commands/SetgameCmd.java +++ b/src/main/java/com/jagrosh/jmusicbot/commands/SetgameCmd.java @@ -1,49 +1,79 @@ -/* - * Copyright 2017 John Grosh . - * - * 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; -import net.dv8tion.jda.core.entities.Game; - -/** - * - * @author John Grosh - */ -public class SetgameCmd extends Command { - - public SetgameCmd(Bot bot) - { - this.name = "setgame"; - this.help = "sets the game the bot is playing"; - this.arguments = "[game]"; - this.ownerCommand = true; - this.category = bot.OWNER; - } - - @Override - protected void execute(CommandEvent event) { - try { - event.getJDA().getPresence().setGame(event.getArgs().isEmpty() ? null : Game.of(event.getArgs())); - event.reply(event.getClient().getSuccess()+" **"+event.getSelfUser().getName() - +"** is "+(event.getArgs().isEmpty() ? "no longer playing anything." : "now playing `"+event.getArgs()+"`")); - } catch(Exception e) { - event.reply(event.getClient().getError()+" The game could not be set!"); - } - } - -} +/* + * Copyright 2017 John Grosh . + * + * 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; +import net.dv8tion.jda.core.entities.Game; + +/** + * + * @author John Grosh + */ +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 "; + this.ownerCommand = true; + this.category = bot.OWNER; + this.children = new Command[]{new SetstreamCmd(bot)}; + } + + @Override + protected void execute(CommandEvent event) { + try { + event.getJDA().getPresence().setGame(event.getArgs().isEmpty() ? null : Game.of(event.getArgs())); + event.reply(event.getClient().getSuccess()+" **"+event.getSelfUser().getName() + +"** is "+(event.getArgs().isEmpty() ? "no longer playing anything." : "now playing `"+event.getArgs()+"`")); + } catch(Exception e) { + event.reply(event.getClient().getError()+" The game could not be set!"); + } + } + + private class SetstreamCmd extends Command { + + private SetstreamCmd(Bot bot) + { + this.name = "stream"; + this.aliases = new String[]{"twitch","streaming"}; + this.help = "sets the game the bot is playing to a stream"; + this.arguments = " "; + this.ownerCommand = true; + this.category = bot.OWNER; + } + + @Override + 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])); + event.replySuccess("**"+event.getSelfUser().getName() + +"** is now streaming `"+parts[1]+"`"); + } catch(Exception e) { + event.reply(event.getClient().getError()+" The game could not be set!"); + } + } + } +} diff --git a/src/main/java/com/jagrosh/jmusicbot/commands/SetstatusCmd.java b/src/main/java/com/jagrosh/jmusicbot/commands/SetstatusCmd.java index ed72d00e6..fc065fd62 100644 --- a/src/main/java/com/jagrosh/jmusicbot/commands/SetstatusCmd.java +++ b/src/main/java/com/jagrosh/jmusicbot/commands/SetstatusCmd.java @@ -30,7 +30,7 @@ public SetstatusCmd(Bot bot) { this.name = "setstatus"; this.help = "sets the status the bot displays"; - this.arguments = "[game]"; + this.arguments = ""; this.ownerCommand = true; this.category = bot.OWNER; } diff --git a/src/main/java/com/jagrosh/jmusicbot/playlist/Playlist.java b/src/main/java/com/jagrosh/jmusicbot/playlist/Playlist.java index a26a2cfc6..c08f738c5 100644 --- a/src/main/java/com/jagrosh/jmusicbot/playlist/Playlist.java +++ b/src/main/java/com/jagrosh/jmusicbot/playlist/Playlist.java @@ -6,6 +6,7 @@ package com.jagrosh.jmusicbot.playlist; import com.jagrosh.jmusicbot.Bot; +import com.jagrosh.jmusicbot.audio.AudioHandler; import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler; import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; import com.sedmelluq.discord.lavaplayer.tools.FriendlyException; @@ -54,8 +55,13 @@ public void loadTracks(AudioPlayerManager manager, Consumer consumer manager.loadItemOrdered(name, items.get(i), new AudioLoadResultHandler() { @Override public void trackLoaded(AudioTrack at) { - tracks.add(at); - consumer.accept(at); + if(AudioHandler.isTooLong(at)) + errors.add(new PlaylistLoadError(index, items.get(index), "This track is longer than the allowed maximum")); + else + { + tracks.add(at); + consumer.accept(at); + } if(last) { if(callback!=null) @@ -66,13 +72,23 @@ public void trackLoaded(AudioTrack at) { public void playlistLoaded(AudioPlaylist ap) { if(ap.isSearchResult()) { - tracks.add(ap.getTracks().get(0)); - consumer.accept(ap.getTracks().get(0)); + if(AudioHandler.isTooLong(ap.getTracks().get(0))) + errors.add(new PlaylistLoadError(index, items.get(index), "This track is longer than the allowed maximum")); + else + { + 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()); + if(AudioHandler.isTooLong(ap.getSelectedTrack())) + errors.add(new PlaylistLoadError(index, items.get(index), "This track is longer than the allowed maximum")); + else + { + tracks.add(ap.getSelectedTrack()); + consumer.accept(ap.getSelectedTrack()); + } } else { @@ -85,6 +101,7 @@ else if(ap.getSelectedTrack()!=null) loaded.set(first, loaded.get(second)); loaded.set(second, tmp); } + loaded.removeIf(track -> AudioHandler.isTooLong(track)); tracks.addAll(loaded); loaded.forEach(at -> consumer.accept(at)); } diff --git a/src/main/java/com/jagrosh/jmusicbot/utils/FormatUtil.java b/src/main/java/com/jagrosh/jmusicbot/utils/FormatUtil.java index 4047b7c4c..4f3d185c0 100644 --- a/src/main/java/com/jagrosh/jmusicbot/utils/FormatUtil.java +++ b/src/main/java/com/jagrosh/jmusicbot/utils/FormatUtil.java @@ -18,7 +18,12 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrack; import java.util.List; import com.jagrosh.jmusicbot.audio.AudioHandler; +import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack; +import net.dv8tion.jda.core.EmbedBuilder; import net.dv8tion.jda.core.JDA; +import net.dv8tion.jda.core.MessageBuilder; +import net.dv8tion.jda.core.entities.Guild; +import net.dv8tion.jda.core.entities.Message; import net.dv8tion.jda.core.entities.Role; import net.dv8tion.jda.core.entities.TextChannel; import net.dv8tion.jda.core.entities.User; @@ -30,8 +35,6 @@ */ public class FormatUtil { - public static boolean NO_PROGRESS_BAR_IN_TOPIC = false; - public static String formatTime(long duration) { if(duration == Long.MAX_VALUE) @@ -44,7 +47,44 @@ public static String formatTime(long duration) return (hours>0 ? hours+":" : "") + (minutes<10 ? "0"+minutes : minutes) + ":" + (seconds<10 ? "0"+seconds : seconds); } - public static String formattedAudio(AudioHandler handler, JDA jda) + public static Message nowPlayingMessage(Guild guild, String successEmoji) + { + MessageBuilder mb = new MessageBuilder(); + mb.append(successEmoji+" **Now Playing...**"); + EmbedBuilder eb = new EmbedBuilder(); + AudioHandler ah = (AudioHandler)guild.getAudioManager().getSendingHandler(); + eb.setColor(guild.getSelfMember().getColor()); + if(ah==null || !ah.isMusicPlaying()) + { + eb.setTitle("No music playing"); + eb.setDescription("\u23F9 "+FormatUtil.progressBar(-1)+" "+FormatUtil.volumeIcon(ah==null?100:ah.getPlayer().getVolume())); + } + else + { + if(ah.getRequester()!=0) + { + User u = guild.getJDA().getUserById(ah.getRequester()); + if(u==null) + eb.setAuthor("Unknown (ID:"+ah.getRequester()+")", null, null); + else + eb.setAuthor(u.getName()+"#"+u.getDiscriminator(), null, u.getEffectiveAvatarUrl()); + } + + try { + eb.setTitle(ah.getPlayer().getPlayingTrack().getInfo().title, ah.getPlayer().getPlayingTrack().getInfo().uri); + } catch(Exception e) { + eb.setTitle(ah.getPlayer().getPlayingTrack().getInfo().title); + } + + if(!AudioHandler.USE_NP_REFRESH && ah.getPlayer().getPlayingTrack() instanceof YoutubeAudioTrack) + eb.setThumbnail("https://img.youtube.com/vi/"+ah.getPlayer().getPlayingTrack().getIdentifier()+"/mqdefault.jpg"); + + eb.setDescription(FormatUtil.embedFormat(ah)); + } + return mb.setEmbed(eb.build()).build(); + } + + public static String topicFormat(AudioHandler handler, JDA jda) { if(handler==null) return "No music playing\n\u23F9 "+progressBar(-1)+" "+volumeIcon(100); @@ -55,25 +95,30 @@ else if (!handler.isMusicPlaying()) long userid = handler.getRequester(); AudioTrack track = handler.getPlayer().getPlayingTrack(); String title = track.getInfo().title; - if(!NO_PROGRESS_BAR_IN_TOPIC && title.length()>30) - title = title.substring(0,27)+"..."; - double progress = (double)track.getPosition()/track.getDuration(); - String str = "**"+title+"** ["+(userid==0 ? "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())+"] ") + return "**"+title+"** ["+(userid==0 ? "autoplay" : "<@"+userid+">")+"]" + + "\n"+(handler.getPlayer().isPaused()?"\u23F8":"\u25B6")+" " + +"["+formatTime(track.getDuration())+"] " +volumeIcon(handler.getPlayer().getVolume()); - return str+str2; } } - public static String embedformattedAudio(AudioHandler ah) + public static String embedFormat(AudioHandler handler) { - return (ah.getPlayer().isPaused()?"\u23F8":"\u25B6")+" "+progressBar((double)ah.getPlayer().getPlayingTrack().getPosition()/ah.getPlayer().getPlayingTrack().getDuration()) - +" `["+formatTime(ah.getPlayer().getPlayingTrack().getPosition()) + "/" + formatTime(ah.getPlayer().getPlayingTrack().getDuration()) +"]` " - +volumeIcon(ah.getPlayer().getVolume()); + if(handler==null) + return "No music playing\n\u23F9 "+progressBar(-1)+" "+volumeIcon(100); + else if (!handler.isMusicPlaying()) + return "No music playing\n\u23F9 "+progressBar(-1)+" "+volumeIcon(handler.getPlayer().getVolume()); + else + { + AudioTrack track = handler.getPlayer().getPlayingTrack(); + double progress = (double)track.getPosition()/track.getDuration(); + return (handler.getPlayer().isPaused()?"\u23F8":"\u25B6") + +" "+progressBar(progress) + +" `["+formatTime(track.getPosition()) + "/" + formatTime(track.getDuration()) +"]` " + +volumeIcon(handler.getPlayer().getVolume()); + } } - + public static String progressBar(double percent) { String str = "";