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; - } -}