diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index b600ee6..6260fda 100644 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -1,7 +1,6 @@ package buttondevteam.discordplugin; import java.awt.Color; -import java.io.BufferedReader; import java.io.File; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -24,7 +23,9 @@ import sx.blah.discord.api.events.IListener; import sx.blah.discord.api.internal.json.objects.EmbedObject; import sx.blah.discord.handle.impl.events.ReadyEvent; import sx.blah.discord.handle.obj.*; +import sx.blah.discord.util.DiscordException; import sx.blah.discord.util.EmbedBuilder; +import sx.blah.discord.util.MissingPermissionsException; import sx.blah.discord.util.RateLimitException; public class DiscordPlugin extends JavaPlugin implements IListener { @@ -230,36 +231,18 @@ public class DiscordPlugin extends JavaPlugin implements IListener { Bukkit.getLogger() .warning("Message was too long to send to discord and got truncated. In " + channel.getName()); } - for (int i = 0; i < 10; i++) { - try { - Thread.sleep(i * 100); - } catch (InterruptedException e2) { - e2.printStackTrace(); - } - try { - if (SafeMode) - return null; - if (channel == chatchannel) - MCChatListener.resetLastMessage(); // If this is a chat message, it'll be set again - final String content = TBMCCoreAPI.IsTestServer() && channel != chatchannel - ? "*The following message is from a test server*\n" + message : message; - return embed == null ? channel.sendMessage(content) : channel.sendMessage(content, embed, false); - } catch (RateLimitException e) { - try { - Thread.sleep(e.getRetryDelay()); - } catch (InterruptedException e1) { - e1.printStackTrace(); - } - } catch (Exception e) { - if (i == 9) { - Bukkit.getLogger().warning("Failed to deliver message to Discord! Channel: " + channel.getName() - + " Message: " + message); - throw new RuntimeException(e); - } else - continue; - } + try { + if (channel == chatchannel) + MCChatListener.resetLastMessage(); // If this is a chat message, it'll be set again + final String content = TBMCCoreAPI.IsTestServer() && channel != chatchannel + ? "*The following message is from a test server*\n" + message : message; + return perform( + () -> embed == null ? channel.sendMessage(content) : channel.sendMessage(content, embed, false)); + } catch (Exception e) { + Bukkit.getLogger().warning( + "Failed to deliver message to Discord! Channel: " + channel.getName() + " Message: " + message); + throw new RuntimeException(e); } - return null; } public static Permission perms; @@ -296,4 +279,43 @@ public class DiscordPlugin extends JavaPlugin implements IListener { } return sanitizedString; } + + /** + * Performs Discord actions, retrying when ratelimited. May return null if action fails too many times or in safe mode. + */ + public static > T perform(DiscordSupplier action) + throws DiscordException, MissingPermissionsException { + for (int i = 0; i < 20; i++) + try { + if (SafeMode) + return null; + return action.get(); + } catch (RateLimitException e) { + try { + Thread.sleep(e.getRetryDelay() > 0 ? e.getRetryDelay() : 10); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + return null; + } + + /** + * Performs Discord actions, retrying when ratelimited. + */ + public static void perform(DiscordRunnable action) throws DiscordException, MissingPermissionsException { + for (int i = 0; i < 20; i++) + try { + if (SafeMode) + return; + action.run(); + return; // Gotta escape that loop + } catch (RateLimitException e) { + try { + Thread.sleep(e.getRetryDelay() > 0 ? e.getRetryDelay() : 10); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + } } diff --git a/src/main/java/buttondevteam/discordplugin/DiscordRunnable.java b/src/main/java/buttondevteam/discordplugin/DiscordRunnable.java new file mode 100644 index 0000000..fb27234 --- /dev/null +++ b/src/main/java/buttondevteam/discordplugin/DiscordRunnable.java @@ -0,0 +1,10 @@ +package buttondevteam.discordplugin; + +import sx.blah.discord.util.DiscordException; +import sx.blah.discord.util.MissingPermissionsException; +import sx.blah.discord.util.RateLimitException; + +@FunctionalInterface +public interface DiscordRunnable { + public abstract void run() throws DiscordException, RateLimitException, MissingPermissionsException; +} diff --git a/src/main/java/buttondevteam/discordplugin/DiscordSupplier.java b/src/main/java/buttondevteam/discordplugin/DiscordSupplier.java new file mode 100644 index 0000000..e2fb570 --- /dev/null +++ b/src/main/java/buttondevteam/discordplugin/DiscordSupplier.java @@ -0,0 +1,11 @@ +package buttondevteam.discordplugin; + +import sx.blah.discord.handle.obj.IDiscordObject; +import sx.blah.discord.util.DiscordException; +import sx.blah.discord.util.MissingPermissionsException; +import sx.blah.discord.util.RateLimitException; + +@FunctionalInterface +public interface DiscordSupplier> { + public abstract T get() throws DiscordException, RateLimitException, MissingPermissionsException; +} diff --git a/src/main/java/buttondevteam/discordplugin/commands/RoleCommand.java b/src/main/java/buttondevteam/discordplugin/commands/RoleCommand.java index 09c6696..6ebe986 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/RoleCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/RoleCommand.java @@ -7,7 +7,6 @@ import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.TBMCCoreAPI; import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IRole; -import sx.blah.discord.util.RateLimitException; public class RoleCommand extends DiscordCommandBase { @@ -49,22 +48,15 @@ public class RoleCommand extends DiscordCommandBase { "There are more roles with this name. Why are there more roles with this name?"); return; } - while (true) { - try { - message.getAuthor().addRole(roles.get(0)); - break; - } catch (RateLimitException e) { - try { - Thread.sleep(e.getRetryDelay() > 0 ? e.getRetryDelay() : 10); - } catch (InterruptedException e1) { - } - } catch (Exception e) { - TBMCCoreAPI.SendException("Error while adding role!", e); - DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while adding the role."); - break; - } + try { + DiscordPlugin.perform(() -> message.getAuthor().addRole(roles.get(0))); + } catch (Exception e) { + TBMCCoreAPI.SendException("Error while adding role!", e); + DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while adding the role."); } - } else if (argsa[0].equalsIgnoreCase("remove")) { + } else if (argsa[0].equalsIgnoreCase("remove")) + + { if (argsa.length < 2) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "This command removes a game role from your account.\nUsage: remove "); diff --git a/src/main/java/buttondevteam/discordplugin/listeners/AutoUpdaterListener.java b/src/main/java/buttondevteam/discordplugin/listeners/AutoUpdaterListener.java index 8f06b3a..865f75c 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/AutoUpdaterListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/AutoUpdaterListener.java @@ -10,7 +10,6 @@ import sx.blah.discord.api.events.IListener; import sx.blah.discord.handle.impl.events.MessageReceivedEvent; import sx.blah.discord.handle.obj.IEmbed; import sx.blah.discord.util.EmbedBuilder; -import sx.blah.discord.util.RateLimitException; public class AutoUpdaterListener implements IListener { @Override @@ -57,18 +56,10 @@ public class AutoUpdaterListener implements IListener { } return true; }).get() && (!TBMCCoreAPI.IsTestServer() || !branch.equals("master"))) - while (true) - try { - event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION); - break; - } catch (RateLimitException e) { - try { - if (e.getRetryDelay() > 0) - Thread.sleep(e.getRetryDelay()); - } catch (InterruptedException ie) { - } - } catch (Exception e) { - TBMCCoreAPI.SendException("An error occured while reacting to plugin update!", e); - } + try { + DiscordPlugin.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION)); + } catch (Exception e) { + TBMCCoreAPI.SendException("An error occured while reacting to plugin update!", e); + } } } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java index 6b318d9..7a32a0e 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java @@ -46,8 +46,8 @@ public class MCChatListener implements Listener, IListener try { embedObject.description = lastmessage.getEmbedded().get(0).getDescription() + "\n" + embedObject.description; - lastmessage.edit("", embedObject); - } catch (MissingPermissionsException | RateLimitException | DiscordException e1) { + DiscordPlugin.perform(() -> lastmessage.edit("", embedObject)); + } catch (MissingPermissionsException | DiscordException e1) { TBMCCoreAPI.SendException("An error occured while editing chat message!", e1); } } // TODO: Author URL @@ -130,39 +130,24 @@ public class MCChatListener implements Listener, IListener } else Bukkit.dispatchCommand(dsender, cmd); lastlistp = (short) Bukkit.getOnlinePlayers().size(); - } else + if (!event.getMessage().isDeleted()) + event.getMessage().delete(); + } else { TBMCChatAPI.SendChatMessage(Channel.GlobalChat, dsender, dmessage + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() .getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n")) : "")); - event.getMessage().getChannel().getMessages().stream().forEach(m -> { - try { - final IReaction reaction = m.getReactionByName(DiscordPlugin.DELIVERED_REACTION); - if (reaction != null) { - while (true) - try { - m.removeReaction(reaction); - Thread.sleep(100); - break; - } catch (RateLimitException e) { - if (e.getRetryDelay() > 0) - Thread.sleep(e.getRetryDelay()); - } + event.getMessage().getChannel().getMessages().stream().forEach(m -> { + try { + final IReaction reaction = m.getReactionByName(DiscordPlugin.DELIVERED_REACTION); + if (reaction != null) + DiscordPlugin.perform(() -> m.removeReaction(reaction)); + } catch (Exception e) { + TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e); } - } catch (Exception e) { - TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e); - } - }); - while (true) - try { - event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION); - break; - } catch (RateLimitException e) { - if (e.getRetryDelay() > 0) - Thread.sleep(e.getRetryDelay()); - else - Thread.sleep(100); - } + }); + DiscordPlugin.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION)); + } } catch (Exception e) { TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e); return;