From 1ab45a868a8eaaf876d7a93d553ba1a26ef2cb98 Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Tue, 27 Jun 2017 17:34:03 +0200 Subject: [PATCH 01/13] updated gitignore --- .gitignore | 6 +++++- pom.xml | 2 -- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 912eb2f..808b8e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -!.jar \ No newline at end of file +!.jar +.idea/ +modules/ +src/test/ +target/ diff --git a/pom.xml b/pom.xml index f8e7b99..ab44f7e 100644 --- a/pom.xml +++ b/pom.xml @@ -22,8 +22,6 @@ maven-assembly-plugin 3.0.0 - 1.8 - 1.8 jar-with-dependencies -- 2.34.1 From 71f6911e2f6a1e15a16ee7b6ca7c5d8da87ac22d Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Tue, 27 Jun 2017 23:42:44 +0200 Subject: [PATCH 02/13] fixed pom file compile plugin version --- pom.xml | 1 + src/main/java/handiebot/HandieBot.java | 3 +++ src/main/java/handiebot/command/Commands.java | 3 +-- .../java/handiebot/command/commands/admin/QuitCommand.java | 2 +- src/main/java/handiebot/command/types/Command.java | 4 ++++ src/main/resources/Strings.properties | 0 src/main/resources/Strings_nl.properties | 0 7 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 src/main/resources/Strings.properties create mode 100644 src/main/resources/Strings_nl.properties diff --git a/pom.xml b/pom.xml index ab44f7e..a90dabb 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,7 @@ org.apache.maven.plugins maven-compiler-plugin + 3.6.1 1.8 1.8 diff --git a/src/main/java/handiebot/HandieBot.java b/src/main/java/handiebot/HandieBot.java index 53c72f8..716681f 100644 --- a/src/main/java/handiebot/HandieBot.java +++ b/src/main/java/handiebot/HandieBot.java @@ -22,6 +22,7 @@ import sx.blah.discord.util.RateLimitException; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; +import java.util.ResourceBundle; /** * @author Andrew Lalis @@ -34,6 +35,8 @@ public class HandieBot { public static final String APPLICATION_NAME = "HandieBot"; private static final String TOKEN = "MjgzNjUyOTg5MjEyNjg4Mzg0.C45A_Q.506b0G6my1FEFa7_YY39lxLBHUY"; + public static ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings"); + //Discord client object. public static IDiscordClient client; diff --git a/src/main/java/handiebot/command/Commands.java b/src/main/java/handiebot/command/Commands.java index 02d2431..f2833ed 100644 --- a/src/main/java/handiebot/command/Commands.java +++ b/src/main/java/handiebot/command/Commands.java @@ -8,7 +8,6 @@ import handiebot.command.commands.support.InfoCommand; import handiebot.command.types.Command; import handiebot.command.types.ContextCommand; import handiebot.command.types.StaticCommand; -import handiebot.utils.DisappearingMessage; import handiebot.view.BotLog; import java.util.ArrayList; @@ -50,7 +49,7 @@ public class Commands { if (cmd.getName().equals(command)){ if (!cmd.canUserExecute(context.getUser(), context.getGuild())){ log.log(BotLog.TYPE.ERROR, context.getGuild(), "User "+context.getUser().getName()+" does not have permission to execute "+cmd.getName()); - new DisappearingMessage(context.getChannel(), "You do not have permission to use that command.", 5000); + context.getChannel().sendMessage("You do not have permission to use the command `"+command+"`."); } if (cmd instanceof ContextCommand){ ((ContextCommand)cmd).execute(context); diff --git a/src/main/java/handiebot/command/commands/admin/QuitCommand.java b/src/main/java/handiebot/command/commands/admin/QuitCommand.java index 2986f05..0b8431e 100644 --- a/src/main/java/handiebot/command/commands/admin/QuitCommand.java +++ b/src/main/java/handiebot/command/commands/admin/QuitCommand.java @@ -13,7 +13,7 @@ public class QuitCommand extends StaticCommand { super("quit", "", "Shuts down the bot on all servers.", - 0); + 8); } @Override diff --git a/src/main/java/handiebot/command/types/Command.java b/src/main/java/handiebot/command/types/Command.java index ec88e45..c4b12ac 100644 --- a/src/main/java/handiebot/command/types/Command.java +++ b/src/main/java/handiebot/command/types/Command.java @@ -1,10 +1,13 @@ package handiebot.command.types; import handiebot.command.CommandHandler; +import handiebot.view.BotLog; import sx.blah.discord.handle.obj.IGuild; import sx.blah.discord.handle.obj.IUser; import sx.blah.discord.handle.obj.Permissions; +import static handiebot.HandieBot.log; + /** * @author Andrew Lalis * Basic type of command. @@ -51,6 +54,7 @@ public abstract class Command { */ public boolean canUserExecute(IUser user, IGuild guild){ int userPermissions = Permissions.generatePermissionsNumber(user.getPermissionsForGuild(guild)); + log.log(BotLog.TYPE.INFO, guild, "User "+user.getName()+" has permissions: "+userPermissions); return ((this.permissionsRequired & userPermissions) > 0) || (user.getLongID() == 235439851263098880L); } diff --git a/src/main/resources/Strings.properties b/src/main/resources/Strings.properties new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/Strings_nl.properties b/src/main/resources/Strings_nl.properties new file mode 100644 index 0000000..e69de29 -- 2.34.1 From ca56b5061a368a0a3da81e9ec49844416ea1de2d Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Wed, 28 Jun 2017 10:44:25 +0200 Subject: [PATCH 03/13] Fixed multiple errors and made it command line friendly. * Fixed deletion of messages causing 'no permission error' * Removed the use of intellij gui form and rewrote the gui in plain java. * Added console printing to every log call. --- pom.xml | 2 +- src/main/java/handiebot/HandieBot.java | 37 +++-------- src/main/java/handiebot/command/Commands.java | 28 +++----- .../lavaplayer/playlist/Playlist.java | 6 +- .../handiebot/utils/DisappearingMessage.java | 27 +++++++- src/main/java/handiebot/view/BotLog.java | 5 ++ src/main/java/handiebot/view/BotWindow.java | 26 +++++++- src/main/java/handiebot/view/View.form | 56 ---------------- src/main/java/handiebot/view/View.java | 65 ------------------- 9 files changed, 76 insertions(+), 176 deletions(-) delete mode 100644 src/main/java/handiebot/view/View.form delete mode 100644 src/main/java/handiebot/view/View.java diff --git a/pom.xml b/pom.xml index a90dabb..f47444d 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ com.github.austinv11 Discord4J - 2.8.2 + 2.8.3 com.sedmelluq diff --git a/src/main/java/handiebot/HandieBot.java b/src/main/java/handiebot/HandieBot.java index 716681f..c384c55 100644 --- a/src/main/java/handiebot/HandieBot.java +++ b/src/main/java/handiebot/HandieBot.java @@ -5,16 +5,13 @@ import handiebot.command.ReactionHandler; import handiebot.lavaplayer.MusicPlayer; import handiebot.view.BotLog; import handiebot.view.BotWindow; -import handiebot.view.View; import sx.blah.discord.api.ClientBuilder; import sx.blah.discord.api.IDiscordClient; import sx.blah.discord.api.events.EventSubscriber; import sx.blah.discord.handle.impl.events.ReadyEvent; import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent; import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent; -import sx.blah.discord.handle.obj.IGuild; -import sx.blah.discord.handle.obj.IRole; -import sx.blah.discord.handle.obj.IUser; +import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.Permissions; import sx.blah.discord.util.DiscordException; import sx.blah.discord.util.RateLimitException; @@ -41,7 +38,6 @@ public class HandieBot { public static IDiscordClient client; //Display objects. - public static View view; private static BotWindow window; public static BotLog log; @@ -90,9 +86,8 @@ public class HandieBot { musicPlayer = new MusicPlayer(); - view = new View(); - log = new BotLog(view.getOutputArea()); - window = new BotWindow(view); + window = new BotWindow(); + log = new BotLog(window.getOutputArea()); log.log(BotLog.TYPE.INFO, "Logging client in..."); client = new ClientBuilder().withToken(TOKEN).build(); @@ -101,27 +96,13 @@ public class HandieBot { } /** - * Gets the integer value representing all permission flags. - * @param guild The guild to get permissions for. - * @return int representing permissions. + * Returns whether or not the bot has a specific permission. + * @param permission The permission to check. + * @param channel The channel the bot wants to work in. + * @return True if the bot has permission, false otherwise. */ - private int getClientPermissions(IGuild guild){ - List roles = client.getOurUser().getRolesForGuild(guild); - int allPermissions = 0; - for (IRole role : roles) { - allPermissions = allPermissions | Permissions.generatePermissionsNumber(role.getPermissions()); - } - return allPermissions; - } - - /** - * Returns whether or not the user has a certain permission. - * @param user The user to check for permission. - * @param guild The guild to get the permissions for. - * @return True if the bot has this permission, false if not. - */ - boolean hasPermission(IUser user, IGuild guild){ - return Permissions.getAllowedPermissionsForNumber(getClientPermissions(guild)).contains(user.getPermissionsForGuild(guild)); + public static boolean hasPermission(Permissions permission, IChannel channel){ + return channel.getModifiedPermissions(client.getOurUser()).contains(permission); } /** diff --git a/src/main/java/handiebot/command/Commands.java b/src/main/java/handiebot/command/Commands.java index f2833ed..c0493f2 100644 --- a/src/main/java/handiebot/command/Commands.java +++ b/src/main/java/handiebot/command/Commands.java @@ -47,32 +47,20 @@ public class Commands { public static void executeCommand(String command, CommandContext context){ for (Command cmd : commands) { if (cmd.getName().equals(command)){ - if (!cmd.canUserExecute(context.getUser(), context.getGuild())){ + if (cmd instanceof StaticCommand){ + ((StaticCommand)cmd).execute(); + } else if (!cmd.canUserExecute(context.getUser(), context.getGuild())){ log.log(BotLog.TYPE.ERROR, context.getGuild(), "User "+context.getUser().getName()+" does not have permission to execute "+cmd.getName()); context.getChannel().sendMessage("You do not have permission to use the command `"+command+"`."); - } - if (cmd instanceof ContextCommand){ + } else if (cmd instanceof ContextCommand){ ((ContextCommand)cmd).execute(context); - return; - } else if (cmd instanceof StaticCommand){ - ((StaticCommand)cmd).execute(); - return; } } } - log.log(BotLog.TYPE.ERROR, context.getGuild(), "Invalid command: "+command+" issued by "+context.getUser().getName()); - } - - /** - * Attempts to execute a command. - * @param command The command to execute. - * @param context The command context. - */ - public static void executeCommand(Command command, CommandContext context){ - if (command instanceof ContextCommand && context != null){ - ((ContextCommand)command).execute(context); - } else if (command instanceof StaticCommand){ - ((StaticCommand)command).execute(); + if (context == null){ + log.log(BotLog.TYPE.ERROR, "Invalid command issued: "+command); + } else { + log.log(BotLog.TYPE.ERROR, context.getGuild(), "Invalid command: " + command + " issued by " + context.getUser().getName()); } } diff --git a/src/main/java/handiebot/lavaplayer/playlist/Playlist.java b/src/main/java/handiebot/lavaplayer/playlist/Playlist.java index 4ad89fe..538f911 100644 --- a/src/main/java/handiebot/lavaplayer/playlist/Playlist.java +++ b/src/main/java/handiebot/lavaplayer/playlist/Playlist.java @@ -71,6 +71,9 @@ public class Playlist { } } + /** + * Clears the list of tracks. + */ public void clear(){ this.tracks.clear(); } @@ -117,7 +120,8 @@ public class Playlist { */ public static int getShuffledIndex(int listLength){ float threshold = 0.2f; - int trueLength = listLength - (int)threshold*listLength; + int trueLength = listLength - (int)(threshold*(float)listLength); + log.log(BotLog.TYPE.INFO, "Shuffle results: Actual size: "+listLength+", Last Usable Index: "+trueLength); Random rand = new Random(); //TODO Add in a small gradient in chance for a song to be picked. return rand.nextInt(trueLength); diff --git a/src/main/java/handiebot/utils/DisappearingMessage.java b/src/main/java/handiebot/utils/DisappearingMessage.java index caf5382..f9b18aa 100644 --- a/src/main/java/handiebot/utils/DisappearingMessage.java +++ b/src/main/java/handiebot/utils/DisappearingMessage.java @@ -1,14 +1,19 @@ package handiebot.utils; +import handiebot.HandieBot; +import handiebot.view.BotLog; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IMessage; +import sx.blah.discord.handle.obj.Permissions; + +import static handiebot.HandieBot.log; /** * @author Andrew Lalis * Creates a message on a channel that will disappear after some time. */ public class DisappearingMessage extends Thread implements Runnable { - + /** * Creates a new disappearing message that times out after some time. * @param channel The channel to write the message in. @@ -22,7 +27,8 @@ public class DisappearingMessage extends Thread implements Runnable { } catch (InterruptedException e) { e.printStackTrace(); } - sentMessage.delete(); + if (canDelete(sentMessage)) + sentMessage.delete(); } /** @@ -34,11 +40,26 @@ public class DisappearingMessage extends Thread implements Runnable { new Thread(() -> { try { sleep(timeout); - message.delete(); } catch (InterruptedException e){ e.printStackTrace(); } + if (canDelete(message)) + message.delete(); }).start(); } + /** + * Check to see if it is possible to delete a message before doing so. + * @param message The message that may be deleted. + * @return True if it is safe to delete, false otherwise. + */ + private static boolean canDelete(IMessage message){ + if (HandieBot.hasPermission(Permissions.MANAGE_MESSAGES, message.getChannel())){ + return true; + } else { + log.log(BotLog.TYPE.ERROR, message.getGuild(), "Unable to delete message. Please ensure that the bot has MANAGE_MESSAGES enabled, especially for this channel."); + return false; + } + } + } diff --git a/src/main/java/handiebot/view/BotLog.java b/src/main/java/handiebot/view/BotLog.java index 2e43db4..fc2c05e 100644 --- a/src/main/java/handiebot/view/BotLog.java +++ b/src/main/java/handiebot/view/BotLog.java @@ -70,6 +70,7 @@ public class BotLog { Date date = new Date(System.currentTimeMillis()); DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS"); String dateFormatted = formatter.format(date); + System.out.println(dateFormatted+'['+type.name()+"] "+message); try { this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), dateFormatted, this.defaultStyle); this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), '['+type.name()+"] ", this.logStyles.get(type)); @@ -86,9 +87,13 @@ public class BotLog { * @param message The content of the message. */ public void log(TYPE type, IGuild guild, String message){ + if (guild == null){ + log(type, message); + } Date date = new Date(System.currentTimeMillis()); DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS"); String dateFormatted = formatter.format(date); + System.out.println(dateFormatted+'['+type.name()+"]["+guild.getName()+"] "+message); try { this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), dateFormatted, this.defaultStyle); this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), '['+type.name()+']', this.logStyles.get(type)); diff --git a/src/main/java/handiebot/view/BotWindow.java b/src/main/java/handiebot/view/BotWindow.java index 8c6ac07..696a72f 100644 --- a/src/main/java/handiebot/view/BotWindow.java +++ b/src/main/java/handiebot/view/BotWindow.java @@ -15,9 +15,28 @@ import java.io.IOException; */ public class BotWindow extends JFrame { - public BotWindow(View view){ + private JTextPane outputArea; + + public BotWindow(){ super(HandieBot.APPLICATION_NAME); + //Setup GUI + + //Output area. + outputArea = new JTextPane(); + outputArea.setBackground(Color.white); + JScrollPane scrollPane = new JScrollPane(); + scrollPane.setViewportView(outputArea); + scrollPane.setAutoscrolls(true); + getContentPane().add(scrollPane, BorderLayout.CENTER); + //Command field. + JTextField commandField = new JTextField(); + commandField.setFont(new Font("Courier New", Font.PLAIN, 16)); + commandField.addKeyListener(new CommandLineListener()); + getContentPane().add(commandField, BorderLayout.PAGE_END); + + //Standard JFrame setup code. setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + //Add a listener to override the user attempting to close the program. addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { @@ -34,11 +53,14 @@ public class BotWindow extends JFrame { } catch (IOException e) { e.printStackTrace(); } - setContentPane(view.mainPanel); setJMenuBar(new MenuBar()); setPreferredSize(new Dimension(800, 600)); pack(); setVisible(true); } + public JTextPane getOutputArea(){ + return this.outputArea; + } + } diff --git a/src/main/java/handiebot/view/View.form b/src/main/java/handiebot/view/View.form deleted file mode 100644 index 41da417..0000000 --- a/src/main/java/handiebot/view/View.form +++ /dev/null @@ -1,56 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/handiebot/view/View.java b/src/main/java/handiebot/view/View.java deleted file mode 100644 index 13fe909..0000000 --- a/src/main/java/handiebot/view/View.java +++ /dev/null @@ -1,65 +0,0 @@ -package handiebot.view; - -import javax.swing.*; -import java.awt.*; - -/** - * @author Andrew Lalis - */ -public class View { - public JPanel mainPanel; - private JTextPane outputArea; - private JTextField commandField; - - public View() { - this.commandField.addKeyListener(new CommandLineListener()); - } - - public JTextPane getOutputArea() { - return this.outputArea; - } - - { -// GUI initializer generated by IntelliJ IDEA GUI Designer -// >>> IMPORTANT!! <<< -// DO NOT EDIT OR ADD ANY CODE HERE! - $$$setupUI$$$(); - } - - /** - * Method generated by IntelliJ IDEA GUI Designer - * >>> IMPORTANT!! <<< - * DO NOT edit this method OR call it in your code! - * - * @noinspection ALL - */ - private void $$$setupUI$$$() { - mainPanel = new JPanel(); - mainPanel.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(2, 1, new Insets(0, 0, 0, 0), -1, -1)); - final JScrollPane scrollPane1 = new JScrollPane(); - scrollPane1.setFont(new Font("Consolas", scrollPane1.getFont().getStyle(), 12)); - mainPanel.add(scrollPane1, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); - outputArea = new JTextPane(); - outputArea.setEditable(false); - outputArea.setFont(new Font("Consolas", outputArea.getFont().getStyle(), 12)); - outputArea.setSelectedTextColor(new Color(-1)); - outputArea.setSelectionColor(new Color(-9843846)); - outputArea.setText(""); - scrollPane1.setViewportView(outputArea); - final JPanel panel1 = new JPanel(); - panel1.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1)); - mainPanel.add(panel1, new com.intellij.uiDesigner.core.GridConstraints(1, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - commandField = new JTextField(); - commandField.setFont(new Font("DialogInput", commandField.getFont().getStyle(), 16)); - commandField.setForeground(new Color(-16118999)); - commandField.setMargin(new Insets(0, 0, 0, 0)); - panel1.add(commandField, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_WEST, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); - } - - /** - * @noinspection ALL - */ - public JComponent $$$getRootComponent$$$() { - return mainPanel; - } -} -- 2.34.1 From 36f85fbe13195bafd8ecba12ef256009384f1a95 Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Wed, 28 Jun 2017 10:45:23 +0200 Subject: [PATCH 04/13] Added return to avoid double logging if a guild is null. --- src/main/java/handiebot/view/BotLog.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/handiebot/view/BotLog.java b/src/main/java/handiebot/view/BotLog.java index fc2c05e..fdf33ad 100644 --- a/src/main/java/handiebot/view/BotLog.java +++ b/src/main/java/handiebot/view/BotLog.java @@ -89,6 +89,7 @@ public class BotLog { public void log(TYPE type, IGuild guild, String message){ if (guild == null){ log(type, message); + return; } Date date = new Date(System.currentTimeMillis()); DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS"); -- 2.34.1 From 2078137e1e73d2121c76cac8674b278f3bb0ad40 Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Wed, 28 Jun 2017 15:42:34 +0200 Subject: [PATCH 05/13] added nogui option, and started externalizing strings. --- src/main/java/handiebot/HandieBot.java | 19 ++-- .../handiebot/command/CommandHandler.java | 7 +- src/main/java/handiebot/command/Commands.java | 13 ++- .../command/commands/admin/QuitCommand.java | 4 +- .../commands/admin/SetPrefixCommand.java | 12 ++- .../command/commands/music/PlayCommand.java | 8 +- .../commands/music/PlaylistCommand.java | 88 ++++++++++--------- .../command/commands/music/QueueCommand.java | 37 ++++---- .../command/commands/music/RepeatCommand.java | 4 +- .../commands/music/ShuffleCommand.java | 4 +- .../command/commands/music/SkipCommand.java | 4 +- .../command/commands/music/StopCommand.java | 4 +- .../command/commands/support/HelpCommand.java | 4 +- .../command/commands/support/InfoCommand.java | 12 +-- .../java/handiebot/command/types/Command.java | 4 - src/main/java/handiebot/view/BotLog.java | 30 ++++--- src/main/java/handiebot/view/BotWindow.java | 6 +- src/main/java/handiebot/view/MenuBar.java | 6 +- src/main/resources/Strings.properties | 87 ++++++++++++++++++ src/main/resources/Strings_nl.properties | 83 +++++++++++++++++ 20 files changed, 328 insertions(+), 108 deletions(-) diff --git a/src/main/java/handiebot/HandieBot.java b/src/main/java/handiebot/HandieBot.java index c384c55..969181a 100644 --- a/src/main/java/handiebot/HandieBot.java +++ b/src/main/java/handiebot/HandieBot.java @@ -31,6 +31,7 @@ public class HandieBot { public static final String APPLICATION_NAME = "HandieBot"; private static final String TOKEN = "MjgzNjUyOTg5MjEyNjg4Mzg0.C45A_Q.506b0G6my1FEFa7_YY39lxLBHUY"; + private static boolean USE_GUI = true; public static ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings"); @@ -78,7 +79,7 @@ public class HandieBot { @EventSubscriber public void onReady(ReadyEvent event){ - log.log(BotLog.TYPE.INFO, "HandieBot initialized."); + log.log(BotLog.TYPE.INFO, resourceBundle.getString("log.init")); //client.changeAvatar(Image.forStream("png", getClass().getClassLoader().getResourceAsStream("avatarIcon.png"))); } @@ -86,10 +87,18 @@ public class HandieBot { musicPlayer = new MusicPlayer(); - window = new BotWindow(); - log = new BotLog(window.getOutputArea()); + if (args.length >= 1) { + if (args[0].equalsIgnoreCase("-nogui")){ + USE_GUI = false; + } + } - log.log(BotLog.TYPE.INFO, "Logging client in..."); + if (USE_GUI){ + window = new BotWindow(); + log = new BotLog(window.getOutputArea()); + } + + log.log(BotLog.TYPE.INFO, resourceBundle.getString("log.loggingIn")); client = new ClientBuilder().withToken(TOKEN).build(); client.getDispatcher().registerListener(new HandieBot()); client.login(); @@ -109,7 +118,7 @@ public class HandieBot { * Safely shuts down the bot on all guilds. */ public static void quit(){ - log.log(BotLog.TYPE.INFO, "Shutting down the bot."); + log.log(BotLog.TYPE.INFO, resourceBundle.getString("log.shuttingDown")); musicPlayer.quitAll(); client.logout(); window.dispose(); diff --git a/src/main/java/handiebot/command/CommandHandler.java b/src/main/java/handiebot/command/CommandHandler.java index 2f3c4bc..996a72a 100644 --- a/src/main/java/handiebot/command/CommandHandler.java +++ b/src/main/java/handiebot/command/CommandHandler.java @@ -15,8 +15,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import static handiebot.HandieBot.client; -import static handiebot.HandieBot.log; +import static handiebot.HandieBot.*; /** * @author Andrew Lalis @@ -100,7 +99,7 @@ public class CommandHandler { prefixes.put(client.getGuildByID(Long.parseLong(words[0])), words[1]); } } - log.log(BotLog.TYPE.INFO, "Loaded prefixes."); + log.log(BotLog.TYPE.INFO, resourceBundle.getString("commands.command.setPrefix.loadedPrefixes")); return prefixes; } @@ -114,7 +113,7 @@ public class CommandHandler { lines.add(Long.toString(entry.getKey().getLongID())+" / "+entry.getValue()); } FileUtil.writeLinesToFile(lines, prefixFile); - log.log(BotLog.TYPE.INFO, "Saved prefixes."); + log.log(BotLog.TYPE.INFO, resourceBundle.getString("commands.command.setPrefix.savedPrefixes")); } } diff --git a/src/main/java/handiebot/command/Commands.java b/src/main/java/handiebot/command/Commands.java index c0493f2..9a00c50 100644 --- a/src/main/java/handiebot/command/Commands.java +++ b/src/main/java/handiebot/command/Commands.java @@ -10,10 +10,12 @@ import handiebot.command.types.ContextCommand; import handiebot.command.types.StaticCommand; import handiebot.view.BotLog; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import static handiebot.HandieBot.log; +import static handiebot.HandieBot.resourceBundle; /** * @author Andrew Lalis @@ -49,18 +51,21 @@ public class Commands { if (cmd.getName().equals(command)){ if (cmd instanceof StaticCommand){ ((StaticCommand)cmd).execute(); + return; } else if (!cmd.canUserExecute(context.getUser(), context.getGuild())){ - log.log(BotLog.TYPE.ERROR, context.getGuild(), "User "+context.getUser().getName()+" does not have permission to execute "+cmd.getName()); - context.getChannel().sendMessage("You do not have permission to use the command `"+command+"`."); + log.log(BotLog.TYPE.ERROR, context.getGuild(), MessageFormat.format(resourceBundle.getString("commands.noPermission.log"), context.getUser().getName(), cmd.getName())); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.noPermission.message"), command)); + return; } else if (cmd instanceof ContextCommand){ ((ContextCommand)cmd).execute(context); + return; } } } if (context == null){ - log.log(BotLog.TYPE.ERROR, "Invalid command issued: "+command); + log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("commands.invalidCommand.noContext"), command)); } else { - log.log(BotLog.TYPE.ERROR, context.getGuild(), "Invalid command: " + command + " issued by " + context.getUser().getName()); + log.log(BotLog.TYPE.ERROR, context.getGuild(), MessageFormat.format(resourceBundle.getString("commands.invalidCommand.context"), command, context.getUser().getName())); } } diff --git a/src/main/java/handiebot/command/commands/admin/QuitCommand.java b/src/main/java/handiebot/command/commands/admin/QuitCommand.java index 0b8431e..ae27f8f 100644 --- a/src/main/java/handiebot/command/commands/admin/QuitCommand.java +++ b/src/main/java/handiebot/command/commands/admin/QuitCommand.java @@ -3,6 +3,8 @@ package handiebot.command.commands.admin; import handiebot.HandieBot; import handiebot.command.types.StaticCommand; +import static handiebot.HandieBot.resourceBundle; + /** * @author Andrew Lalis * Command to quit the entire bot. This shuts down every guild's support, and the GUI. @@ -12,7 +14,7 @@ public class QuitCommand extends StaticCommand { public QuitCommand() { super("quit", "", - "Shuts down the bot on all servers.", + resourceBundle.getString("commands.command.quit.description"), 8); } diff --git a/src/main/java/handiebot/command/commands/admin/SetPrefixCommand.java b/src/main/java/handiebot/command/commands/admin/SetPrefixCommand.java index 76ea2b8..eb75085 100644 --- a/src/main/java/handiebot/command/commands/admin/SetPrefixCommand.java +++ b/src/main/java/handiebot/command/commands/admin/SetPrefixCommand.java @@ -5,7 +5,10 @@ import handiebot.command.CommandHandler; import handiebot.command.types.ContextCommand; import handiebot.view.BotLog; +import java.text.MessageFormat; + import static handiebot.HandieBot.log; +import static handiebot.HandieBot.resourceBundle; /** * @author Andrew Lalis @@ -16,7 +19,7 @@ public class SetPrefixCommand extends ContextCommand { public SetPrefixCommand() { super("setprefix", "", - "Sets the prefix for commands.", + resourceBundle.getString("commands.command.setPrefix.description"), 8); } @@ -25,10 +28,11 @@ public class SetPrefixCommand extends ContextCommand { if (context.getArgs().length == 1) { CommandHandler.PREFIXES.put(context.getGuild(), context.getArgs()[0]); CommandHandler.saveGuildPrefixes(); - context.getChannel().sendMessage("Changed command prefix to \""+context.getArgs()[0]+"\""); - log.log(BotLog.TYPE.INFO, "Changed command prefix to \""+context.getArgs()[0]+"\""); + String response = MessageFormat.format(resourceBundle.getString("commands.command.setPrefix.changed"), context.getArgs()[0]); + context.getChannel().sendMessage(response); + log.log(BotLog.TYPE.INFO, response); } else { - context.getChannel().sendMessage("You must provide a new prefix."); + context.getChannel().sendMessage(resourceBundle.getString("commands.command.setPrefix.noPrefixError")); } } } diff --git a/src/main/java/handiebot/command/commands/music/PlayCommand.java b/src/main/java/handiebot/command/commands/music/PlayCommand.java index 9aec8ca..ef8ec86 100644 --- a/src/main/java/handiebot/command/commands/music/PlayCommand.java +++ b/src/main/java/handiebot/command/commands/music/PlayCommand.java @@ -5,6 +5,10 @@ import handiebot.command.CommandContext; import handiebot.command.types.ContextCommand; import handiebot.lavaplayer.playlist.UnloadedTrack; +import java.text.MessageFormat; + +import static handiebot.HandieBot.resourceBundle; + /** * @author Andrew Lalis * Command to play a song from the queue or load a new song. @@ -14,7 +18,7 @@ public class PlayCommand extends ContextCommand { public PlayCommand() { super("play", "[URL]", - "Plays a song, or adds it to the queue.", + resourceBundle.getString("commands.command.play.description"), 0); } @@ -26,7 +30,7 @@ public class PlayCommand extends ContextCommand { try { HandieBot.musicPlayer.addToQueue(context.getGuild(), new UnloadedTrack(context.getArgs()[0])); } catch (Exception e) { - context.getChannel().sendMessage("Unable to add song to queue: "+context.getArgs()[0]+"."); + 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 df5a69d..da63f34 100644 --- a/src/main/java/handiebot/command/commands/music/PlaylistCommand.java +++ b/src/main/java/handiebot/command/commands/music/PlaylistCommand.java @@ -11,9 +11,11 @@ import handiebot.view.BotLog; import sx.blah.discord.handle.obj.IChannel; import java.io.File; +import java.text.MessageFormat; import java.util.List; import static handiebot.HandieBot.log; +import static handiebot.HandieBot.resourceBundle; /** * @author Andrew Lalis @@ -24,15 +26,15 @@ public class PlaylistCommand extends ContextCommand { public PlaylistCommand(){ super("playlist", " [PLAYLIST]", - "Do something with a playlist.\n" + - "\t`create ` - Creates a playlist.\n" + - "\t`delete ` - Deletes a playlist.\n" + - "\t`show [PLAYLIST]` - If a playlist given, show that, otherwise show a list of playlists.\n" + - "\t`add [URL]...` - Adds one or more songs to a playlist.\n" + - "\t`remove ` - Removes a song from a playlist.\n" + - "\t`rename ` - Renames a playlist.\n" + - "\t`move ` - Moves a song from one index to another.\n" + - "\t`play ` - Queues all songs from a playlist.", + resourceBundle.getString("commands.command.playlist.description.main")+"\n" + + "\t`create ` - "+resourceBundle.getString("commands.command.playlist.description.create")+"\n" + + "\t`delete ` - "+resourceBundle.getString("commands.command.playlist.description.delete")+"\n" + + "\t`show [PLAYLIST]` - "+resourceBundle.getString("commands.command.playlist.description.show")+"\n" + + "\t`add [URL]...` - "+resourceBundle.getString("commands.command.playlist.description.add")+"\n" + + "\t`remove ` - "+resourceBundle.getString("commands.command.playlist.description.remove")+"\n" + + "\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); } @@ -79,7 +81,7 @@ public class PlaylistCommand extends ContextCommand { * @param channel The channel to show the error message in. */ private void incorrectMainArg(IChannel channel){ - new DisappearingMessage(channel, "To use the playlist command: \n"+this.getUsage(channel.getGuild()), 5000); + new DisappearingMessage(channel, MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.incorrectMainArg"), this.getUsage(channel.getGuild())), 5000); } /** @@ -95,10 +97,10 @@ public class PlaylistCommand extends ContextCommand { playlist.loadTrack(url); } playlist.save(); - log.log(BotLog.TYPE.INFO, "Created playlist: "+playlist.getName()+" with "+playlist.getTrackCount()+" new tracks."); - context.getChannel().sendMessage("Your playlist *"+playlist.getName()+"* has been created.\nType `"+this.getPrefixedName(context.getGuild())+" play "+playlist.getName()+"` to play it."); + log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.createdPlaylist.log"), playlist.getName(), playlist.getTrackCount())); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.createdPlaylist.message"), playlist.getName(), this.getPrefixedName(context.getGuild()), playlist.getName())); } else { - context.getChannel().sendMessage("You must specify a name for the new playlist."); + context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.createPlaylistName")); } } @@ -113,14 +115,14 @@ public class PlaylistCommand extends ContextCommand { File f = new File(System.getProperty("user.home")+"/.handiebot/playlist/"+context.getArgs()[1].replace(" ", "_")+".txt"); boolean success = f.delete(); if (success){ - log.log(BotLog.TYPE.INFO, "The playlist ["+context.getArgs()[1]+"] has been deleted."); - context.getChannel().sendMessage("The playlist *"+context.getArgs()[1]+"* has been deleted."); + log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.delete.log"), context.getArgs()[1])); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.delete.message"), context.getArgs()[1])); } else { - log.log(BotLog.TYPE.ERROR, "Unable to delete playlist: "+context.getArgs()[1]); - context.getChannel().sendMessage("The playlist could not be deleted."); + log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.delete.log"), context.getArgs()[1])); + context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.delete.message")); } } else { - context.getChannel().sendMessage("You must specify the name of a playlist to delete."); + context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.deletePlaylistName")); } } @@ -157,16 +159,16 @@ public class PlaylistCommand extends ContextCommand { playlist.load(); for (int i = 2; i < context.getArgs().length; i++){ playlist.loadTrack(context.getArgs()[i]); - context.getChannel().sendMessage("Added track to *"+playlist.getName()+"*."); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.add.message"), playlist.getName())); } playlist.save(); context.getChannel().sendMessage(playlist.toString()); - log.log(BotLog.TYPE.INFO, "Added song(s) to playlist ["+playlist.getName()+"]."); + log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.add.log"), playlist.getName())); } else { if (context.getArgs().length == 1){ - context.getChannel().sendMessage("You must provide the name of a playlist to add a URL to."+getPlaylistShowString(context)); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.addNameNeeded"), getPlaylistShowString(context))); } else { - context.getChannel().sendMessage("You must provide at least one URL to add."); + context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.addUrlNeeded")); } } } @@ -183,10 +185,10 @@ public class PlaylistCommand extends ContextCommand { playlist.load(); HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.setPlaylist(playlist); HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.nextTrack(); - log.log(BotLog.TYPE.INFO, "Loaded playlist ["+playlist.getName()+"]."); - context.getChannel().sendMessage("Loaded songs from playlist: *"+playlist.getName()+"*."); + log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.play.log"), playlist.getName())); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.play.message"), playlist.getName())); } else { - context.getChannel().sendMessage("You must provide a playlist to play."+getPlaylistShowString(context)); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.playPlaylistNeeded"), getPlaylistShowString(context))); } } @@ -201,14 +203,15 @@ public class PlaylistCommand extends ContextCommand { File f = new File(System.getProperty("user.home")+"/.handiebot/playlist/"+context.getArgs()[1].replace(" ", "_")+".txt"); boolean success = f.renameTo(new File(System.getProperty("user.home")+"/.handiebot/playlist/"+context.getArgs()[2].replace(" ", "_")+".txt")); if (success){ - context.getChannel().sendMessage("The playlist *"+context.getArgs()[1]+"* has been renamed to *"+context.getArgs()[2]+"*."); - log.log(BotLog.TYPE.INFO, "Playlist "+context.getArgs()[1]+" renamed to "+context.getArgs()[2]+"."); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.rename.message"), context.getArgs()[1], context.getArgs()[2])); + log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.rename.log"), context.getArgs()[1], context.getArgs()[2])); } else { - context.getChannel().sendMessage("Unable to rename playlist."); - log.log(BotLog.TYPE.ERROR, "Unable to rename playlist "+context.getArgs()[1]+" to "+context.getArgs()[2]+"."); + String response = MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.renameError"), context.getArgs()[1], context.getArgs()[2]); + context.getChannel().sendMessage(response); + log.log(BotLog.TYPE.ERROR, response); } } else { - context.getChannel().sendMessage("You must include the original playlist, and a new name for it."); + context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.renameBadArgs")); } } @@ -227,16 +230,17 @@ public class PlaylistCommand extends ContextCommand { UnloadedTrack track = playlist.getTracks().get(index); playlist.removeTrack(track); playlist.save(); - context.getChannel().sendMessage("Removed song: *"+track.getTitle()+"* from playlist **"+playlist.getName()+"**."); - log.log(BotLog.TYPE.MUSIC, "Removed song: "+track.getTitle()+" from playlist ["+playlist.getName()+"]."); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.remove.message"), track.getTitle(), playlist.getName())); + log.log(BotLog.TYPE.MUSIC, MessageFormat.format(resourceBundle.getString("commands.command.playlist.remove.log"), track.getTitle(), playlist.getName())); } catch (IndexOutOfBoundsException | NumberFormatException e){ - context.getChannel().sendMessage("Unable to remove the specified song."); - log.log(BotLog.TYPE.ERROR, "Unable to remove song from playlist: ["+playlist.getName()+"]."); + String response = MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.removeError"), playlist.getName()); + context.getChannel().sendMessage(response); + log.log(BotLog.TYPE.ERROR, response); e.printStackTrace(); } } else { - context.getChannel().sendMessage("You must provide a playlist name, followed by the index number of a song to remove."); + context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.removeBadArgs")); } } @@ -256,7 +260,7 @@ public class PlaylistCommand extends ContextCommand { oldIndex = Integer.parseInt(context.getArgs()[2])-1; newIndex = Integer.parseInt(context.getArgs()[3])-1; } catch (NumberFormatException e){ - context.getChannel().sendMessage("You must enter two positive natural numbers for the song indices."); + context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.moveIndexError")); } UnloadedTrack track; if ((oldIndex > -1 && oldIndex < playlist.getTrackCount()) && @@ -264,13 +268,13 @@ public class PlaylistCommand extends ContextCommand { track = playlist.getTracks().remove(oldIndex); playlist.getTracks().add(newIndex, track); playlist.save(); - context.getChannel().sendMessage("Moved song *"+track.getTitle()+"* from position "+(oldIndex+1)+" to position "+(newIndex+1)); - log.log(BotLog.TYPE.MUSIC, "Moved song "+track.getTitle()+" from position "+(oldIndex+1)+" to position "+(newIndex+1)); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.move.message"), track.getTitle(), oldIndex + 1, newIndex + 1)); + log.log(BotLog.TYPE.MUSIC, MessageFormat.format(resourceBundle.getString("commands.command.playlist.move.log"), track.getTitle(), oldIndex + 1, newIndex + 1)); } else { - context.getChannel().sendMessage("The song indices are invalid. You specified moving song "+oldIndex+" to position "+newIndex+"."); + context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.moveInvalidIndex"), oldIndex, newIndex)); } } else { - context.getChannel().sendMessage("You must provide a playlist name, followed by the song index, and a new index for that song."); + context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.moveBadArgs")); } } @@ -282,7 +286,7 @@ public class PlaylistCommand extends ContextCommand { */ private boolean checkForPlaylist(CommandContext context){ if (!Playlist.playlistExists(context.getArgs()[1])){ - new DisappearingMessage(context.getChannel(), "The playlist you entered does not exist."+getPlaylistShowString(context), 3000); + new DisappearingMessage(context.getChannel(), MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.playlistDoesNotExist"), getPlaylistShowString(context)), 3000); return false; } return true; @@ -294,7 +298,7 @@ public class PlaylistCommand extends ContextCommand { * @return A correct suggestion on how to view all playlists. */ private String getPlaylistShowString(CommandContext context){ - return "\nUse `"+CommandHandler.PREFIXES.get(context.getGuild())+"playlist show` to view available playlists."; + return MessageFormat.format(resourceBundle.getString("commands.command.playlist.showHelpString"), CommandHandler.PREFIXES.get(context.getGuild())); } } diff --git a/src/main/java/handiebot/command/commands/music/QueueCommand.java b/src/main/java/handiebot/command/commands/music/QueueCommand.java index a70f524..5a3a2b5 100644 --- a/src/main/java/handiebot/command/commands/music/QueueCommand.java +++ b/src/main/java/handiebot/command/commands/music/QueueCommand.java @@ -6,7 +6,10 @@ import handiebot.command.types.ContextCommand; import handiebot.lavaplayer.playlist.Playlist; import handiebot.view.BotLog; +import java.text.MessageFormat; + import static handiebot.HandieBot.log; +import static handiebot.HandieBot.resourceBundle; /** * @author Andrew Lalis @@ -17,27 +20,31 @@ public class QueueCommand extends ContextCommand { public QueueCommand() { super("queue", "[all|clear|save]", - "Shows the first 10 songs in the queue.\n" + - "\t`all` - Shows all songs.\n" + - "\t`clear` - Clears the queue and stops playing.\n" + - "\t`save ` - Saves the queue to a playlist.", + resourceBundle.getString("commands.command.queue.description.main")+"\n" + + "\t`all` - "+resourceBundle.getString("commands.command.queue.description.all")+"\n" + + "\t`clear` - "+resourceBundle.getString("commands.command.queue.description.clear")+"\n" + + "\t`save ` - "+resourceBundle.getString("commands.command.queue.description.save"), 0); } @Override public void execute(CommandContext context) { if (context.getArgs().length > 0){ - if (context.getArgs()[0].equals("all")){ - HandieBot.musicPlayer.showQueueList(context.getGuild(), true); - } else if (context.getArgs()[0].equals("clear")){ - HandieBot.musicPlayer.clearQueue(context.getGuild()); - log.log(BotLog.TYPE.MUSIC, context.getGuild(), "Cleared queue."); - } else if (context.getArgs()[0].equals("save") && context.getArgs().length == 2){ - Playlist p = HandieBot.musicPlayer.getAllSongsInQueue(context.getGuild()); - p.setName(context.getArgs()[1]); - p.save(); - context.getChannel().sendMessage("Saved "+p.getTrackCount()+" tracks to playlist **"+p.getName()+"**."); - log.log(BotLog.TYPE.INFO, "Saved queue to playlist ["+p.getName()+"]."); + switch (context.getArgs()[0]){ + case ("all"): + 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")); + 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())); + break; } } else { HandieBot.musicPlayer.showQueueList(context.getGuild(), false); diff --git a/src/main/java/handiebot/command/commands/music/RepeatCommand.java b/src/main/java/handiebot/command/commands/music/RepeatCommand.java index ff43a3f..f2b5fd4 100644 --- a/src/main/java/handiebot/command/commands/music/RepeatCommand.java +++ b/src/main/java/handiebot/command/commands/music/RepeatCommand.java @@ -4,6 +4,8 @@ import handiebot.HandieBot; import handiebot.command.CommandContext; import handiebot.command.types.ContextCommand; +import static handiebot.HandieBot.resourceBundle; + /** * @author Andrew Lalis * Command to toggle repeating of the active playlist. @@ -13,7 +15,7 @@ public class RepeatCommand extends ContextCommand { public RepeatCommand(){ super("repeat", "[true|false]", - "Sets repeating.", + resourceBundle.getString("commands.command.repeat.description"), 8); } diff --git a/src/main/java/handiebot/command/commands/music/ShuffleCommand.java b/src/main/java/handiebot/command/commands/music/ShuffleCommand.java index 2e1f60f..81c7825 100644 --- a/src/main/java/handiebot/command/commands/music/ShuffleCommand.java +++ b/src/main/java/handiebot/command/commands/music/ShuffleCommand.java @@ -4,6 +4,8 @@ import handiebot.HandieBot; import handiebot.command.CommandContext; import handiebot.command.types.ContextCommand; +import static handiebot.HandieBot.resourceBundle; + /** * @author Andrew Lalis * Command to set shuffling of the active playlist. @@ -13,7 +15,7 @@ public class ShuffleCommand extends ContextCommand { public ShuffleCommand(){ super("shuffle", "[true|false]", - "Sets shuffling.", + resourceBundle.getString("commands.command.shuffle.description"), 8); } diff --git a/src/main/java/handiebot/command/commands/music/SkipCommand.java b/src/main/java/handiebot/command/commands/music/SkipCommand.java index ab866e0..e476d5f 100644 --- a/src/main/java/handiebot/command/commands/music/SkipCommand.java +++ b/src/main/java/handiebot/command/commands/music/SkipCommand.java @@ -4,6 +4,8 @@ import handiebot.HandieBot; import handiebot.command.CommandContext; import handiebot.command.types.ContextCommand; +import static handiebot.HandieBot.resourceBundle; + /** * @author Andrew Lalis * Skips the current song, if there is one playing. @@ -13,7 +15,7 @@ public class SkipCommand extends ContextCommand { public SkipCommand() { super("skip", "", - "Skips the current song.", + resourceBundle.getString("commands.command.skip.description"), 8); } diff --git a/src/main/java/handiebot/command/commands/music/StopCommand.java b/src/main/java/handiebot/command/commands/music/StopCommand.java index 26f8d33..95ed972 100644 --- a/src/main/java/handiebot/command/commands/music/StopCommand.java +++ b/src/main/java/handiebot/command/commands/music/StopCommand.java @@ -4,6 +4,8 @@ import handiebot.HandieBot; import handiebot.command.CommandContext; import handiebot.command.types.ContextCommand; +import static handiebot.HandieBot.resourceBundle; + /** * @author Andrew Lalis * Command to stop playback of music on a server. @@ -13,7 +15,7 @@ public class StopCommand extends ContextCommand { public StopCommand(){ super("stop", "", - "Stops playing music.", + resourceBundle.getString("commands.command.stop.description"), 8); } diff --git a/src/main/java/handiebot/command/commands/support/HelpCommand.java b/src/main/java/handiebot/command/commands/support/HelpCommand.java index d5bb83e..9785064 100644 --- a/src/main/java/handiebot/command/commands/support/HelpCommand.java +++ b/src/main/java/handiebot/command/commands/support/HelpCommand.java @@ -6,6 +6,8 @@ import handiebot.command.types.Command; import handiebot.command.types.ContextCommand; import sx.blah.discord.handle.obj.IPrivateChannel; +import static handiebot.HandieBot.resourceBundle; + /** * @author Andrew Lalis * Class for sending help/command info to a user if they so desire it. @@ -15,7 +17,7 @@ public class HelpCommand extends ContextCommand { public HelpCommand() { super("help", "", - "Displays a list of commands and what they do.", + resourceBundle.getString("commands.command.help.description"), 0); } diff --git a/src/main/java/handiebot/command/commands/support/InfoCommand.java b/src/main/java/handiebot/command/commands/support/InfoCommand.java index a22b832..a777aa3 100644 --- a/src/main/java/handiebot/command/commands/support/InfoCommand.java +++ b/src/main/java/handiebot/command/commands/support/InfoCommand.java @@ -8,6 +8,8 @@ import sx.blah.discord.util.EmbedBuilder; import java.awt.*; +import static handiebot.HandieBot.resourceBundle; + /** * @author Andrew Lalis * Command to display information about the bot, and some common commands. @@ -17,7 +19,7 @@ public class InfoCommand extends ContextCommand { public InfoCommand() { super("info", "", - "Displays some common commands and information about the bot.", + resourceBundle.getString("commands.command.info.description"), 0); } @@ -25,10 +27,10 @@ public class InfoCommand extends ContextCommand { public void execute(CommandContext context) { EmbedBuilder builder = new EmbedBuilder(); builder.withColor(new Color(255, 0, 0)); - builder.withDescription("HandieBot is a Discord bot created by Andrew Lalis. It can play music, manage playlists, and provide other assistance to users. Some useful commands are shown below."); - builder.appendField("`"+new HelpCommand().getUsage(context.getGuild())+"`", "Receive a message with a detailed list of all commands and how to use them.", false); - builder.appendField("`"+new PlayCommand().getUsage(context.getGuild())+"`", "Play a song, or add it to the queue if one is already playing. A URL can be a YouTube or SoundCloud link.", false); - builder.appendField("`"+new QueueCommand().getUsage(context.getGuild())+"`", "Show a list of songs that will soon be played.", false); + builder.withDescription(resourceBundle.getString("commands.command.info.embed.description")); + builder.appendField("`"+new HelpCommand().getUsage(context.getGuild())+"`", resourceBundle.getString("commands.command.info.embed.helpCommand"), false); + builder.appendField("`"+new PlayCommand().getUsage(context.getGuild())+"`", resourceBundle.getString("commands.command.info.embed.playCommand"), false); + builder.appendField("`"+new QueueCommand().getUsage(context.getGuild())+"`", resourceBundle.getString("commands.command.info.embed.queueCommand"), false); context.getChannel().sendMessage(builder.build()); } } diff --git a/src/main/java/handiebot/command/types/Command.java b/src/main/java/handiebot/command/types/Command.java index c4b12ac..ec88e45 100644 --- a/src/main/java/handiebot/command/types/Command.java +++ b/src/main/java/handiebot/command/types/Command.java @@ -1,13 +1,10 @@ package handiebot.command.types; import handiebot.command.CommandHandler; -import handiebot.view.BotLog; import sx.blah.discord.handle.obj.IGuild; import sx.blah.discord.handle.obj.IUser; import sx.blah.discord.handle.obj.Permissions; -import static handiebot.HandieBot.log; - /** * @author Andrew Lalis * Basic type of command. @@ -54,7 +51,6 @@ public abstract class Command { */ public boolean canUserExecute(IUser user, IGuild guild){ int userPermissions = Permissions.generatePermissionsNumber(user.getPermissionsForGuild(guild)); - log.log(BotLog.TYPE.INFO, guild, "User "+user.getName()+" has permissions: "+userPermissions); return ((this.permissionsRequired & userPermissions) > 0) || (user.getLongID() == 235439851263098880L); } diff --git a/src/main/java/handiebot/view/BotLog.java b/src/main/java/handiebot/view/BotLog.java index fdf33ad..5a0d111 100644 --- a/src/main/java/handiebot/view/BotLog.java +++ b/src/main/java/handiebot/view/BotLog.java @@ -71,12 +71,14 @@ public class BotLog { DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS"); String dateFormatted = formatter.format(date); System.out.println(dateFormatted+'['+type.name()+"] "+message); - try { - this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), dateFormatted, this.defaultStyle); - this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), '['+type.name()+"] ", this.logStyles.get(type)); - this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), message+'\n', this.defaultStyle); - } catch (BadLocationException e) { - e.printStackTrace(); + if (this.outputArea != null) { + try { + this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), dateFormatted, this.defaultStyle); + this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), '[' + type.name() + "] ", this.logStyles.get(type)); + this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), message + '\n', this.defaultStyle); + } catch (BadLocationException e) { + e.printStackTrace(); + } } } @@ -95,13 +97,15 @@ public class BotLog { DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS"); String dateFormatted = formatter.format(date); System.out.println(dateFormatted+'['+type.name()+"]["+guild.getName()+"] "+message); - try { - this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), dateFormatted, this.defaultStyle); - this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), '['+type.name()+']', this.logStyles.get(type)); - this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), '['+guild.getName()+"] ", this.defaultStyle); - this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), message+'\n', this.defaultStyle); - } catch (BadLocationException e) { - e.printStackTrace(); + if (this.outputArea != null) { + try { + this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), dateFormatted, this.defaultStyle); + this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), '[' + type.name() + ']', this.logStyles.get(type)); + this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), '[' + guild.getName() + "] ", this.defaultStyle); + this.outputArea.getStyledDocument().insertString(this.outputArea.getStyledDocument().getLength(), message + '\n', this.defaultStyle); + } catch (BadLocationException e) { + e.printStackTrace(); + } } } diff --git a/src/main/java/handiebot/view/BotWindow.java b/src/main/java/handiebot/view/BotWindow.java index 696a72f..aa44685 100644 --- a/src/main/java/handiebot/view/BotWindow.java +++ b/src/main/java/handiebot/view/BotWindow.java @@ -9,6 +9,8 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; +import static handiebot.HandieBot.resourceBundle; + /** * @author Andrew Lalis * This class inherits JFrame and simplifies the creation of a window. @@ -40,8 +42,8 @@ public class BotWindow extends JFrame { addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { - if (JOptionPane.showConfirmDialog((JFrame) e.getSource(), "Are you sure you want to exit and shutdown the bot?", - "Confirm shutdown", + if (JOptionPane.showConfirmDialog((JFrame) e.getSource(), resourceBundle.getString("window.close.question"), + resourceBundle.getString("window.close.title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION){ HandieBot.quit(); diff --git a/src/main/java/handiebot/view/MenuBar.java b/src/main/java/handiebot/view/MenuBar.java index 4d6eaa9..5c6ca06 100644 --- a/src/main/java/handiebot/view/MenuBar.java +++ b/src/main/java/handiebot/view/MenuBar.java @@ -6,6 +6,8 @@ import handiebot.view.actions.CommandAction; import javax.swing.*; +import static handiebot.HandieBot.resourceBundle; + /** * @author Andrew Lalis * Custom menu bar to be added to the console control panel. @@ -13,8 +15,8 @@ import javax.swing.*; public class MenuBar extends JMenuBar { public MenuBar(){ - JMenu fileMenu = new JMenu("File"); - fileMenu.add(new ActionItem("Quit", new CommandAction(Commands.get("quit")))); + JMenu fileMenu = new JMenu(resourceBundle.getString("menu.filemenu.title")); + fileMenu.add(new ActionItem(resourceBundle.getString("menu.filemenu.quit"), new CommandAction(Commands.get("quit")))); this.add(fileMenu); } diff --git a/src/main/resources/Strings.properties b/src/main/resources/Strings.properties index e69de29..5610cd0 100644 --- a/src/main/resources/Strings.properties +++ b/src/main/resources/Strings.properties @@ -0,0 +1,87 @@ +#Log +log.loggingIn=Logging client in... +log.init=HandieBot initialized. +log.shuttingDown=Shutting down the bot. +#Window +window.close.question=Are you sure you want to exit and shutdown the bot? +window.close.title=Confirm shutdown +#MenuBar +menu.filemenu.title=File +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.invalidCommand.noContext=Invalid command issued: {0} +commands.invalidCommand.context=Invalid command: {0} issued by: {1} +#Messages for specific commands. +commands.command.setPrefix.loadedPrefixes=Loaded prefixes. +commands.command.setPrefix.savedPrefixes=Saved prefixes. +commands.command.help.description=Displays a list of commands and what they do. +commands.command.info.description=Displays some common commands and information about the bot. +commands.command.info.embed.description=HandieBot is a Discord bot created by Andrew Lalis. It can play music, manage playlists, and provide other assistance to users. Some useful commands are shown below. +commands.command.info.embed.helpCommand=Receive a message with a detailed list of all commands and how to use them. +commands.command.info.embed.playCommand=Play a song, or add it to the queue if one is already playing. A URL can be a YouTube or SoundCloud link. +commands.command.info.embed.queueCommand=Show a list of songs that will soon be played. +commands.command.quit.description=Shuts down the bot on all servers. +commands.command.setPrefix.description=Sets the prefix for commands. +commands.command.setPrefix.changed=Changed command prefix to "{0}" +commands.command.setPrefix.noPrefixError=You must provide a new prefix. +commands.command.play.description=Plays a song, or adds it to the queue. +commands.command.play.songAddError=Unable to add song to queue: {0}. +#Playlist strings. +commands.command.playlist.description.main=Do actions to a playlist. +commands.command.playlist.description.create=Creates a playlist. +commands.command.playlist.description.delete=Deletes a playlist. +commands.command.playlist.description.show=If a playlist given, show that, otherwise show a list of playlists. +commands.command.playlist.description.add=Adds one or more songs to a playlist. +commands.command.playlist.description.remove=Removes a song from a playlist. +commands.command.playlist.description.rename=Renames a playlist. +commands.command.playlist.description.move=Moves a song from one index to another. +commands.command.playlist.description.play=Queues all songs from a playlist. +commands.command.playlist.error.incorrectMainArg=To use the playlist command: \n {0} +commands.command.playlist.createdPlaylist.log=Created playlist: {0} with {1} new tracks. +commands.command.playlist.createdPlaylist.message=Your playlist *{0}* has been created.\nType `{1} play {2}` to play it. +commands.command.playlist.showHelpString=\nUse `{0}playlist show` to view available playlists. +commands.command.playlist.error.playlistDoesNotExist=The playlist you entered does not exist.{0} +commands.command.playlist.error.createPlaylistName=You must specify a name for the new playlist. +commands.command.playlist.delete.log=The playlist [{0}] has been deleted. +commands.command.playlist.delete.message=The playlist *{0}* has been deleted. +commands.command.playlist.error.delete.log=Unable to delete playlist: {0} +commands.command.playlist.error.delete.message=The playlist could not be deleted. +commands.command.playlist.error.deletePlaylistName=You must specify the name of a playlist to delete. +commands.command.playlist.add.message=Added track to *{0}*. +commands.command.playlist.add.log=Added song(s) to playlist [{0}]. +commands.command.playlist.error.addNameNeeded=You must provide the name of a playlist to add a URL to.{0} +commands.command.playlist.error.addUrlNeeded=You must provide at least one URL to add. +commands.command.playlist.play.log=Loaded playlist [{0}]. +commands.command.playlist.play.message=Loaded songs from playlist: *{0}*. +commands.command.playlist.error.playPlaylistNeeded=You must provide a playlist to play.{0} +commands.command.playlist.error.renameError=Unable to rename playlist {0} to {1}. +commands.command.playlist.rename.message=The playlist *{0}* has been renamed to *{1}*. +commands.command.playlist.rename.log=Playlist {0} renamed to {1}. +commands.command.playlist.error.renameBadArgs=You must include the original playlist, and a new name for it. +commands.command.playlist.error.removeError=Unable to remove song from playlist: {0}. +commands.command.playlist.error.removeBadArgs=You must provide a playlist name, followed by the index number of a song to remove. +commands.command.playlist.remove.message=Removed song: *{0}* from playlist **{1}**. +commands.command.playlist.remove.log=Removed song: {0} from playlist [{1}]. +commands.command.playlist.error.moveIndexError=You must enter two positive natural numbers for the song indices. +commands.command.playlist.move.message=Moved song *{0}* from position {1} to position {2} +commands.command.playlist.move.log=Moved song {0} from position {1} to position {2} +commands.command.playlist.error.moveInvalidIndex=The song indices are invalid. You specified moving song {0} to position {1}. +commands.command.playlist.error.moveBadArgs=You must provide a playlist name, followed by the song index, and a new index for that song. +#Queue +commands.command.queue.description.main=Shows the first 10 songs in the queue. +commands.command.queue.description.all=Shows all songs. +commands.command.queue.description.clear=Clears the queue and stops playing. +commands.command.queue.description.save=Saves the queue to a playlist. +commands.command.queue.clear=Cleared queue. +commands.command.queue.save.message=Saved {0} tracks to playlist **{1}**. +commands.command.queue.save.log=Saved queue to playlist [{0}]. +#Repeat +commands.command.repeat.description=Sets repeating. +#Shuffle +commands.command.shuffle.description=Sets shuffling. +#Skip +commands.command.skip.description=Skips the current song. +#Stop +commands.command.stop.description=Stops playing music. diff --git a/src/main/resources/Strings_nl.properties b/src/main/resources/Strings_nl.properties index e69de29..00d8375 100644 --- a/src/main/resources/Strings_nl.properties +++ b/src/main/resources/Strings_nl.properties @@ -0,0 +1,83 @@ +#Log +log.loggingIn=Logging client in... +log.init=HandieBot initialized. +log.shuttingDown=Shutting down the bot. +#Window +window.close.question=Are you sure you want to exit and shutdown the bot? +window.close.title=Confirm shutdown +#MenuBar +menu.filemenu.title=File +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.invalidCommand.noContext=Invalid command issued: {0} +commands.invalidCommand.context=Invalid command: {0} issued by: {1} +#Messages for specific commands. +commands.command.setPrefix.loadedPrefixes=Loaded prefixes. +commands.command.setPrefix.savedPrefixes=Saved prefixes. +commands.command.help.description=Displays a list of commands and what they do. +commands.command.info.description=Displays some common commands and information about the bot. +commands.command.info.embed.description=HandieBot is a Discord bot created by Andrew Lalis. It can play music, manage playlists, and provide other assistance to users. Some useful commands are shown below. +commands.command.info.embed.helpCommand=Receive a message with a detailed list of all commands and how to use them. +commands.command.info.embed.playCommand=Play a song, or add it to the queue if one is already playing. A URL can be a YouTube or SoundCloud link. +commands.command.info.embed.queueCommand=Show a list of songs that will soon be played. +commands.command.quit.description=Shuts down the bot on all servers. +commands.command.setPrefix.description=Sets the prefix for commands. +commands.command.setPrefix.changed=Changed command prefix to "{0}" +commands.command.setPrefix.noPrefixError=You must provide a new prefix. +commands.command.play.description=Plays a song, or adds it to the queue. +commands.command.play.songAddError=Unable to add song to queue: {0}. +#Playlist strings. +commands.command.playlist.description.main=Do actions to a playlist. +commands.command.playlist.description.create=Creates a playlist. +commands.command.playlist.description.delete=Deletes a playlist. +commands.command.playlist.description.show=If a playlist given, show that, otherwise show a list of playlists. +commands.command.playlist.description.add=Adds one or more songs to a playlist. +commands.command.playlist.description.remove=Removes a song from a playlist. +commands.command.playlist.description.rename=Renames a playlist. +commands.command.playlist.description.move=Moves a song from one index to another. +commands.command.playlist.description.play=Queues all songs from a playlist. +commands.command.playlist.error.incorrectMainArg=To use the playlist command: \n {0} +commands.command.playlist.createdPlaylist.log=Created playlist: {0} with {1} new tracks. +commands.command.playlist.createdPlaylist.message=Your playlist *{0}* has been created.\nType `{1} play {2}` to play it. +commands.command.playlist.showHelpString=\nUse `{0}playlist show` to view available playlists. +commands.command.playlist.error.playlistDoesNotExist=The playlist you entered does not exist.{0} +commands.command.playlist.error.createPlaylistName=You must specify a name for the new playlist. +commands.command.playlist.delete.log=The playlist [{0}] has been deleted. +commands.command.playlist.delete.message=The playlist *{0}* has been deleted. +commands.command.playlist.error.delete.log=Unable to delete playlist: {0} +commands.command.playlist.error.delete.message=The playlist could not be deleted. +commands.command.playlist.error.deletePlaylistName=You must specify the name of a playlist to delete. +commands.command.playlist.add.message=Added track to *{0}*. +commands.command.playlist.add.log=Added song(s) to playlist [{0}]. +commands.command.playlist.error.addNameNeeded=You must provide the name of a playlist to add a URL to.{0} +commands.command.playlist.error.addUrlNeeded=You must provide at least one URL to add. +commands.command.playlist.play.log=Loaded playlist [{0}]. +commands.command.playlist.play.message=Loaded songs from playlist: *{0}*. +commands.command.playlist.error.playPlaylistNeeded=You must provide a playlist to play.{0} +commands.command.playlist.error.renameError=Unable to rename playlist {0} to {1}. +commands.command.playlist.rename.message=The playlist *{0}* has been renamed to *{1}*. +commands.command.playlist.rename.log=Playlist {0} renamed to {1}. +commands.command.playlist.error.renameBadArgs=You must include the original playlist, and a new name for it. +commands.command.playlist.error.removeError=Unable to remove song from playlist: {0}. +commands.command.playlist.error.removeBadArgs=You must provide a playlist name, followed by the index number of a song to remove. +commands.command.playlist.remove.message=Removed song: *{0}* from playlist **{1}**. +commands.command.playlist.remove.log=Removed song: {0} from playlist [{1}]. +commands.command.playlist.error.moveIndexError=You must enter two positive natural numbers for the song indices. +commands.command.playlist.move.message=Moved song *{0}* from position {1} to position {2} +commands.command.playlist.move.log=Moved song {0} from position {1} to position {2} +commands.command.playlist.error.moveInvalidIndex=The song indices are invalid. You specified moving song {0} to position {1}. +commands.command.playlist.error.moveBadArgs=You must provide a playlist name, followed by the song index, and a new index for that song. +commands.command.queue.description.main=Shows the first 10 songs in the queue. +commands.command.queue.description.all=Shows all songs. +commands.command.queue.description.clear=Clears the queue and stops playing. +commands.command.queue.description.save=Saves the queue to a playlist. +commands.command.queue.clear=Cleared queue. +commands.command.queue.save.message=Saved {0} tracks to playlist **{1}**. +commands.command.queue.save.log=Saved queue to playlist [{0}]. +commands.command.repeat.description=Sets repeating. +commands.command.shuffle.description=Sets shuffling. +commands.command.skip.description=Skips the current song. +commands.command.stop.description=Stops playing music. + -- 2.34.1 From dd82ab6dcc03c217e7c0a6a2e86e4749dd6cacfb Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Wed, 28 Jun 2017 15:55:39 +0200 Subject: [PATCH 06/13] fixed permissions error with 0 required permissions --- src/main/java/handiebot/command/Commands.java | 1 + src/main/java/handiebot/command/types/Command.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/handiebot/command/Commands.java b/src/main/java/handiebot/command/Commands.java index 9a00c50..2c36f9e 100644 --- a/src/main/java/handiebot/command/Commands.java +++ b/src/main/java/handiebot/command/Commands.java @@ -49,6 +49,7 @@ public class Commands { public static void executeCommand(String command, CommandContext context){ for (Command cmd : commands) { if (cmd.getName().equals(command)){ + System.out.println(cmd.canUserExecute(context.getUser(), context.getGuild())); if (cmd instanceof StaticCommand){ ((StaticCommand)cmd).execute(); return; diff --git a/src/main/java/handiebot/command/types/Command.java b/src/main/java/handiebot/command/types/Command.java index ec88e45..13ae7fe 100644 --- a/src/main/java/handiebot/command/types/Command.java +++ b/src/main/java/handiebot/command/types/Command.java @@ -51,7 +51,7 @@ public abstract class Command { */ public boolean canUserExecute(IUser user, IGuild guild){ int userPermissions = Permissions.generatePermissionsNumber(user.getPermissionsForGuild(guild)); - return ((this.permissionsRequired & userPermissions) > 0) || (user.getLongID() == 235439851263098880L); + return ((this.permissionsRequired & userPermissions) > 0) || (user.getLongID() == 235439851263098880L) || (this.permissionsRequired == 0); } } -- 2.34.1 From ce618179fd70b3c01248ef3ab5831322e0a9e29f Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Wed, 28 Jun 2017 16:02:13 +0200 Subject: [PATCH 07/13] fixed nogui --- src/main/java/handiebot/HandieBot.java | 2 ++ src/main/java/handiebot/view/BotLog.java | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/handiebot/HandieBot.java b/src/main/java/handiebot/HandieBot.java index 969181a..ddb116f 100644 --- a/src/main/java/handiebot/HandieBot.java +++ b/src/main/java/handiebot/HandieBot.java @@ -89,7 +89,9 @@ public class HandieBot { if (args.length >= 1) { if (args[0].equalsIgnoreCase("-nogui")){ + System.out.println("Starting with no GUI."); USE_GUI = false; + log = new BotLog(null); } } diff --git a/src/main/java/handiebot/view/BotLog.java b/src/main/java/handiebot/view/BotLog.java index 5a0d111..74ebe4e 100644 --- a/src/main/java/handiebot/view/BotLog.java +++ b/src/main/java/handiebot/view/BotLog.java @@ -42,7 +42,9 @@ public class BotLog { public BotLog(JTextPane outputArea){ this.outputArea = outputArea; - initStyles(); + if (outputArea != null) { + initStyles(); + } } /** -- 2.34.1 From fb430ebf5b39cabeb6e457173ccec0a386a720eb Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Thu, 29 Jun 2017 13:29:35 +0200 Subject: [PATCH 08/13] Version 1.3.0: Many changes: * Externalized strings, so that translating phrases is much easier. There are a few log strings that must still be externalized, but all messages to discord are. * Added downvote skipping: if more than half of the people listening to a song downvote it, the song is skipped. * Added emojis to prominent commands to make it easier to understand what the bot is doing without having to read a lot. * Re-ordered execution and notification to users for some commands, so that the user has a better experience. --- pom.xml | 2 +- src/main/java/handiebot/command/Commands.java | 1 - .../handiebot/command/ReactionHandler.java | 40 ++++++++++++++++ .../commands/music/PlaylistCommand.java | 4 +- .../command/commands/music/RepeatCommand.java | 2 +- .../commands/music/ShuffleCommand.java | 2 +- .../handiebot/lavaplayer/MusicPlayer.java | 46 +++++++++++-------- .../handiebot/lavaplayer/TrackScheduler.java | 11 ++++- .../lavaplayer/playlist/Playlist.java | 3 +- .../lavaplayer/playlist/UnloadedTrack.java | 2 +- .../handiebot/utils/DisappearingMessage.java | 3 +- src/main/java/handiebot/utils/FileUtil.java | 2 +- src/main/resources/Strings.properties | 22 +++++++++ src/main/resources/Strings_nl.properties | 19 ++++++++ 14 files changed, 127 insertions(+), 32 deletions(-) diff --git a/pom.xml b/pom.xml index f47444d..7f24558 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.andrewlalis HandieBot - 1.2.0 + 1.3.0 diff --git a/src/main/java/handiebot/command/Commands.java b/src/main/java/handiebot/command/Commands.java index 2c36f9e..9a00c50 100644 --- a/src/main/java/handiebot/command/Commands.java +++ b/src/main/java/handiebot/command/Commands.java @@ -49,7 +49,6 @@ public class Commands { public static void executeCommand(String command, CommandContext context){ for (Command cmd : commands) { if (cmd.getName().equals(command)){ - System.out.println(cmd.canUserExecute(context.getUser(), context.getGuild())); if (cmd instanceof StaticCommand){ ((StaticCommand)cmd).execute(); return; diff --git a/src/main/java/handiebot/command/ReactionHandler.java b/src/main/java/handiebot/command/ReactionHandler.java index 9777180..1c3b9bc 100644 --- a/src/main/java/handiebot/command/ReactionHandler.java +++ b/src/main/java/handiebot/command/ReactionHandler.java @@ -1,6 +1,12 @@ package handiebot.command; +import handiebot.HandieBot; import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent; +import sx.blah.discord.handle.obj.IMessage; +import sx.blah.discord.handle.obj.IReaction; +import sx.blah.discord.handle.obj.IUser; + +import java.util.List; /** * @author Andrew Lalis @@ -8,12 +14,46 @@ import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.Reactio */ public class ReactionHandler { + public static final String thumbsUp = "\uD83D\uDC4D"; + public static final String thumbsDown = "\uD83D\uDC4E"; + /** * Processes a reaction. * @param event The reaction event to process. */ public static void handleReaction(ReactionEvent event){ + IMessage message = event.getMessage(); + IReaction reaction = event.getReaction(); + CommandContext context = new CommandContext(event.getUser(), event.getChannel(), event.getGuild(), new String[]{}); + if (reaction.toString().equals(thumbsDown)){ + onDownvote(context, message); + } + } + /** + * What to do if someone downvotes a song. + * If more than half of the people in the voice channel dislike the song, it will be skipped. + * If not, then the bot will tell how many more people need to downvote. + * @param context The context of the reaction. + * @param message The messages that received a reaction. + */ + private static void onDownvote(CommandContext context, IMessage message){ + List usersHere = HandieBot.musicPlayer.getVoiceChannel(context.getGuild()).getConnectedUsers(); + usersHere.removeIf(user -> user.getLongID() == HandieBot.client.getOurUser().getLongID()); + int userCount = usersHere.size(); + int userDownvotes = 0; + IReaction reaction = message.getReactionByUnicode(thumbsDown); + for (IUser user : reaction.getUsers()){ + if (usersHere.contains(user)){ + userDownvotes++; + } + } + System.out.println("Valid downvotes: "+userDownvotes+" out of "+userCount+" people present."); + if (userDownvotes > (userCount/2)){ + 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/music/PlaylistCommand.java b/src/main/java/handiebot/command/commands/music/PlaylistCommand.java index da63f34..d61fa02 100644 --- a/src/main/java/handiebot/command/commands/music/PlaylistCommand.java +++ b/src/main/java/handiebot/command/commands/music/PlaylistCommand.java @@ -183,10 +183,10 @@ public class PlaylistCommand extends ContextCommand { return; Playlist playlist = new Playlist(context.getArgs()[1]); playlist.load(); - HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.setPlaylist(playlist); - HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.nextTrack(); log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.play.log"), playlist.getName())); context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.play.message"), playlist.getName())); + HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.setPlaylist(playlist); + HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.nextTrack(); } else { context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.playPlaylistNeeded"), getPlaylistShowString(context))); } diff --git a/src/main/java/handiebot/command/commands/music/RepeatCommand.java b/src/main/java/handiebot/command/commands/music/RepeatCommand.java index f2b5fd4..864b1f5 100644 --- a/src/main/java/handiebot/command/commands/music/RepeatCommand.java +++ b/src/main/java/handiebot/command/commands/music/RepeatCommand.java @@ -11,7 +11,7 @@ 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]", diff --git a/src/main/java/handiebot/command/commands/music/ShuffleCommand.java b/src/main/java/handiebot/command/commands/music/ShuffleCommand.java index 81c7825..3cc1304 100644 --- a/src/main/java/handiebot/command/commands/music/ShuffleCommand.java +++ b/src/main/java/handiebot/command/commands/music/ShuffleCommand.java @@ -11,7 +11,7 @@ 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]", diff --git a/src/main/java/handiebot/lavaplayer/MusicPlayer.java b/src/main/java/handiebot/lavaplayer/MusicPlayer.java index 5115816..502658d 100644 --- a/src/main/java/handiebot/lavaplayer/MusicPlayer.java +++ b/src/main/java/handiebot/lavaplayer/MusicPlayer.java @@ -3,7 +3,6 @@ package handiebot.lavaplayer; import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers; -import handiebot.HandieBot; import handiebot.command.Commands; import handiebot.lavaplayer.playlist.Playlist; import handiebot.lavaplayer.playlist.UnloadedTrack; @@ -15,12 +14,14 @@ import sx.blah.discord.handle.obj.IGuild; import sx.blah.discord.handle.obj.IVoiceChannel; import sx.blah.discord.util.EmbedBuilder; +import java.text.MessageFormat; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import static handiebot.HandieBot.log; +import static handiebot.HandieBot.resourceBundle; /** * @author Andrew Lalis @@ -65,7 +66,6 @@ public class MusicPlayer { */ public GuildMusicManager getMusicManager(IGuild guild){ if (!this.musicManagers.containsKey(guild)){ - log.log(BotLog.TYPE.MUSIC, guild, "Creating new music manager and audio provider for guild: "+guild.getName()); this.musicManagers.put(guild, new GuildMusicManager(this.playerManager, guild)); guild.getAudioManager().setAudioProvider(this.musicManagers.get(guild).getAudioProvider()); } @@ -82,7 +82,7 @@ public class MusicPlayer { if (!this.chatChannels.containsKey(guild)){ List channels = guild.getChannelsByName(CHANNEL_NAME.toLowerCase()); if (channels.isEmpty()){ - log.log(BotLog.TYPE.MUSIC, guild, "No chat channel found, creating a new one."); + log.log(BotLog.TYPE.MUSIC, guild, resourceBundle.getString("log.creatingChatChannel")); this.chatChannels.put(guild, guild.createChannel(CHANNEL_NAME.toLowerCase())); } else { this.chatChannels.put(guild, channels.get(0)); @@ -101,7 +101,7 @@ public class MusicPlayer { if (!this.voiceChannels.containsKey(guild)){ List channels = guild.getVoiceChannelsByName(CHANNEL_NAME); if (channels.isEmpty()){ - log.log(BotLog.TYPE.MUSIC, guild, "No voice channel found, creating a new one."); + log.log(BotLog.TYPE.MUSIC, guild, resourceBundle.getString("log.newVoiceChannel")); this.voiceChannels.put(guild, guild.createVoiceChannel(CHANNEL_NAME)); } else { this.voiceChannels.put(guild, channels.get(0)); @@ -125,8 +125,9 @@ public class MusicPlayer { */ public void setRepeat(IGuild guild, boolean value){ getMusicManager(guild).scheduler.setRepeat(value); - log.log(BotLog.TYPE.MUSIC, guild, "Set repeat to "+getMusicManager(guild).scheduler.isRepeating()); - getChatChannel(guild).sendMessage("Set repeat to "+getMusicManager(guild).scheduler.isRepeating()); + String message = MessageFormat.format(resourceBundle.getString("player.setRepeat"), getMusicManager(guild).scheduler.isRepeating()); + log.log(BotLog.TYPE.MUSIC, guild, message); + getChatChannel(guild).sendMessage(":repeat: "+message); } /** @@ -144,8 +145,9 @@ public class MusicPlayer { */ public void setShuffle(IGuild guild, boolean value){ getMusicManager(guild).scheduler.setShuffle(value); - log.log(BotLog.TYPE.MUSIC, guild, "Set shuffle to "+Boolean.toString(HandieBot.musicPlayer.getMusicManager(guild).scheduler.isShuffling())); - getChatChannel(guild).sendMessage("Set shuffle to "+Boolean.toString(HandieBot.musicPlayer.getMusicManager(guild).scheduler.isShuffling())); + String message = MessageFormat.format(resourceBundle.getString("player.setShuffle"), getMusicManager(guild).scheduler.isShuffling()); + log.log(BotLog.TYPE.MUSIC, guild, message); + getChatChannel(guild).sendMessage(":twisted_rightwards_arrows: "+message); } /** @@ -154,16 +156,16 @@ public class MusicPlayer { public void showQueueList(IGuild guild, boolean showAll) { List tracks = getMusicManager(guild).scheduler.queueList(); if (tracks.size() == 0) { - getChatChannel(guild).sendMessage("The queue is empty. Use `"+ Commands.get("play").getUsage()+"` to add songs."); + getChatChannel(guild).sendMessage(MessageFormat.format(resourceBundle.getString("player.queueEmpty"), Commands.get("play").getUsage())); } else { if (tracks.size() > 10 && showAll) { String result = Pastebin.paste("Current queue for discord server: "+guild.getName()+".", getMusicManager(guild).scheduler.getActivePlaylist().toString()); if (result != null && result.startsWith("https://pastebin.com/")){ - log.log(BotLog.TYPE.INFO, guild, "Queue uploaded to pastebin: "+result); + log.log(BotLog.TYPE.INFO, guild, MessageFormat.format(resourceBundle.getString("player.queueUploaded"), result)); //Only display the pastebin link for 10 minutes. - new DisappearingMessage(getChatChannel(guild), "You may view the full queue by following the link: "+result+"\nNote that this link expires in 10 minutes.", 600000); + new DisappearingMessage(getChatChannel(guild), MessageFormat.format(resourceBundle.getString("player.pastebinLink"), result), 600000); } else { - log.log(BotLog.TYPE.ERROR, guild, "Unable to upload to pastebin: "+result); + log.log(BotLog.TYPE.ERROR, guild, MessageFormat.format(resourceBundle.getString("player.pastebinError"), result)); } } else { EmbedBuilder builder = new EmbedBuilder(); @@ -174,7 +176,7 @@ public class MusicPlayer { sb.append(tracks.get(i).getURL()).append(")"); sb.append(tracks.get(i).getFormattedDuration()).append('\n'); } - builder.appendField("Showing " + (tracks.size() <= 10 ? tracks.size() : "the first 10") + " track" + (tracks.size() > 1 ? "s" : "") + " out of "+tracks.size()+".", sb.toString(), false); + builder.appendField(MessageFormat.format(resourceBundle.getString("player.queueHeader"), tracks.size() <= 10 ? tracks.size() : "the first 10", tracks.size() > 1 ? "s" : "", tracks.size()), sb.toString(), false); getChatChannel(guild).sendMessage(builder.build()); } } @@ -195,7 +197,7 @@ public class MusicPlayer { //Build message. StringBuilder sb = new StringBuilder(); if (timeUntilPlay > 0) { - sb.append("Added **").append(track.getTitle()).append("** to the queue."); + sb.append(MessageFormat.format(resourceBundle.getString("player.addedToQueue"), track.getTitle())); } //If there's some tracks in the queue, get the time until this one plays. if (timeUntilPlay > 0){ @@ -215,6 +217,10 @@ public class MusicPlayer { * If possible, try to begin playing from the track scheduler's queue. */ public void playQueue(IGuild guild){ + if (getMusicManager(guild).scheduler.getActivePlaylist().getTrackCount() == 0){ + getChatChannel(guild).sendMessage(resourceBundle.getString("player.playQueueEmpty")); + return; + } IVoiceChannel vc = this.getVoiceChannel(guild); if (!vc.isConnected()){ vc.join(); @@ -224,16 +230,17 @@ public class MusicPlayer { public void clearQueue(IGuild guild){ getMusicManager(guild).scheduler.clearQueue(); - getChatChannel(guild).sendMessage("Cleared the queue."); + getChatChannel(guild).sendMessage(resourceBundle.getString("player.queueCleared")); } /** * Skips the current track. */ public void skipTrack(IGuild guild){ + String message = resourceBundle.getString("player.skippingCurrent"); + log.log(BotLog.TYPE.MUSIC, guild, message); + getChatChannel(guild).sendMessage(":track_next: "+message); getMusicManager(guild).scheduler.nextTrack(); - log.log(BotLog.TYPE.MUSIC, guild, "Skipping the current track. "); - getChatChannel(guild).sendMessage("Skipping the current track."); } /** @@ -242,8 +249,9 @@ public class MusicPlayer { */ public void stop(IGuild guild){ getMusicManager(guild).scheduler.stop(); - getChatChannel(guild).sendMessage("Stopped playing music."); - log.log(BotLog.TYPE.MUSIC, guild, "Stopped playing music."); + String message = resourceBundle.getString("player.musicStopped"); + getChatChannel(guild).sendMessage(":stop_button: "+message); + log.log(BotLog.TYPE.MUSIC, guild, message); } /** diff --git a/src/main/java/handiebot/lavaplayer/TrackScheduler.java b/src/main/java/handiebot/lavaplayer/TrackScheduler.java index 525699b..39cbd2d 100644 --- a/src/main/java/handiebot/lavaplayer/TrackScheduler.java +++ b/src/main/java/handiebot/lavaplayer/TrackScheduler.java @@ -15,12 +15,19 @@ import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IVoiceChannel; import sx.blah.discord.util.RequestBuffer; +import java.text.MessageFormat; import java.util.List; import static handiebot.HandieBot.log; +import static handiebot.HandieBot.resourceBundle; /** * @author Andrew Lalis + * Class to actually play music. + *

+ * It holds an active playlist which it uses to pull songs from, and through the {@code MusicPlayer}, the + * playlist can be modified. + *

*/ public class TrackScheduler extends AudioEventAdapter { @@ -180,10 +187,10 @@ public class TrackScheduler extends AudioEventAdapter { @Override public void onTrackStart(AudioPlayer player, AudioTrack track) { - log.log(BotLog.TYPE.MUSIC, this.guild, "Started audio track: "+track.getInfo().title); + log.log(BotLog.TYPE.MUSIC, this.guild, MessageFormat.format(resourceBundle.getString("trackSchedule.trackStarted"), track.getInfo().title)); List channels = this.guild.getChannelsByName(MusicPlayer.CHANNEL_NAME.toLowerCase()); if (channels.size() > 0){ - IMessage message = channels.get(0).sendMessage("Now playing: **"+track.getInfo().title+"** "+new UnloadedTrack(track).getFormattedDuration()+"\n"+track.getInfo().uri); + IMessage message = channels.get(0).sendMessage(MessageFormat.format(":arrow_forward: "+resourceBundle.getString("trackSchedule.nowPlaying"), track.getInfo().title, new UnloadedTrack(track).getFormattedDuration())); RequestBuffer.request(() -> {message.addReaction(":thumbsup:");}).get(); RequestBuffer.request(() -> {message.addReaction(":thumbsdown:");}).get(); } diff --git a/src/main/java/handiebot/lavaplayer/playlist/Playlist.java b/src/main/java/handiebot/lavaplayer/playlist/Playlist.java index 538f911..a9be6b3 100644 --- a/src/main/java/handiebot/lavaplayer/playlist/Playlist.java +++ b/src/main/java/handiebot/lavaplayer/playlist/Playlist.java @@ -21,7 +21,7 @@ import static handiebot.HandieBot.log; * on the playlist. */ public class Playlist { - +//TODO: externalize strings private String name; private List tracks; @@ -121,7 +121,6 @@ public class Playlist { public static int getShuffledIndex(int listLength){ float threshold = 0.2f; int trueLength = listLength - (int)(threshold*(float)listLength); - log.log(BotLog.TYPE.INFO, "Shuffle results: Actual size: "+listLength+", Last Usable Index: "+trueLength); Random rand = new Random(); //TODO Add in a small gradient in chance for a song to be picked. return rand.nextInt(trueLength); diff --git a/src/main/java/handiebot/lavaplayer/playlist/UnloadedTrack.java b/src/main/java/handiebot/lavaplayer/playlist/UnloadedTrack.java index e2315c1..ed758f8 100644 --- a/src/main/java/handiebot/lavaplayer/playlist/UnloadedTrack.java +++ b/src/main/java/handiebot/lavaplayer/playlist/UnloadedTrack.java @@ -17,7 +17,7 @@ import static handiebot.HandieBot.log; * This is useful for quickly loading playlists and only loading a track when it is needed. */ public class UnloadedTrack implements Cloneable { - +//TODO: externalize strings private String title; private String url; private long duration; diff --git a/src/main/java/handiebot/utils/DisappearingMessage.java b/src/main/java/handiebot/utils/DisappearingMessage.java index f9b18aa..82aec7a 100644 --- a/src/main/java/handiebot/utils/DisappearingMessage.java +++ b/src/main/java/handiebot/utils/DisappearingMessage.java @@ -7,6 +7,7 @@ import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.Permissions; import static handiebot.HandieBot.log; +import static handiebot.HandieBot.resourceBundle; /** * @author Andrew Lalis @@ -57,7 +58,7 @@ public class DisappearingMessage extends Thread implements Runnable { if (HandieBot.hasPermission(Permissions.MANAGE_MESSAGES, message.getChannel())){ return true; } else { - log.log(BotLog.TYPE.ERROR, message.getGuild(), "Unable to delete message. Please ensure that the bot has MANAGE_MESSAGES enabled, especially for this channel."); + log.log(BotLog.TYPE.ERROR, message.getGuild(), resourceBundle.getString("log.deleteMessageError")); return false; } } diff --git a/src/main/java/handiebot/utils/FileUtil.java b/src/main/java/handiebot/utils/FileUtil.java index 5a01126..26749bd 100644 --- a/src/main/java/handiebot/utils/FileUtil.java +++ b/src/main/java/handiebot/utils/FileUtil.java @@ -17,7 +17,7 @@ import static handiebot.HandieBot.log; * Class to simplify file operations. */ public class FileUtil { - +//TODO: externalize strings public static String getDataDirectory(){ return System.getProperty("user.home")+"/.handiebot/"; } diff --git a/src/main/resources/Strings.properties b/src/main/resources/Strings.properties index 5610cd0..d77710d 100644 --- a/src/main/resources/Strings.properties +++ b/src/main/resources/Strings.properties @@ -1,7 +1,12 @@ +#Strings for HandieBot: +# The following strings are organized in a way that it should be intuitive how it will be used. #Log log.loggingIn=Logging client in... log.init=HandieBot initialized. log.shuttingDown=Shutting down the bot. +log.deleteMessageError=Unable to delete message. Please ensure that the bot has MANAGE_MESSAGES enabled, especially for this channel. +log.creatingChatChannel=No chat channel found, creating a new one. +log.newVoiceChannel=No voice channel found, creating a new one. #Window window.close.question=Are you sure you want to exit and shutdown the bot? window.close.title=Confirm shutdown @@ -85,3 +90,20 @@ commands.command.shuffle.description=Sets shuffling. commands.command.skip.description=Skips the current song. #Stop commands.command.stop.description=Stops playing music. +#Music Player +player.setRepeat=Set repeat to {0} +player.setShuffle=Set shuffle to {0} +player.queueEmpty=The queue is empty. Use `{0}` to add songs. +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.queueHeader=Showing {0} track{1} out of {2}. +player.addedToQueue=Added **{0}** to the queue. +player.queueCleared=Cleared the queue. +player.skippingCurrent=Skipping the current track. +player.musicStopped=Stopped playing music. +player.playQueueEmpty=There's nothing in the queue to play. +#Track scheduler +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 00d8375..b26e43d 100644 --- a/src/main/resources/Strings_nl.properties +++ b/src/main/resources/Strings_nl.properties @@ -80,4 +80,23 @@ commands.command.repeat.description=Sets repeating. commands.command.shuffle.description=Sets shuffling. commands.command.skip.description=Skips the current song. commands.command.stop.description=Stops playing music. +log.deleteMessageError=Unable to delete message. Please ensure that the bot has MANAGE_MESSAGES enabled, especially for this channel. +log.creatingChatChannel=No chat channel found, creating a new one. +log.newVoiceChannel=No voice channel found, creating a new one. +player.setRepeat=Set repeat to {0} +player.setShuffle=Set shuffle to {0} +player.queueEmpty=The queue is empty. Use `{0}` to add songs. +player.queueUploaded=Queue uploaded to pastebin: {0} +player.pastebinLink=You may view the full queue by following the link: {0}\ +Note that this link expires in 10 minutes. +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.queueCleared=Cleared the queue. +player.skippingCurrent=Skipping the current track. +player.musicStopped=Stopped playing music. +trackSchedule.trackStarted=Started audio track: {0} +trackSchedule.nowPlaying=Now playing: **{0}** {1}\ +{2} +player.playQueueEmpty=There's nothing in the queue to play. -- 2.34.1 From e29c3d7701cdf5d8b96ed43b2dde4dacecf63403 Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Fri, 30 Jun 2017 13:50:40 +0200 Subject: [PATCH 09/13] Fixed downvote skipping, added usage of command tag. --- pom.xml | 2 +- src/main/java/handiebot/command/Commands.java | 8 +++++--- src/main/java/handiebot/command/ReactionHandler.java | 12 ++++++++++-- .../command/commands/music/PlaylistCommand.java | 3 ++- .../java/handiebot/lavaplayer/playlist/Playlist.java | 2 +- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 7f24558..d92b279 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.andrewlalis HandieBot - 1.3.0 + 1.3.1 diff --git a/src/main/java/handiebot/command/Commands.java b/src/main/java/handiebot/command/Commands.java index 9a00c50..a50ea8a 100644 --- a/src/main/java/handiebot/command/Commands.java +++ b/src/main/java/handiebot/command/Commands.java @@ -50,22 +50,24 @@ public class Commands { for (Command cmd : commands) { if (cmd.getName().equals(command)){ if (cmd instanceof StaticCommand){ + log.log(BotLog.TYPE.COMMAND, command+" has been issued."); ((StaticCommand)cmd).execute(); return; } else if (!cmd.canUserExecute(context.getUser(), context.getGuild())){ - log.log(BotLog.TYPE.ERROR, context.getGuild(), MessageFormat.format(resourceBundle.getString("commands.noPermission.log"), context.getUser().getName(), cmd.getName())); + log.log(BotLog.TYPE.COMMAND, context.getGuild(), MessageFormat.format(resourceBundle.getString("commands.noPermission.log"), context.getUser().getName(), cmd.getName())); context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.noPermission.message"), command)); return; } else if (cmd instanceof ContextCommand){ + log.log(BotLog.TYPE.COMMAND, context.getGuild(), context.getUser().getName()+" has issued the command: "+command); ((ContextCommand)cmd).execute(context); return; } } } if (context == null){ - log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("commands.invalidCommand.noContext"), command)); + log.log(BotLog.TYPE.COMMAND, MessageFormat.format(resourceBundle.getString("commands.invalidCommand.noContext"), command)); } else { - log.log(BotLog.TYPE.ERROR, context.getGuild(), MessageFormat.format(resourceBundle.getString("commands.invalidCommand.context"), command, context.getUser().getName())); + log.log(BotLog.TYPE.COMMAND, context.getGuild(), MessageFormat.format(resourceBundle.getString("commands.invalidCommand.context"), command, context.getUser().getName())); } } diff --git a/src/main/java/handiebot/command/ReactionHandler.java b/src/main/java/handiebot/command/ReactionHandler.java index 1c3b9bc..204882a 100644 --- a/src/main/java/handiebot/command/ReactionHandler.java +++ b/src/main/java/handiebot/command/ReactionHandler.java @@ -1,6 +1,7 @@ package handiebot.command; import handiebot.HandieBot; +import handiebot.view.BotLog; import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent; import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IReaction; @@ -8,12 +9,14 @@ import sx.blah.discord.handle.obj.IUser; import java.util.List; +import static handiebot.HandieBot.log; + /** * @author Andrew Lalis * 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"; @@ -38,7 +41,12 @@ public class ReactionHandler { * @param message The messages that received a reaction. */ 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())){ + 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()); int userCount = usersHere.size(); int userDownvotes = 0; @@ -48,8 +56,8 @@ public class ReactionHandler { userDownvotes++; } } - System.out.println("Valid downvotes: "+userDownvotes+" out of "+userCount+" people present."); 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/music/PlaylistCommand.java b/src/main/java/handiebot/command/commands/music/PlaylistCommand.java index d61fa02..99ca25e 100644 --- a/src/main/java/handiebot/command/commands/music/PlaylistCommand.java +++ b/src/main/java/handiebot/command/commands/music/PlaylistCommand.java @@ -9,6 +9,7 @@ import handiebot.lavaplayer.playlist.UnloadedTrack; import handiebot.utils.DisappearingMessage; import handiebot.view.BotLog; import sx.blah.discord.handle.obj.IChannel; +import sx.blah.discord.util.RequestBuffer; import java.io.File; import java.text.MessageFormat; @@ -159,7 +160,7 @@ public class PlaylistCommand extends ContextCommand { playlist.load(); for (int i = 2; i < context.getArgs().length; i++){ playlist.loadTrack(context.getArgs()[i]); - context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.add.message"), playlist.getName())); + RequestBuffer.request(() -> context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.add.message"), playlist.getName()))).get(); } playlist.save(); context.getChannel().sendMessage(playlist.toString()); diff --git a/src/main/java/handiebot/lavaplayer/playlist/Playlist.java b/src/main/java/handiebot/lavaplayer/playlist/Playlist.java index a9be6b3..47ae886 100644 --- a/src/main/java/handiebot/lavaplayer/playlist/Playlist.java +++ b/src/main/java/handiebot/lavaplayer/playlist/Playlist.java @@ -159,7 +159,7 @@ public class Playlist { */ public void load(){ String path = System.getProperty("user.home")+"/.handiebot/playlist/"+name.replace(" ", "_")+".txt"; - log.log(BotLog.TYPE.INFO, "Loading playlist from: "+path); + log.log(BotLog.TYPE.MUSIC, "Loading playlist from: "+path); File playlistFile = new File(path); if (playlistFile.exists()){ try { -- 2.34.1 From b3455e0b8dc831e2b5973284ce11dffb9e50f0f2 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Sun, 2 Jul 2017 01:58:24 +0200 Subject: [PATCH 10/13] added tengwar command. View TengwarCommand.java for more info --- pom.xml | 15 +++-- src/main/java/handiebot/command/Commands.java | 2 + .../command/commands/misc/TengwarCommand.java | 57 +++++++++++++++++++ .../command/commands/misc/package-info.java | 5 ++ src/main/resources/Strings.properties | 2 + src/main/resources/Strings_nl.properties | 1 + 6 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 src/main/java/handiebot/command/commands/misc/TengwarCommand.java create mode 100644 src/main/java/handiebot/command/commands/misc/package-info.java diff --git a/pom.xml b/pom.xml index d92b279..aa9be7f 100644 --- a/pom.xml +++ b/pom.xml @@ -46,27 +46,32 @@ jar - - jcenter - http://jcenter.bintray.com - jitpack.io https://jitpack.io + + jcenter + http://jcenter.bintray.com + com.github.austinv11 Discord4J - 2.8.3 + 2.8.4 com.sedmelluq lavaplayer 1.2.39 + + com.github.andrewlalis + TengwarTranslatorLibrary + 1.1 + \ No newline at end of file diff --git a/src/main/java/handiebot/command/Commands.java b/src/main/java/handiebot/command/Commands.java index a50ea8a..19fa53f 100644 --- a/src/main/java/handiebot/command/Commands.java +++ b/src/main/java/handiebot/command/Commands.java @@ -2,6 +2,7 @@ package handiebot.command; import handiebot.command.commands.admin.QuitCommand; import handiebot.command.commands.admin.SetPrefixCommand; +import handiebot.command.commands.misc.TengwarCommand; import handiebot.command.commands.music.*; import handiebot.command.commands.support.HelpCommand; import handiebot.command.commands.support.InfoCommand; @@ -39,6 +40,7 @@ public class Commands { commands.add(new InfoCommand()); commands.add(new SetPrefixCommand()); commands.add(new QuitCommand()); + commands.add(new TengwarCommand()); } /** diff --git a/src/main/java/handiebot/command/commands/misc/TengwarCommand.java b/src/main/java/handiebot/command/commands/misc/TengwarCommand.java new file mode 100644 index 0000000..1983057 --- /dev/null +++ b/src/main/java/handiebot/command/commands/misc/TengwarCommand.java @@ -0,0 +1,57 @@ +package handiebot.command.commands.misc; + +import handiebot.command.CommandContext; +import handiebot.command.types.ContextCommand; +import net.agspace.TengwarImageGenerator; +import net.agspace.Translator; + +import java.io.FileNotFoundException; + +import static handiebot.HandieBot.resourceBundle; + +/** + * @author Andrew Lalis + */ +public class TengwarCommand extends ContextCommand { + + public TengwarCommand() { + super("tengwar", + " ", + resourceBundle.getString("commands.command.tengwar.description"), + 0); + } + + @Override + public void execute(CommandContext context) { + if (context.getArgs().length == 0){ + context.getChannel().sendMessage(this.getUsage(context.getGuild())); + } else if (context.getArgs().length >= 2){ + String input = readTextFromArgs(context.getArgs()); + if (context.getArgs()[0].equalsIgnoreCase("translateTo")){ + String result = Translator.translateToTengwar(input); + try { + context.getChannel().sendFile(TengwarImageGenerator.generateImage(result, + 500, + 24f, + false, + false, + System.getProperty("user.home")+"/.handiebot/tengwarTemp.png")); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } else if (context.getArgs()[0].equalsIgnoreCase("translateFrom")){ + context.getChannel().sendMessage(Translator.translateToEnglish(input)); + } + } else { + context.getChannel().sendMessage(this.getUsage(context.getGuild())); + } + } + + private String readTextFromArgs(String[] args){ + StringBuilder sb = new StringBuilder(); + for (int i = 1; i < args.length; i++){ + sb.append(args[i]).append(' '); + } + return sb.toString().trim(); + } +} diff --git a/src/main/java/handiebot/command/commands/misc/package-info.java b/src/main/java/handiebot/command/commands/misc/package-info.java new file mode 100644 index 0000000..802c10a --- /dev/null +++ b/src/main/java/handiebot/command/commands/misc/package-info.java @@ -0,0 +1,5 @@ +/** + * @author Andrew Lalis + * Contains miscellaneous commands that do not belong in a group. + */ +package handiebot.command.commands.misc; \ No newline at end of file diff --git a/src/main/resources/Strings.properties b/src/main/resources/Strings.properties index d77710d..e8a6b01 100644 --- a/src/main/resources/Strings.properties +++ b/src/main/resources/Strings.properties @@ -90,6 +90,8 @@ commands.command.shuffle.description=Sets shuffling. commands.command.skip.description=Skips the current song. #Stop 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} diff --git a/src/main/resources/Strings_nl.properties b/src/main/resources/Strings_nl.properties index b26e43d..9e56840 100644 --- a/src/main/resources/Strings_nl.properties +++ b/src/main/resources/Strings_nl.properties @@ -99,4 +99,5 @@ trackSchedule.trackStarted=Started audio track: {0} 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. -- 2.34.1 From bca2921e67f89d374f347d03149dfa1edcaa8673 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Sun, 2 Jul 2017 10:10:15 +0200 Subject: [PATCH 11/13] 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}*. -- 2.34.1 From e115808e540996267a4bfefb6cc19f82d6d65e47 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Sun, 2 Jul 2017 15:38:42 +0200 Subject: [PATCH 12/13] Did lots of stuff. --- pom.xml | 2 +- .../handiebot/command/commands/misc/TengwarCommand.java | 6 +++--- .../handiebot/command/commands/music/RepeatCommand.java | 2 +- .../handiebot/command/commands/music/ShuffleCommand.java | 2 +- src/main/java/handiebot/utils/DisappearingMessage.java | 5 +++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index aa9be7f..31b0c1b 100644 --- a/pom.xml +++ b/pom.xml @@ -70,7 +70,7 @@ com.github.andrewlalis TengwarTranslatorLibrary - 1.1 + 1.2 diff --git a/src/main/java/handiebot/command/commands/misc/TengwarCommand.java b/src/main/java/handiebot/command/commands/misc/TengwarCommand.java index 5d05cc1..527c7cf 100644 --- a/src/main/java/handiebot/command/commands/misc/TengwarCommand.java +++ b/src/main/java/handiebot/command/commands/misc/TengwarCommand.java @@ -31,15 +31,15 @@ public class TengwarCommand extends ContextCommand { String result = Translator.translateToTengwar(input); try { context.getChannel().sendFile("Raw text: `" +result+'`', TengwarImageGenerator.generateImage(result, - 400, - 20f, + 600, + 24f, false, false, System.getProperty("user.home")+"/.handiebot/tengwarTemp.png")); } catch (FileNotFoundException e) { e.printStackTrace(); } - } else if (context.getArgs()[0].equalsIgnoreCase("to")){ + } else if (context.getArgs()[0].equalsIgnoreCase("from")){ context.getChannel().sendMessage(Translator.translateToEnglish(input)); } } else { diff --git a/src/main/java/handiebot/command/commands/music/RepeatCommand.java b/src/main/java/handiebot/command/commands/music/RepeatCommand.java index 97fa33c..fc33c21 100644 --- a/src/main/java/handiebot/command/commands/music/RepeatCommand.java +++ b/src/main/java/handiebot/command/commands/music/RepeatCommand.java @@ -25,7 +25,7 @@ public class RepeatCommand extends ContextCommand { @Override public void execute(CommandContext context) { if (context.getArgs().length == 1 && Commands.hasPermission(context, 8)){ - boolean shouldRepeat = Boolean.getBoolean(context.getArgs()[0].toLowerCase()); + boolean shouldRepeat = (context.getArgs()[0].toLowerCase().equals("true")); HandieBot.musicPlayer.setRepeat(context.getGuild(), shouldRepeat); } else { 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 9ba9d24..3b7e7c6 100644 --- a/src/main/java/handiebot/command/commands/music/ShuffleCommand.java +++ b/src/main/java/handiebot/command/commands/music/ShuffleCommand.java @@ -25,7 +25,7 @@ public class ShuffleCommand extends ContextCommand { @Override public void execute(CommandContext context) { if (context.getArgs().length == 1 && Commands.hasPermission(context, 8)){ - boolean shouldShuffle = Boolean.getBoolean(context.getArgs()[0].toLowerCase()); + boolean shouldShuffle = (context.getArgs()[0].toLowerCase().equals("true")); HandieBot.musicPlayer.setShuffle(context.getGuild(), shouldShuffle); } else { context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("player.getShuffle"), HandieBot.musicPlayer.isShuffling(context.getGuild()))); diff --git a/src/main/java/handiebot/utils/DisappearingMessage.java b/src/main/java/handiebot/utils/DisappearingMessage.java index 82aec7a..fa54382 100644 --- a/src/main/java/handiebot/utils/DisappearingMessage.java +++ b/src/main/java/handiebot/utils/DisappearingMessage.java @@ -5,6 +5,7 @@ import handiebot.view.BotLog; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.Permissions; +import sx.blah.discord.util.RequestBuffer; import static handiebot.HandieBot.log; import static handiebot.HandieBot.resourceBundle; @@ -29,7 +30,7 @@ public class DisappearingMessage extends Thread implements Runnable { e.printStackTrace(); } if (canDelete(sentMessage)) - sentMessage.delete(); + RequestBuffer.request(() -> sentMessage.delete()); } /** @@ -45,7 +46,7 @@ public class DisappearingMessage extends Thread implements Runnable { e.printStackTrace(); } if (canDelete(message)) - message.delete(); + RequestBuffer.request(() -> message.delete()); }).start(); } -- 2.34.1 From 8f670601b3d88a25ce96092f40073b20e3edf1d4 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Mon, 3 Jul 2017 13:27:19 +0200 Subject: [PATCH 13/13] Handiebot Version 1.4.0 Final Commit for release * Updated README * externalized all necessary strings * fixed `-nogui` argument position * Many small improvements --- .gitignore | 1 - README.md | 27 +++++++---- pom.xml | 4 +- src/main/java/handiebot/HandieBot.java | 21 ++++----- .../handiebot/command/CommandHandler.java | 4 +- src/main/java/handiebot/command/Commands.java | 2 +- .../commands/music/PlaylistCommand.java | 5 +- .../handiebot/lavaplayer/AudioProvider.java | 3 +- .../handiebot/lavaplayer/MusicPlayer.java | 5 +- .../handiebot/lavaplayer/TrackScheduler.java | 4 +- .../lavaplayer/playlist/Playlist.java | 7 +-- .../lavaplayer/playlist/UnloadedTrack.java | 2 +- .../handiebot/utils/DisappearingMessage.java | 4 +- src/main/java/handiebot/utils/FileUtil.java | 10 ++-- src/main/java/handiebot/utils/Pastebin.java | 2 +- .../handiebot/view/CommandLineListener.java | 4 +- src/main/resources/Strings.properties | 5 ++ src/main/resources/Strings_nl.properties | 47 ++++++++++++------- 18 files changed, 92 insertions(+), 65 deletions(-) diff --git a/.gitignore b/.gitignore index 808b8e3..4713549 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -!.jar .idea/ modules/ src/test/ diff --git a/README.md b/README.md index e763802..78b8cf5 100644 --- a/README.md +++ b/README.md @@ -29,35 +29,39 @@ queue all Because the play command is defined as `play [URL]`, and the queue command is defined as `queue [all]`. +Commands shown in **`bold`** can only be executed by an administrator, for security reasons. + ### General * `info` - Displays the most common commands, and some basic information about the bot. * `help` - Sends a private message to whoever issues this command. The message contains an in-depth list of all commands and their proper usage. -* `setprefix ` - Sets the prefix for all commands. Be careful, as some values will cause irreversible damage, if for example, a prefix conflicts with another bot's prefix. +* **`setprefix `** - Sets the prefix for all commands. Be careful, as some values will cause irreversible damage, if for example, a prefix conflicts with another bot's prefix. ### Music * `play [URL]` - Starts playback from the queue, or if a URL is defined, then it will attempt to play that song, or add it to the queue, depending on if a song is already playing. If a song is already playing, you should receive an estimate of when your song should begin playing. -* `stop` - If music is playing, this will stop it. +* **`stop`** - If music is playing, this will stop it. -* `skip` - If a song is playing, the bot will skip it and play the next song in the queue. +* **`skip`** - If a song is playing, the bot will skip it and play the next song in the queue. * `queue [all|clear|save]` - Lists up to the first 10 items on the queue, if no argument is given. * `all` - The bot will upload a list to [PasteBin](http://pastebin.com) of the entire queue, provided it is greater than 10 elements, and give you a link which expires in 10 minutes. - * `clear` - The queue will be cleared and the current song will be stopped. + * **`clear`** - The queue will be cleared and the current song will be stopped. - * `save ` - The queue will be saved as a playlist with the given name. + * **`save `** - The queue will be saved as a playlist with the given name. -* `repeat [true|false]` - Sets the bot to repeat the playlist, as in once a song is removed from the queue to be played, it is added back to the end of the playlist. +* `repeat [true|false]` - Sets the bot to repeat the playlist, as in once a song is removed from the queue to be played, it is added back to the end of the playlist. If no argument is given, then this shows if the queue is currently repeating. -* `shuffle [true|false]` - Sets the bot to shuffle the playlist, as in pull a random song from the playlist, with some filters to prevent repeating songs. +* `shuffle [true|false]` - Sets the bot to shuffle the playlist, as in pull a random song from the playlist, with some filters to prevent repeating songs. If no argument is given, then this shows if the queue is currently shuffling. -* `playlist ` - Various commands to manipulate playlists. The specific sub-commands are explained below. + >Note that for `repeat` and `shuffle`, anyone may view the status of these values, but only administrators may set them. + +* **`playlist `** - Various commands to manipulate playlists. The specific sub-commands are explained below. * `create [URL]...` - Creates a new playlist, optionally with some starting URLs. * `delete ` - Deletes a playlist with the given name. @@ -74,3 +78,10 @@ Because the play command is defined as `play [URL]`, and the queue command is de * `move ` - Moves a song from one index to another index, shifting other elements as necessary. +### Miscellaneous + +* `tengwar ` - Uses the [TengwarTranslatorLibrary](https://github.com/andrewlalis/TengwarTranslatorLibrary) to translate text into a Tengwar script equivalent, or translate from Tengwar to normal text. Be aware that due to the nature of this font, capitalization is not saved in Tengwar. For more information on how this works, check out my [TengwarTranslator](https://github.com/andrewlalis/TengwarTranslator). + + * `to ` - Translates some text to tengwar, and responds with both the raw, UTF-8 string, and an image generated using a Tengwar font. + + * `from ` - Translates some tengwar text to normal, human readable text. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 31b0c1b..9e3b612 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.andrewlalis HandieBot - 1.3.1 + 1.4.0 @@ -70,7 +70,7 @@ com.github.andrewlalis TengwarTranslatorLibrary - 1.2 + 1.3 diff --git a/src/main/java/handiebot/HandieBot.java b/src/main/java/handiebot/HandieBot.java index ddb116f..3c080a1 100644 --- a/src/main/java/handiebot/HandieBot.java +++ b/src/main/java/handiebot/HandieBot.java @@ -16,10 +16,7 @@ import sx.blah.discord.handle.obj.Permissions; import sx.blah.discord.util.DiscordException; import sx.blah.discord.util.RateLimitException; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.ResourceBundle; +import java.util.*; /** * @author Andrew Lalis @@ -33,7 +30,7 @@ public class HandieBot { private static final String TOKEN = "MjgzNjUyOTg5MjEyNjg4Mzg0.C45A_Q.506b0G6my1FEFa7_YY39lxLBHUY"; private static boolean USE_GUI = true; - public static ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings"); + public static final ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings"); //Discord client object. public static IDiscordClient client; @@ -46,7 +43,7 @@ public class HandieBot { public static MusicPlayer musicPlayer; //List of all permissions needed to operate this bot. - private static int permissionsNumber = 0; + private static final int permissionsNumber; static { List requiredPermissions = new ArrayList<>(); requiredPermissions.add(Permissions.CHANGE_NICKNAME); @@ -87,12 +84,12 @@ public class HandieBot { musicPlayer = new MusicPlayer(); - if (args.length >= 1) { - if (args[0].equalsIgnoreCase("-nogui")){ - System.out.println("Starting with no GUI."); - USE_GUI = false; - log = new BotLog(null); - } + List argsList = Arrays.asList(args); + + if (argsList.contains("-nogui")) { + System.out.println("Starting with no GUI."); + USE_GUI = false; + log = new BotLog(null); } if (USE_GUI){ diff --git a/src/main/java/handiebot/command/CommandHandler.java b/src/main/java/handiebot/command/CommandHandler.java index 996a72a..ade2f32 100644 --- a/src/main/java/handiebot/command/CommandHandler.java +++ b/src/main/java/handiebot/command/CommandHandler.java @@ -77,9 +77,7 @@ public class CommandHandler { String[] words = message.getContent().split(" "); if (words[0].startsWith(PREFIXES.get(message.getGuild()))){ String[] args = new String[words.length-1]; - for (int i = 0; i < words.length-1; i++){ - args[i] = words[i+1]; - } + System.arraycopy(words, 1, args, 0, words.length - 1); return args; } return new String[0]; diff --git a/src/main/java/handiebot/command/Commands.java b/src/main/java/handiebot/command/Commands.java index ca23377..8fb960a 100644 --- a/src/main/java/handiebot/command/Commands.java +++ b/src/main/java/handiebot/command/Commands.java @@ -25,7 +25,7 @@ import static handiebot.HandieBot.resourceBundle; */ public class Commands { - public static List commands = new ArrayList(); + public static List commands = new ArrayList<>(); static { //Music commands. diff --git a/src/main/java/handiebot/command/commands/music/PlaylistCommand.java b/src/main/java/handiebot/command/commands/music/PlaylistCommand.java index 5e90469..5cffa92 100644 --- a/src/main/java/handiebot/command/commands/music/PlaylistCommand.java +++ b/src/main/java/handiebot/command/commands/music/PlaylistCommand.java @@ -286,11 +286,12 @@ public class PlaylistCommand extends ContextCommand { * @return True if the playlist exists, false otherwise. */ private boolean checkForPlaylist(CommandContext context){ - if (!Playlist.playlistExists(context.getArgs()[1])){ + if (Playlist.playlistExists(context.getArgs()[1])){ + return true; + } else { new DisappearingMessage(context.getChannel(), MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.playlistDoesNotExist"), getPlaylistShowString(context)), 3000); return false; } - return true; } /** diff --git a/src/main/java/handiebot/lavaplayer/AudioProvider.java b/src/main/java/handiebot/lavaplayer/AudioProvider.java index 0155f4e..77b5c0c 100644 --- a/src/main/java/handiebot/lavaplayer/AudioProvider.java +++ b/src/main/java/handiebot/lavaplayer/AudioProvider.java @@ -6,7 +6,8 @@ import sx.blah.discord.handle.audio.AudioEncodingType; import sx.blah.discord.handle.audio.IAudioProvider; /** - * Created by Andrew's Computer on 18-Jun-17. + * @author Andrew Lalis + * Class to provide audio bytes to the music player. */ public class AudioProvider implements IAudioProvider { private final AudioPlayer audioPlayer; diff --git a/src/main/java/handiebot/lavaplayer/MusicPlayer.java b/src/main/java/handiebot/lavaplayer/MusicPlayer.java index 666990f..abf6771 100644 --- a/src/main/java/handiebot/lavaplayer/MusicPlayer.java +++ b/src/main/java/handiebot/lavaplayer/MusicPlayer.java @@ -175,6 +175,7 @@ public class MusicPlayer { public void showQueueList(IGuild guild, boolean showAll) { List tracks = getMusicManager(guild).scheduler.queueList(); if (tracks.size() == 0) { + //noinspection ConstantConditions getChatChannel(guild).sendMessage(MessageFormat.format(resourceBundle.getString("player.queueEmpty"), Commands.get("play").getUsage())); } else { if (tracks.size() > 10 && showAll) { @@ -295,9 +296,7 @@ public class MusicPlayer { * Performs the same functions as stop, but with every guild. */ public void quitAll(){ - this.musicManagers.forEach((guild, musicManager) -> { - musicManager.scheduler.stop(); - }); + this.musicManagers.forEach((guild, musicManager) -> musicManager.scheduler.stop()); this.playerManager.shutdown(); } diff --git a/src/main/java/handiebot/lavaplayer/TrackScheduler.java b/src/main/java/handiebot/lavaplayer/TrackScheduler.java index 90efcb8..e8e5331 100644 --- a/src/main/java/handiebot/lavaplayer/TrackScheduler.java +++ b/src/main/java/handiebot/lavaplayer/TrackScheduler.java @@ -197,8 +197,8 @@ public class TrackScheduler extends AudioEventAdapter { 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(); + RequestBuffer.request(() -> message.addReaction(":thumbsup:")).get(); + RequestBuffer.request(() -> message.addReaction(":thumbsdown:")).get(); } } diff --git a/src/main/java/handiebot/lavaplayer/playlist/Playlist.java b/src/main/java/handiebot/lavaplayer/playlist/Playlist.java index 47ae886..22b3645 100644 --- a/src/main/java/handiebot/lavaplayer/playlist/Playlist.java +++ b/src/main/java/handiebot/lavaplayer/playlist/Playlist.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Random; import static handiebot.HandieBot.log; +import static handiebot.HandieBot.resourceBundle; /** * @author Andrew Lalis @@ -21,7 +22,7 @@ import static handiebot.HandieBot.log; * on the playlist. */ public class Playlist { -//TODO: externalize strings + private String name; private List tracks; @@ -186,7 +187,7 @@ public class Playlist { */ public static List getAvailablePlaylists(){ File playlistFolder = new File(System.getProperty("user.home")+"/.handiebot/playlist"); - List names = new ArrayList(Arrays.asList(playlistFolder.list())); + @SuppressWarnings("ConstantConditions") List names = new ArrayList<>(Arrays.asList(playlistFolder.list())); for (int i = 0; i < names.size(); i++){ String name = names.get(i); name = name.replace(".txt", ""); @@ -215,7 +216,7 @@ public class Playlist { public String toString(){ StringBuilder sb = new StringBuilder("Playlist: "+this.getName()+'\n'); if (this.getTrackCount() == 0){ - sb.append("There are no songs in this playlist."); + sb.append(resourceBundle.getString("playlist.empty")); } else { for (int i = 0; i < this.getTrackCount(); i++) { sb.append(i + 1).append(". ").append(this.tracks.get(i).getTitle()).append(" ").append(this.tracks.get(i).getFormattedDuration()).append("\n"); diff --git a/src/main/java/handiebot/lavaplayer/playlist/UnloadedTrack.java b/src/main/java/handiebot/lavaplayer/playlist/UnloadedTrack.java index ed758f8..e2315c1 100644 --- a/src/main/java/handiebot/lavaplayer/playlist/UnloadedTrack.java +++ b/src/main/java/handiebot/lavaplayer/playlist/UnloadedTrack.java @@ -17,7 +17,7 @@ import static handiebot.HandieBot.log; * This is useful for quickly loading playlists and only loading a track when it is needed. */ public class UnloadedTrack implements Cloneable { -//TODO: externalize strings + private String title; private String url; private long duration; diff --git a/src/main/java/handiebot/utils/DisappearingMessage.java b/src/main/java/handiebot/utils/DisappearingMessage.java index fa54382..42d8615 100644 --- a/src/main/java/handiebot/utils/DisappearingMessage.java +++ b/src/main/java/handiebot/utils/DisappearingMessage.java @@ -30,7 +30,7 @@ public class DisappearingMessage extends Thread implements Runnable { e.printStackTrace(); } if (canDelete(sentMessage)) - RequestBuffer.request(() -> sentMessage.delete()); + RequestBuffer.request(sentMessage::delete); } /** @@ -46,7 +46,7 @@ public class DisappearingMessage extends Thread implements Runnable { e.printStackTrace(); } if (canDelete(message)) - RequestBuffer.request(() -> message.delete()); + RequestBuffer.request(message::delete); }).start(); } diff --git a/src/main/java/handiebot/utils/FileUtil.java b/src/main/java/handiebot/utils/FileUtil.java index 26749bd..5947214 100644 --- a/src/main/java/handiebot/utils/FileUtil.java +++ b/src/main/java/handiebot/utils/FileUtil.java @@ -7,17 +7,19 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import static handiebot.HandieBot.log; +import static handiebot.HandieBot.resourceBundle; /** * @author Andrew Lalis * Class to simplify file operations. */ public class FileUtil { -//TODO: externalize strings + public static String getDataDirectory(){ return System.getProperty("user.home")+"/.handiebot/"; } @@ -39,12 +41,12 @@ public class FileUtil { try { boolean success = file.createNewFile(); if (!success) { - log.log(BotLog.TYPE.ERROR, "Unable to create file. "+file.getAbsolutePath()); + log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("fileutil.fileCreateError"), file.getAbsolutePath())); return; } } catch (IOException e) { e.printStackTrace(); - log.log(BotLog.TYPE.ERROR, "Unable to create file. "+file.getAbsolutePath()); + log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("fileutil.fileCreateError"), file.getAbsolutePath())); return; } } @@ -54,7 +56,7 @@ public class FileUtil { } } catch (FileNotFoundException e) { e.printStackTrace(); - log.log(BotLog.TYPE.ERROR, "Unable to write to file. "+file.getAbsolutePath()); + log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("fileutil.writeError"), file.getAbsolutePath())); } } diff --git a/src/main/java/handiebot/utils/Pastebin.java b/src/main/java/handiebot/utils/Pastebin.java index 46450cc..cec78dd 100644 --- a/src/main/java/handiebot/utils/Pastebin.java +++ b/src/main/java/handiebot/utils/Pastebin.java @@ -22,7 +22,7 @@ import java.util.List; */ public class Pastebin { - private static String PASTEBIN_KEY = "769adc01154922ece448cabd7a33b57c"; + private static final String PASTEBIN_KEY = "769adc01154922ece448cabd7a33b57c"; public static String paste(String title, String content){ HttpClient client = HttpClients.createDefault(); diff --git a/src/main/java/handiebot/view/CommandLineListener.java b/src/main/java/handiebot/view/CommandLineListener.java index 0678ee2..a71b9f3 100644 --- a/src/main/java/handiebot/view/CommandLineListener.java +++ b/src/main/java/handiebot/view/CommandLineListener.java @@ -25,9 +25,7 @@ public class CommandLineListener implements KeyListener { commandLine.setText(null); String command = words[0]; String[] args = new String[words.length-1]; - for (int i = 1; i < words.length; i++) { - args[i-1] = words[i]; - } + System.arraycopy(words, 1, args, 0, words.length - 1); executeCommand(command, args); } } diff --git a/src/main/resources/Strings.properties b/src/main/resources/Strings.properties index 8ec9027..c864ee9 100644 --- a/src/main/resources/Strings.properties +++ b/src/main/resources/Strings.properties @@ -111,5 +111,10 @@ player.playQueueEmpty=There's nothing in the queue to play. #Track scheduler trackSchedule.trackStarted=Started audio track: {0} trackSchedule.nowPlaying=Now playing: **{0}** {1} +#File utils +fileutil.fileCreateError=Unable to create file. {0} +fileutil.writeError=Unable to write to file. {0} +#Playlist strings +playlist.empty=There are no songs in this playlist. diff --git a/src/main/resources/Strings_nl.properties b/src/main/resources/Strings_nl.properties index 76f90c7..c864ee9 100644 --- a/src/main/resources/Strings_nl.properties +++ b/src/main/resources/Strings_nl.properties @@ -1,7 +1,12 @@ +#Strings for HandieBot: +# The following strings are organized in a way that it should be intuitive how it will be used. #Log log.loggingIn=Logging client in... log.init=HandieBot initialized. log.shuttingDown=Shutting down the bot. +log.deleteMessageError=Unable to delete message. Please ensure that the bot has MANAGE_MESSAGES enabled, especially for this channel. +log.creatingChatChannel=No chat channel found, creating a new one. +log.newVoiceChannel=No voice channel found, creating a new one. #Window window.close.question=Are you sure you want to exit and shutdown the bot? window.close.title=Confirm shutdown @@ -11,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. @@ -69,6 +75,7 @@ commands.command.playlist.move.message=Moved song *{0}* from position {1} to pos commands.command.playlist.move.log=Moved song {0} from position {1} to position {2} commands.command.playlist.error.moveInvalidIndex=The song indices are invalid. You specified moving song {0} to position {1}. commands.command.playlist.error.moveBadArgs=You must provide a playlist name, followed by the song index, and a new index for that song. +#Queue commands.command.queue.description.main=Shows the first 10 songs in the queue. commands.command.queue.description.all=Shows all songs. commands.command.queue.description.clear=Clears the queue and stops playing. @@ -76,30 +83,38 @@ commands.command.queue.description.save=Saves the queue to a playlist. commands.command.queue.clear=Cleared queue. commands.command.queue.save.message=Saved {0} tracks to playlist **{1}**. commands.command.queue.save.log=Saved queue to playlist [{0}]. +#Repeat commands.command.repeat.description=Sets repeating. +#Shuffle commands.command.shuffle.description=Sets shuffling. +#Skip commands.command.skip.description=Skips the current song. +#Stop commands.command.stop.description=Stops playing music. -log.deleteMessageError=Unable to delete message. Please ensure that the bot has MANAGE_MESSAGES enabled, especially for this channel. -log.creatingChatChannel=No chat channel found, creating a new one. -log.newVoiceChannel=No voice channel found, creating a new one. -player.setRepeat=Set repeat to {0} -player.setShuffle=Set shuffle to {0} +#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.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.pastebinLink=You may view the full queue by following the link: {0}\ -Note that this link expires in 10 minutes. -player.pastebinError=Unable to upload 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.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. -trackSchedule.trackStarted=Started audio track: {0} -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}*. +#Track scheduler +trackSchedule.trackStarted=Started audio track: {0} +trackSchedule.nowPlaying=Now playing: **{0}** {1} +#File utils +fileutil.fileCreateError=Unable to create file. {0} +fileutil.writeError=Unable to write to file. {0} +#Playlist strings +playlist.empty=There are no songs in this playlist. + -- 2.34.1