Version 1.4.0 merge from development. #6

Merged
andrewlalis merged 13 commits from development into master 2017-07-03 11:28:00 +00:00
12 changed files with 100 additions and 37 deletions
Showing only changes of commit bca2921e67 - Show all commits

View File

@ -10,6 +10,7 @@ import handiebot.command.types.Command;
import handiebot.command.types.ContextCommand; import handiebot.command.types.ContextCommand;
import handiebot.command.types.StaticCommand; import handiebot.command.types.StaticCommand;
import handiebot.view.BotLog; import handiebot.view.BotLog;
import sx.blah.discord.handle.obj.Permissions;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
@ -87,4 +88,21 @@ public class Commands {
return null; 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;
}
} }

View File

@ -16,7 +16,7 @@ import static handiebot.HandieBot.log;
* Class which handles user reactions to songs and performs necessary actions. * Class which handles user reactions to songs and performs necessary actions.
*/ */
public class ReactionHandler { 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 thumbsUp = "\uD83D\uDC4D";
public static final String thumbsDown = "\uD83D\uDC4E"; public static final String thumbsDown = "\uD83D\uDC4E";
@ -42,12 +42,15 @@ public class ReactionHandler {
*/ */
private static void onDownvote(CommandContext context, IMessage message){ private static void onDownvote(CommandContext context, IMessage message){
//Filter out reactions to previous messages. //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; return;
} }
List<IUser> usersHere = HandieBot.musicPlayer.getVoiceChannel(context.getGuild()).getConnectedUsers(); List<IUser> usersHere = HandieBot.musicPlayer.getVoiceChannel(context.getGuild()).getConnectedUsers();
//Remove the bot from the list of users in the voice channel. //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 userCount = usersHere.size();
int userDownvotes = 0; int userDownvotes = 0;
IReaction reaction = message.getReactionByUnicode(thumbsDown); IReaction reaction = message.getReactionByUnicode(thumbsDown);
@ -59,8 +62,6 @@ public class ReactionHandler {
if (userDownvotes > (userCount/2)){ if (userDownvotes > (userCount/2)){
log.log(BotLog.TYPE.MUSIC, context.getGuild(), "Users voted to skip the current song."); log.log(BotLog.TYPE.MUSIC, context.getGuild(), "Users voted to skip the current song.");
HandieBot.musicPlayer.skipTrack(context.getGuild()); 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.");
} }
} }

View File

@ -16,7 +16,7 @@ public class TengwarCommand extends ContextCommand {
public TengwarCommand() { public TengwarCommand() {
super("tengwar", super("tengwar",
"<translateTo|translateFrom> <TEXT>", "<to|from> <TEXT>",
resourceBundle.getString("commands.command.tengwar.description"), resourceBundle.getString("commands.command.tengwar.description"),
0); 0);
} }
@ -27,19 +27,19 @@ public class TengwarCommand extends ContextCommand {
context.getChannel().sendMessage(this.getUsage(context.getGuild())); context.getChannel().sendMessage(this.getUsage(context.getGuild()));
} else if (context.getArgs().length >= 2){ } else if (context.getArgs().length >= 2){
String input = readTextFromArgs(context.getArgs()); String input = readTextFromArgs(context.getArgs());
if (context.getArgs()[0].equalsIgnoreCase("translateTo")){ if (context.getArgs()[0].equalsIgnoreCase("to")){
String result = Translator.translateToTengwar(input); String result = Translator.translateToTengwar(input);
try { try {
context.getChannel().sendFile(TengwarImageGenerator.generateImage(result, context.getChannel().sendFile("Raw text: `" +result+'`', TengwarImageGenerator.generateImage(result,
500, 400,
24f, 20f,
false, false,
false, false,
System.getProperty("user.home")+"/.handiebot/tengwarTemp.png")); System.getProperty("user.home")+"/.handiebot/tengwarTemp.png"));
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} }
} else if (context.getArgs()[0].equalsIgnoreCase("translateFrom")){ } else if (context.getArgs()[0].equalsIgnoreCase("to")){
context.getChannel().sendMessage(Translator.translateToEnglish(input)); context.getChannel().sendMessage(Translator.translateToEnglish(input));
} }
} else { } else {

View File

@ -28,7 +28,7 @@ public class PlayCommand extends ContextCommand {
HandieBot.musicPlayer.playQueue(context.getGuild()); HandieBot.musicPlayer.playQueue(context.getGuild());
} else { } else {
try { 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) { } catch (Exception e) {
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.play.songAddError"), context.getArgs()[0])); context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.play.songAddError"), context.getArgs()[0]));
e.printStackTrace(); e.printStackTrace();

View File

@ -23,7 +23,7 @@ import static handiebot.HandieBot.resourceBundle;
* Command to manipulate playlists. * Command to manipulate playlists.
*/ */
public class PlaylistCommand extends ContextCommand { public class PlaylistCommand extends ContextCommand {
//TODO: Add specific permissions per argument.
public PlaylistCommand(){ public PlaylistCommand(){
super("playlist", super("playlist",
"<create|delete|show|add|remove|rename|move|play> [PLAYLIST]", "<create|delete|show|add|remove|rename|move|play> [PLAYLIST]",
@ -36,7 +36,7 @@ public class PlaylistCommand extends ContextCommand {
"\t`rename <PLAYLIST> <NEWNAME>` - "+resourceBundle.getString("commands.command.playlist.description.rename")+"\n" + "\t`rename <PLAYLIST> <NEWNAME>` - "+resourceBundle.getString("commands.command.playlist.description.rename")+"\n" +
"\t`move <PLAYLIST> <OLDINDEX> <NEWINDEX>` - "+resourceBundle.getString("commands.command.playlist.description.move")+"\n" + "\t`move <PLAYLIST> <OLDINDEX> <NEWINDEX>` - "+resourceBundle.getString("commands.command.playlist.description.move")+"\n" +
"\t`play <PLAYLIST>` - "+resourceBundle.getString("commands.command.playlist.description.play"), "\t`play <PLAYLIST>` - "+resourceBundle.getString("commands.command.playlist.description.play"),
0); 8);
} }
@Override @Override

View File

@ -2,6 +2,7 @@ package handiebot.command.commands.music;
import handiebot.HandieBot; import handiebot.HandieBot;
import handiebot.command.CommandContext; import handiebot.command.CommandContext;
import handiebot.command.Commands;
import handiebot.command.types.ContextCommand; import handiebot.command.types.ContextCommand;
import handiebot.lavaplayer.playlist.Playlist; import handiebot.lavaplayer.playlist.Playlist;
import handiebot.view.BotLog; import handiebot.view.BotLog;
@ -16,7 +17,7 @@ import static handiebot.HandieBot.resourceBundle;
* Queue command to display the active queue. * Queue command to display the active queue.
*/ */
public class QueueCommand extends ContextCommand { public class QueueCommand extends ContextCommand {
//TODO: Add specific permissions per argument.
public QueueCommand() { public QueueCommand() {
super("queue", super("queue",
"[all|clear|save]", "[all|clear|save]",
@ -35,15 +36,19 @@ public class QueueCommand extends ContextCommand {
HandieBot.musicPlayer.showQueueList(context.getGuild(), true); HandieBot.musicPlayer.showQueueList(context.getGuild(), true);
break; break;
case ("clear"): case ("clear"):
if (Commands.hasPermission(context, 8)) {
HandieBot.musicPlayer.clearQueue(context.getGuild()); HandieBot.musicPlayer.clearQueue(context.getGuild());
log.log(BotLog.TYPE.MUSIC, context.getGuild(), resourceBundle.getString("commands.command.queue.clear")); log.log(BotLog.TYPE.MUSIC, context.getGuild(), resourceBundle.getString("commands.command.queue.clear"));
}
break; break;
case ("save"): case ("save"):
if (context.getArgs().length == 2 && Commands.hasPermission(context, 8)) {
Playlist p = HandieBot.musicPlayer.getAllSongsInQueue(context.getGuild()); Playlist p = HandieBot.musicPlayer.getAllSongsInQueue(context.getGuild());
p.setName(context.getArgs()[1]); p.setName(context.getArgs()[1]);
p.save(); p.save();
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.queue.save.message"), p.getTrackCount(), p.getName())); 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())); log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.queue.save.log"), p.getName()));
}
break; break;
} }
} else { } else {

View File

@ -2,8 +2,11 @@ package handiebot.command.commands.music;
import handiebot.HandieBot; import handiebot.HandieBot;
import handiebot.command.CommandContext; import handiebot.command.CommandContext;
import handiebot.command.Commands;
import handiebot.command.types.ContextCommand; import handiebot.command.types.ContextCommand;
import java.text.MessageFormat;
import static handiebot.HandieBot.resourceBundle; import static handiebot.HandieBot.resourceBundle;
/** /**
@ -11,21 +14,21 @@ import static handiebot.HandieBot.resourceBundle;
* Command to toggle repeating of the active playlist. * Command to toggle repeating of the active playlist.
*/ */
public class RepeatCommand extends ContextCommand { public class RepeatCommand extends ContextCommand {
//TODO: make changing settings admin-only
public RepeatCommand(){ public RepeatCommand(){
super("repeat", super("repeat",
"[true|false]", "[true|false]",
resourceBundle.getString("commands.command.repeat.description"), resourceBundle.getString("commands.command.repeat.description"),
8); 0);
} }
@Override @Override
public void execute(CommandContext context) { 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()); boolean shouldRepeat = Boolean.getBoolean(context.getArgs()[0].toLowerCase());
HandieBot.musicPlayer.setRepeat(context.getGuild(), shouldRepeat); HandieBot.musicPlayer.setRepeat(context.getGuild(), shouldRepeat);
} else { } else {
HandieBot.musicPlayer.toggleRepeat(context.getGuild()); context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("player.getRepeat"), HandieBot.musicPlayer.isRepeating(context.getGuild())));
} }
} }
} }

View File

@ -2,8 +2,11 @@ package handiebot.command.commands.music;
import handiebot.HandieBot; import handiebot.HandieBot;
import handiebot.command.CommandContext; import handiebot.command.CommandContext;
import handiebot.command.Commands;
import handiebot.command.types.ContextCommand; import handiebot.command.types.ContextCommand;
import java.text.MessageFormat;
import static handiebot.HandieBot.resourceBundle; import static handiebot.HandieBot.resourceBundle;
/** /**
@ -11,21 +14,21 @@ import static handiebot.HandieBot.resourceBundle;
* Command to set shuffling of the active playlist. * Command to set shuffling of the active playlist.
*/ */
public class ShuffleCommand extends ContextCommand { public class ShuffleCommand extends ContextCommand {
//TODO: make changes admin-only
public ShuffleCommand(){ public ShuffleCommand(){
super("shuffle", super("shuffle",
"[true|false]", "[true|false]",
resourceBundle.getString("commands.command.shuffle.description"), resourceBundle.getString("commands.command.shuffle.description"),
8); 0);
} }
@Override @Override
public void execute(CommandContext context) { 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()); boolean shouldShuffle = Boolean.getBoolean(context.getArgs()[0].toLowerCase());
HandieBot.musicPlayer.setShuffle(context.getGuild(), shouldShuffle); HandieBot.musicPlayer.setShuffle(context.getGuild(), shouldShuffle);
} else { } else {
HandieBot.musicPlayer.toggleShuffle(context.getGuild()); context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("player.getShuffle"), HandieBot.musicPlayer.isShuffling(context.getGuild())));
} }
} }
} }

