From bca2921e67f89d374f347d03149dfa1edcaa8673 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Sun, 2 Jul 2017 10:10:15 +0200 Subject: [PATCH] Added sub-command permissions, fixed spam for downvoting, changed repeat and shuffle to admin only, and some few fixes. --- src/main/java/handiebot/command/Commands.java | 18 +++++++++++++ .../handiebot/command/ReactionHandler.java | 11 ++++---- .../command/commands/misc/TengwarCommand.java | 12 ++++----- .../command/commands/music/PlayCommand.java | 2 +- .../commands/music/PlaylistCommand.java | 4 +-- .../command/commands/music/QueueCommand.java | 21 ++++++++++------ .../command/commands/music/RepeatCommand.java | 11 +++++--- .../commands/music/ShuffleCommand.java | 11 +++++--- .../handiebot/lavaplayer/MusicPlayer.java | 25 +++++++++++++++++-- .../handiebot/lavaplayer/TrackScheduler.java | 6 +++++ src/main/resources/Strings.properties | 14 +++++++---- src/main/resources/Strings_nl.properties | 2 ++ 12 files changed, 100 insertions(+), 37 deletions(-) diff --git a/src/main/java/handiebot/command/Commands.java b/src/main/java/handiebot/command/Commands.java index 19fa53f..ca23377 100644 --- a/src/main/java/handiebot/command/Commands.java +++ b/src/main/java/handiebot/command/Commands.java @@ -10,6 +10,7 @@ import handiebot.command.types.Command; import handiebot.command.types.ContextCommand; import handiebot.command.types.StaticCommand; import handiebot.view.BotLog; +import sx.blah.discord.handle.obj.Permissions; import java.text.MessageFormat; import java.util.ArrayList; @@ -87,4 +88,21 @@ public class Commands { return null; } + /** + * Static function to easily check to see if the user has a specified permissions value. + * @param context The command context. + * @param permission The permission integer to check for. + * @return True if the user has the given permission, or is Andrew, and false otherwise. + */ + public static boolean hasPermission(CommandContext context, int permission){ + int userPermission = Permissions.generatePermissionsNumber(context.getUser().getPermissionsForGuild(context.getGuild())); + boolean result = ((userPermission & permission) > 0) || + (context.getUser().getLongID() == 235439851263098880L) || + (permission == 0); + if (!result){ + context.getChannel().sendMessage(resourceBundle.getString("commands.noPermission.subcommand")); + } + return result; + } + } diff --git a/src/main/java/handiebot/command/ReactionHandler.java b/src/main/java/handiebot/command/ReactionHandler.java index 204882a..6e7bde2 100644 --- a/src/main/java/handiebot/command/ReactionHandler.java +++ b/src/main/java/handiebot/command/ReactionHandler.java @@ -16,7 +16,7 @@ import static handiebot.HandieBot.log; * Class which handles user reactions to songs and performs necessary actions. */ public class ReactionHandler { -//TODO: Fix so only reactions on the most recent song count! + public static final String thumbsUp = "\uD83D\uDC4D"; public static final String thumbsDown = "\uD83D\uDC4E"; @@ -42,12 +42,15 @@ public class ReactionHandler { */ private static void onDownvote(CommandContext context, IMessage message){ //Filter out reactions to previous messages. - if (!message.getContent().contains(HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.getPlayingTrack().getTitle())){ + if (message.getLongID() != HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.getPlayMessageId()){ return; } List usersHere = HandieBot.musicPlayer.getVoiceChannel(context.getGuild()).getConnectedUsers(); //Remove the bot from the list of users in the voice channel. - usersHere.removeIf(user -> user.getLongID() == HandieBot.client.getOurUser().getLongID()); + usersHere.removeIf(user -> (user.getLongID() == HandieBot.client.getOurUser().getLongID()) || + (user.getVoiceStateForGuild(context.getGuild()).isDeafened()) || + (user.getVoiceStateForGuild(context.getGuild()).isSelfDeafened())); + int userCount = usersHere.size(); int userDownvotes = 0; IReaction reaction = message.getReactionByUnicode(thumbsDown); @@ -59,8 +62,6 @@ public class ReactionHandler { if (userDownvotes > (userCount/2)){ log.log(BotLog.TYPE.MUSIC, context.getGuild(), "Users voted to skip the current song."); HandieBot.musicPlayer.skipTrack(context.getGuild()); - } else if (userDownvotes > 0) { - context.getChannel().sendMessage((((userCount/2)+1) - userDownvotes)+" more people must downvote before the track is skipped."); } } diff --git a/src/main/java/handiebot/command/commands/misc/TengwarCommand.java b/src/main/java/handiebot/command/commands/misc/TengwarCommand.java index 1983057..5d05cc1 100644 --- a/src/main/java/handiebot/command/commands/misc/TengwarCommand.java +++ b/src/main/java/handiebot/command/commands/misc/TengwarCommand.java @@ -16,7 +16,7 @@ public class TengwarCommand extends ContextCommand { public TengwarCommand() { super("tengwar", - " ", + " ", resourceBundle.getString("commands.command.tengwar.description"), 0); } @@ -27,19 +27,19 @@ public class TengwarCommand extends ContextCommand { context.getChannel().sendMessage(this.getUsage(context.getGuild())); } else if (context.getArgs().length >= 2){ String input = readTextFromArgs(context.getArgs()); - if (context.getArgs()[0].equalsIgnoreCase("translateTo")){ + if (context.getArgs()[0].equalsIgnoreCase("to")){ String result = Translator.translateToTengwar(input); try { - context.getChannel().sendFile(TengwarImageGenerator.generateImage(result, - 500, - 24f, + context.getChannel().sendFile("Raw text: `" +result+'`', TengwarImageGenerator.generateImage(result, + 400, + 20f, false, false, System.getProperty("user.home")+"/.handiebot/tengwarTemp.png")); } catch (FileNotFoundException e) { e.printStackTrace(); } - } else if (context.getArgs()[0].equalsIgnoreCase("translateFrom")){ + } else if (context.getArgs()[0].equalsIgnoreCase("to")){ context.getChannel().sendMessage(Translator.translateToEnglish(input)); } } else { diff --git a/src/main/java/handiebot/command/commands/music/PlayCommand.java b/src/main/java/handiebot/command/commands/music/PlayCommand.java index ef8ec86..33398c0 100644 --- a/src/main/java/handiebot/command/commands/music/PlayCommand.java +++ b/src/main/java/handiebot/command/commands/music/PlayCommand.java @@ -28,7 +28,7 @@ public class PlayCommand extends ContextCommand { HandieBot.musicPlayer.playQueue(context.getGuild()); } else { try { - HandieBot.musicPlayer.addToQueue(context.getGuild(), new UnloadedTrack(context.getArgs()[0])); + HandieBot.musicPlayer.addToQueue(context.getGuild(), new UnloadedTrack(context.getArgs()[0]), context.getUser()); } catch (Exception e) { context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.play.songAddError"), context.getArgs()[0])); e.printStackTrace(); diff --git a/src/main/java/handiebot/command/commands/music/PlaylistCommand.java b/src/main/java/handiebot/command/commands/music/PlaylistCommand.java index 99ca25e..5e90469 100644 --- a/src/main/java/handiebot/command/commands/music/PlaylistCommand.java +++ b/src/main/java/handiebot/command/commands/music/PlaylistCommand.java @@ -23,7 +23,7 @@ import static handiebot.HandieBot.resourceBundle; * Command to manipulate playlists. */ public class PlaylistCommand extends ContextCommand { -//TODO: Add specific permissions per argument. + public PlaylistCommand(){ super("playlist", " [PLAYLIST]", @@ -36,7 +36,7 @@ public class PlaylistCommand extends ContextCommand { "\t`rename ` - "+resourceBundle.getString("commands.command.playlist.description.rename")+"\n" + "\t`move ` - "+resourceBundle.getString("commands.command.playlist.description.move")+"\n" + "\t`play ` - "+resourceBundle.getString("commands.command.playlist.description.play"), - 0); + 8); } @Override diff --git a/src/main/java/handiebot/command/commands/music/QueueCommand.java b/src/main/java/handiebot/command/commands/music/QueueCommand.java index 5a3a2b5..644d63d 100644 --- a/src/main/java/handiebot/command/commands/music/QueueCommand.java +++ b/src/main/java/handiebot/command/commands/music/QueueCommand.java @@ -2,6 +2,7 @@ package handiebot.command.commands.music; import handiebot.HandieBot; import handiebot.command.CommandContext; +import handiebot.command.Commands; import handiebot.command.types.ContextCommand; import handiebot.lavaplayer.playlist.Playlist; import handiebot.view.BotLog; @@ -16,7 +17,7 @@ import static handiebot.HandieBot.resourceBundle; * Queue command to display the active queue. */ public class QueueCommand extends ContextCommand { - //TODO: Add specific permissions per argument. + public QueueCommand() { super("queue", "[all|clear|save]", @@ -35,15 +36,19 @@ public class QueueCommand extends ContextCommand { HandieBot.musicPlayer.showQueueList(context.getGuild(), true); break; case ("clear"): - HandieBot.musicPlayer.clearQueue(context.getGuild()); - log.log(BotLog.TYPE.MUSIC, context.getGuild(), resourceBundle.getString("commands.command.queue.clear")); + if (Commands.hasPermission(context, 8)) { + HandieBot.musicPlayer.clearQueue(context.getGuild()); + log.log(BotLog.TYPE.MUSIC, context.getGuild(), resourceBundle.getString("commands.command.queue.clear")); + } break; case ("save"): - Playlist p = HandieBot.musicPlayer.getAllSongsInQueue(context.getGuild()); - p.setName(context.getArgs()[1]); - p.save(); - context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.queue.save.message"), p.getTrackCount(), p.getName())); - log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.queue.save.log"), p.getName())); + if (context.getArgs().length == 2 && Commands.hasPermission(context, 8)) { + Playlist p = HandieBot.musicPlayer.getAllSongsInQueue(context.getGuild()); + p.setName(context.getArgs()[1]); + p.save(); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.queue.save.message"), p.getTrackCount(), p.getName())); + log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.queue.save.log"), p.getName())); + } break; } } else { diff --git a/src/main/java/handiebot/command/commands/music/RepeatCommand.java b/src/main/java/handiebot/command/commands/music/RepeatCommand.java index 864b1f5..97fa33c 100644 --- a/src/main/java/handiebot/command/commands/music/RepeatCommand.java +++ b/src/main/java/handiebot/command/commands/music/RepeatCommand.java @@ -2,8 +2,11 @@ package handiebot.command.commands.music; import handiebot.HandieBot; import handiebot.command.CommandContext; +import handiebot.command.Commands; import handiebot.command.types.ContextCommand; +import java.text.MessageFormat; + import static handiebot.HandieBot.resourceBundle; /** @@ -11,21 +14,21 @@ import static handiebot.HandieBot.resourceBundle; * Command to toggle repeating of the active playlist. */ public class RepeatCommand extends ContextCommand { -//TODO: make changing settings admin-only + public RepeatCommand(){ super("repeat", "[true|false]", resourceBundle.getString("commands.command.repeat.description"), - 8); + 0); } @Override public void execute(CommandContext context) { - if (context.getArgs().length == 1){ + if (context.getArgs().length == 1 && Commands.hasPermission(context, 8)){ boolean shouldRepeat = Boolean.getBoolean(context.getArgs()[0].toLowerCase()); HandieBot.musicPlayer.setRepeat(context.getGuild(), shouldRepeat); } else { - HandieBot.musicPlayer.toggleRepeat(context.getGuild()); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("player.getRepeat"), HandieBot.musicPlayer.isRepeating(context.getGuild()))); } } } diff --git a/src/main/java/handiebot/command/commands/music/ShuffleCommand.java b/src/main/java/handiebot/command/commands/music/ShuffleCommand.java index 3cc1304..9ba9d24 100644 --- a/src/main/java/handiebot/command/commands/music/ShuffleCommand.java +++ b/src/main/java/handiebot/command/commands/music/ShuffleCommand.java @@ -2,8 +2,11 @@ package handiebot.command.commands.music; import handiebot.HandieBot; import handiebot.command.CommandContext; +import handiebot.command.Commands; import handiebot.command.types.ContextCommand; +import java.text.MessageFormat; + import static handiebot.HandieBot.resourceBundle; /** @@ -11,21 +14,21 @@ import static handiebot.HandieBot.resourceBundle; * Command to set shuffling of the active playlist. */ public class ShuffleCommand extends ContextCommand { -//TODO: make changes admin-only + public ShuffleCommand(){ super("shuffle", "[true|false]", resourceBundle.getString("commands.command.shuffle.description"), - 8); + 0); } @Override public void execute(CommandContext context) { - if (context.getArgs().length == 1){ + if (context.getArgs().length == 1 && Commands.hasPermission(context, 8)){ boolean shouldShuffle = Boolean.getBoolean(context.getArgs()[0].toLowerCase()); HandieBot.musicPlayer.setShuffle(context.getGuild(), shouldShuffle); } else { - HandieBot.musicPlayer.toggleShuffle(context.getGuild()); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("player.getShuffle"), HandieBot.musicPlayer.isShuffling(context.getGuild()))); } } } diff --git a/src/main/java/handiebot/lavaplayer/MusicPlayer.java b/src/main/java/handiebot/lavaplayer/MusicPlayer.java index 502658d..666990f 100644 --- a/src/main/java/handiebot/lavaplayer/MusicPlayer.java +++ b/src/main/java/handiebot/lavaplayer/MusicPlayer.java @@ -11,6 +11,7 @@ import handiebot.utils.Pastebin; import handiebot.view.BotLog; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IGuild; +import sx.blah.discord.handle.obj.IUser; import sx.blah.discord.handle.obj.IVoiceChannel; import sx.blah.discord.util.EmbedBuilder; @@ -130,6 +131,15 @@ public class MusicPlayer { getChatChannel(guild).sendMessage(":repeat: "+message); } + /** + * Returns whether or not repeat is set for a guild. + * @param guild The guild to check for. + * @return True if repeating is enabled, false otherwise. + */ + public boolean isRepeating(IGuild guild){ + return getMusicManager(guild).scheduler.isRepeating(); + } + /** * Toggles shuffling for a specific guild. * @param guild The guild to toggle shuffling for. @@ -150,6 +160,15 @@ public class MusicPlayer { getChatChannel(guild).sendMessage(":twisted_rightwards_arrows: "+message); } + /** + * Returns whether or not shuffle is set for a guild. + * @param guild The guild to check for. + * @return True if shuffling is enabled, false otherwise. + */ + public boolean isShuffling(IGuild guild){ + return getMusicManager(guild).scheduler.isShuffling(); + } + /** * Sends a formatted message to the guild about the first few items in a queue. */ @@ -184,9 +203,11 @@ public class MusicPlayer { /** * Adds a track to the queue and sends a message to the appropriate channel notifying users. + * @param guild The guild to add the song to. * @param track The track to queue. + * @param user the user who added the song. */ - public void addToQueue(IGuild guild, UnloadedTrack track){ + public void addToQueue(IGuild guild, UnloadedTrack track, IUser user){ IVoiceChannel voiceChannel = getVoiceChannel(guild); if (voiceChannel != null){ if (!voiceChannel.isConnected()) { @@ -197,7 +218,7 @@ public class MusicPlayer { //Build message. StringBuilder sb = new StringBuilder(); if (timeUntilPlay > 0) { - sb.append(MessageFormat.format(resourceBundle.getString("player.addedToQueue"), track.getTitle())); + sb.append(MessageFormat.format(resourceBundle.getString("player.addedToQueue"), user.getName(), track.getTitle())); } //If there's some tracks in the queue, get the time until this one plays. if (timeUntilPlay > 0){ diff --git a/src/main/java/handiebot/lavaplayer/TrackScheduler.java b/src/main/java/handiebot/lavaplayer/TrackScheduler.java index 39cbd2d..90efcb8 100644 --- a/src/main/java/handiebot/lavaplayer/TrackScheduler.java +++ b/src/main/java/handiebot/lavaplayer/TrackScheduler.java @@ -34,6 +34,7 @@ public class TrackScheduler extends AudioEventAdapter { private final AudioPlayer player; private Playlist activePlaylist; + private long activePlayMessageId; private boolean repeat = true; private boolean shuffle = false; @@ -64,6 +65,10 @@ public class TrackScheduler extends AudioEventAdapter { return this.activePlaylist; } + public long getPlayMessageId(){ + return this.activePlayMessageId; + } + /** * Clears the queue. */ @@ -191,6 +196,7 @@ public class TrackScheduler extends AudioEventAdapter { List channels = this.guild.getChannelsByName(MusicPlayer.CHANNEL_NAME.toLowerCase()); if (channels.size() > 0){ IMessage message = channels.get(0).sendMessage(MessageFormat.format(":arrow_forward: "+resourceBundle.getString("trackSchedule.nowPlaying"), track.getInfo().title, new UnloadedTrack(track).getFormattedDuration())); + this.activePlayMessageId = message.getLongID(); RequestBuffer.request(() -> {message.addReaction(":thumbsup:");}).get(); RequestBuffer.request(() -> {message.addReaction(":thumbsdown:");}).get(); } diff --git a/src/main/resources/Strings.properties b/src/main/resources/Strings.properties index e8a6b01..8ec9027 100644 --- a/src/main/resources/Strings.properties +++ b/src/main/resources/Strings.properties @@ -16,6 +16,7 @@ menu.filemenu.quit=Quit #Generic Command Messages commands.noPermission.message=You do not have permission to use the command `{0}`. commands.noPermission.log=User {0} does not have permission to execute {1} +commands.noPermission.subcommand=You don't have permission to do that. commands.invalidCommand.noContext=Invalid command issued: {0} commands.invalidCommand.context=Invalid command: {0} issued by: {1} #Messages for specific commands. @@ -93,14 +94,16 @@ commands.command.stop.description=Stops playing music. #Tengwar translator commands.command.tengwar.description=Translates text to tengwar, or decodes tengwar text back into human readable form. #Music Player -player.setRepeat=Set repeat to {0} -player.setShuffle=Set shuffle to {0} +player.setRepeat=Set **Repeat** to *{0}*. +player.setShuffle=Set **Shuffle** to *{0}*. +player.getRepeat=**Repeat** is set to *{0}*. +player.getShuffle=**Shuffle** is set to *{0}*. player.queueEmpty=The queue is empty. Use `{0}` to add songs. -player.queueUploaded=Queue uploaded to pastebin: {0} +player.queueUploaded=Queue uploaded to pastebin: {0}. player.pastebinLink=You may view the full queue by following the link: {0}\nNote that this link expires in 10 minutes. -player.pastebinError=Unable to upload to pastebin: {0} +player.pastebinError=Unable to upload to pastebin: {0}. player.queueHeader=Showing {0} track{1} out of {2}. -player.addedToQueue=Added **{0}** to the queue. +player.addedToQueue={0} added **{1}** to the queue. player.queueCleared=Cleared the queue. player.skippingCurrent=Skipping the current track. player.musicStopped=Stopped playing music. @@ -109,3 +112,4 @@ player.playQueueEmpty=There's nothing in the queue to play. trackSchedule.trackStarted=Started audio track: {0} trackSchedule.nowPlaying=Now playing: **{0}** {1} + diff --git a/src/main/resources/Strings_nl.properties b/src/main/resources/Strings_nl.properties index 9e56840..76f90c7 100644 --- a/src/main/resources/Strings_nl.properties +++ b/src/main/resources/Strings_nl.properties @@ -100,4 +100,6 @@ trackSchedule.nowPlaying=Now playing: **{0}** {1}\ {2} player.playQueueEmpty=There's nothing in the queue to play. commands.command.tengwar.description=Translates text to tengwar, or decodes tengwar text back into human readable form. +commands.noPermissions=You don't have permission to do that. +player.getRepeat=Repeat is set to *{0}*.