View File

@ -11,6 +11,7 @@ import handiebot.utils.Pastebin;
import handiebot.view.BotLog; import handiebot.view.BotLog;
import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IGuild; 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.handle.obj.IVoiceChannel;
import sx.blah.discord.util.EmbedBuilder; import sx.blah.discord.util.EmbedBuilder;
@ -130,6 +131,15 @@ public class MusicPlayer {
getChatChannel(guild).sendMessage(":repeat: "+message); 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. * Toggles shuffling for a specific guild.
* @param guild The guild to toggle shuffling for. * @param guild The guild to toggle shuffling for.
@ -150,6 +160,15 @@ public class MusicPlayer {
getChatChannel(guild).sendMessage(":twisted_rightwards_arrows: "+message); 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. * 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. * 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 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); IVoiceChannel voiceChannel = getVoiceChannel(guild);
if (voiceChannel != null){ if (voiceChannel != null){
if (!voiceChannel.isConnected()) { if (!voiceChannel.isConnected()) {
@ -197,7 +218,7 @@ public class MusicPlayer {
//Build message. //Build message.
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (timeUntilPlay > 0) { 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 there's some tracks in the queue, get the time until this one plays.
if (timeUntilPlay > 0){ if (timeUntilPlay > 0){

View File

@ -34,6 +34,7 @@ public class TrackScheduler extends AudioEventAdapter {
private final AudioPlayer player; private final AudioPlayer player;
private Playlist activePlaylist; private Playlist activePlaylist;
private long activePlayMessageId;
private boolean repeat = true; private boolean repeat = true;
private boolean shuffle = false; private boolean shuffle = false;
@ -64,6 +65,10 @@ public class TrackScheduler extends AudioEventAdapter {
return this.activePlaylist; return this.activePlaylist;
} }
public long getPlayMessageId(){
return this.activePlayMessageId;
}
/** /**
* Clears the queue. * Clears the queue.
*/ */
@ -191,6 +196,7 @@ public class TrackScheduler extends AudioEventAdapter {
List<IChannel> channels = this.guild.getChannelsByName(MusicPlayer.CHANNEL_NAME.toLowerCase()); List<IChannel> channels = this.guild.getChannelsByName(MusicPlayer.CHANNEL_NAME.toLowerCase());
if (channels.size() > 0){ 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())); 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(":thumbsup:");}).get();
RequestBuffer.request(() -> {message.addReaction(":thumbsdown:");}).get(); RequestBuffer.request(() -> {message.addReaction(":thumbsdown:");}).get();
} }

View File

@ -16,6 +16,7 @@ menu.filemenu.quit=Quit
#Generic Command Messages #Generic Command Messages
commands.noPermission.message=You do not have permission to use the command `{0}`. 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.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.noContext=Invalid command issued: {0}
commands.invalidCommand.context=Invalid command: {0} issued by: {1} commands.invalidCommand.context=Invalid command: {0} issued by: {1}
#Messages for specific commands. #Messages for specific commands.
@ -93,14 +94,16 @@ commands.command.stop.description=Stops playing music.
#Tengwar translator #Tengwar translator
commands.command.tengwar.description=Translates text to tengwar, or decodes tengwar text back into human readable form. commands.command.tengwar.description=Translates text to tengwar, or decodes tengwar text back into human readable form.
#Music Player #Music Player
player.setRepeat=Set repeat to {0} player.setRepeat=Set **Repeat** to *{0}*.
player.setShuffle=Set shuffle 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.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.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.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.queueCleared=Cleared the queue.
player.skippingCurrent=Skipping the current track. player.skippingCurrent=Skipping the current track.
player.musicStopped=Stopped playing music. 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.trackStarted=Started audio track: {0}
trackSchedule.nowPlaying=Now playing: **{0}** {1} trackSchedule.nowPlaying=Now playing: **{0}** {1}

View File

@ -100,4 +100,6 @@ trackSchedule.nowPlaying=Now playing: **{0}** {1}\
{2} {2}
player.playQueueEmpty=There's nothing in the queue to play. 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.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}*.