From 127e9bc9f635ff6421ab1ee1575b5e7b97518077 Mon Sep 17 00:00:00 2001 From: stijnb1234 Date: Mon, 16 Nov 2020 18:23:05 +0100 Subject: [PATCH] Fixed strange bug with webhook --- pom.xml | 5 - .../themeparkplus/ThemeParkPlus.java | 28 +- .../listeners/StatusChangeListener.java | 30 +- .../themeparkplus/util/DiscordWebhook.java | 392 ++++++++++++++++++ .../themeparkplus/util/LGUtil.java | 6 +- 5 files changed, 420 insertions(+), 41 deletions(-) create mode 100644 src/main/lombok/nl/sbdeveloper/themeparkplus/util/DiscordWebhook.java diff --git a/pom.xml b/pom.xml index 5df26ad..f164c2b 100644 --- a/pom.xml +++ b/pom.xml @@ -151,11 +151,6 @@ 1.7 provided - - club.minnced - discord-webhooks - 0.3.1 - com.zaxxer HikariCP diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java index a8a8faa..4e2f3fa 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java @@ -1,7 +1,5 @@ package nl.sbdeveloper.themeparkplus; -import club.minnced.discord.webhook.WebhookClient; -import club.minnced.discord.webhook.WebhookClientBuilder; import net.milkbowl.vault.economy.Economy; import nl.sbdeveloper.themeparkplus.commands.TPPCMD; import nl.sbdeveloper.themeparkplus.commands.TPPTabComplete; @@ -9,7 +7,6 @@ import nl.sbdeveloper.themeparkplus.listeners.*; import nl.sbdeveloper.themeparkplus.managers.DBManager; import nl.sbdeveloper.themeparkplus.sbutils.UpdateManager; import nl.sbdeveloper.themeparkplus.sbutils.YamlFile; -import nl.sbdeveloper.themeparkplus.util.LGUtil; import nl.sbdeveloper.themeparkplus.util.License; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -33,9 +30,9 @@ public final class ThemeParkPlus extends JavaPlugin { private static YamlFile messages; private static Economy econ = null; - private static WebhookClient webhookClient; + private static String webhookURL; - private int configVersion = 2; + private final int configVersion = 2; @Override public void onEnable() { @@ -154,23 +151,12 @@ public final class ThemeParkPlus extends JavaPlugin { Bukkit.getPluginManager().registerEvents(new StatusChangeListener(), this); Bukkit.getLogger().info("[ThemeParkPlus] Loading Discord webhook..."); - WebhookClientBuilder builder = new WebhookClientBuilder(URL); - builder.setThreadFactory((job) -> { - Thread thread = new Thread(job); - thread.setName("ThemeParkPlus"); - thread.setDaemon(true); - return thread; - }); - builder.setWait(true); - webhookClient = builder.build(); + webhookURL = URL; } else { Bukkit.getLogger().severe("[ThemeParkPlus] Couldn't load the webhook builder! The URL is null."); } } - Bukkit.getLogger().info("[ThemeParkPlus] Loading Lamp & Gate util..."); - new LGUtil(); - Bukkit.getLogger().info("[ThemeParkPlus] Loading data..."); try { data.load(); @@ -191,10 +177,6 @@ public final class ThemeParkPlus extends JavaPlugin { Bukkit.getLogger().info("[ThemeParkPlus] Saving data to data file..."); data.save(); - if (getSConfig().getFile().getBoolean("DiscordWebhook.Enabled")) { - Bukkit.getLogger().info("[ThemeParkPlus] Breaking discord connection..."); - webhookClient.close(); - } Bukkit.getLogger().info("[ThemeParkPlus] Plugin disabled!"); instance = null; } @@ -219,8 +201,8 @@ public final class ThemeParkPlus extends JavaPlugin { return econ; } - public static WebhookClient getWebhookClient() { - return webhookClient; + public static String getWebhookURL() { + return webhookURL; } private boolean setupEconomy() { diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/StatusChangeListener.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/StatusChangeListener.java index 12963ab..7280ca8 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/StatusChangeListener.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/listeners/StatusChangeListener.java @@ -1,17 +1,20 @@ package nl.sbdeveloper.themeparkplus.listeners; -import club.minnced.discord.webhook.send.WebhookEmbed; -import club.minnced.discord.webhook.send.WebhookEmbedBuilder; import nl.iobyte.themepark.api.attraction.component.Status; import nl.iobyte.themepark.api.attraction.manager.StatusManager; import nl.iobyte.themepark.api.events.attraction.ChangeStatusEvent; import nl.sbdeveloper.themeparkplus.ThemeParkPlus; import nl.sbdeveloper.themeparkplus.util.ConfigUtil; +import nl.sbdeveloper.themeparkplus.util.DiscordWebhook; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; +import java.awt.*; +import java.io.IOException; + /** * Status change listener for discord webhook */ @@ -30,17 +33,24 @@ public class StatusChangeListener implements Listener { title = title.replaceAll("%Region%", regionName); String copy = ThemeParkPlus.getSConfig().getFile().getString("DiscordWebhook.Embed.Copyright"); String copyimg = ThemeParkPlus.getSConfig().getFile().getString("DiscordWebhook.Embed.CopyrightImage"); - Integer color = ThemeParkPlus.getSConfig().getFile().getInt("DiscordWebhook.Embed.Colors." + e.getAfter().toString()); + Color color = new Color(ThemeParkPlus.getSConfig().getFile().getInt("DiscordWebhook.Embed.Colors." + e.getAfter().toString())); if (copy == null || copyimg == null) return; - WebhookEmbed embed = new WebhookEmbedBuilder() - .setTitle(new WebhookEmbed.EmbedTitle(title, "")) - .setFooter(new WebhookEmbed.EmbedFooter(copy, copyimg)) - .setColor(color) - .addField(new WebhookEmbed.EmbedField(false, rideName, statusAfter)) - .build(); + DiscordWebhook webhook = new DiscordWebhook(ThemeParkPlus.getWebhookURL()); - ThemeParkPlus.getWebhookClient().send(embed); + DiscordWebhook.EmbedObject embed = new DiscordWebhook.EmbedObject() + .setTitle(title) + .setFooter(copy, copyimg) + .setColor(color) + .addField(rideName, statusAfter, false); + + webhook.addEmbed(embed); + try { + webhook.execute(); + } catch (IOException ex) { + Bukkit.getLogger().severe("[ThemeParkPlus] Could not send the status update to Discord! See the error below:"); + ex.printStackTrace(); + } } } } diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/util/DiscordWebhook.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/util/DiscordWebhook.java new file mode 100644 index 0000000..78bcbe4 --- /dev/null +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/util/DiscordWebhook.java @@ -0,0 +1,392 @@ +package nl.sbdeveloper.themeparkplus.util; + +import javax.net.ssl.HttpsURLConnection; +import java.awt.Color; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.Array; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Class used to execute Discord Webhooks with low effort + */ +public class DiscordWebhook { + + private final String url; + private String content; + private String username; + private String avatarUrl; + private boolean tts; + private final List embeds = new ArrayList<>(); + + /** + * Constructs a new DiscordWebhook instance + * + * @param url The webhook URL obtained in Discord + */ + public DiscordWebhook(String url) { + this.url = url; + } + + public void setContent(String content) { + this.content = content; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setAvatarUrl(String avatarUrl) { + this.avatarUrl = avatarUrl; + } + + public void setTts(boolean tts) { + this.tts = tts; + } + + public void addEmbed(EmbedObject embed) { + this.embeds.add(embed); + } + + public void execute() throws IOException { + if (this.content == null && this.embeds.isEmpty()) { + throw new IllegalArgumentException("Set content or add at least one EmbedObject"); + } + + JSONObject json = new JSONObject(); + + json.put("content", this.content); + json.put("username", this.username); + json.put("avatar_url", this.avatarUrl); + json.put("tts", this.tts); + + if (!this.embeds.isEmpty()) { + List embedObjects = new ArrayList<>(); + + for (EmbedObject embed : this.embeds) { + JSONObject jsonEmbed = new JSONObject(); + + jsonEmbed.put("title", embed.getTitle()); + jsonEmbed.put("description", embed.getDescription()); + jsonEmbed.put("url", embed.getUrl()); + + if (embed.getColor() != null) { + Color color = embed.getColor(); + int rgb = color.getRed(); + rgb = (rgb << 8) + color.getGreen(); + rgb = (rgb << 8) + color.getBlue(); + + jsonEmbed.put("color", rgb); + } + + EmbedObject.Footer footer = embed.getFooter(); + EmbedObject.Image image = embed.getImage(); + EmbedObject.Thumbnail thumbnail = embed.getThumbnail(); + EmbedObject.Author author = embed.getAuthor(); + List fields = embed.getFields(); + + if (footer != null) { + JSONObject jsonFooter = new JSONObject(); + + jsonFooter.put("text", footer.getText()); + jsonFooter.put("icon_url", footer.getIconUrl()); + jsonEmbed.put("footer", jsonFooter); + } + + if (image != null) { + JSONObject jsonImage = new JSONObject(); + + jsonImage.put("url", image.getUrl()); + jsonEmbed.put("image", jsonImage); + } + + if (thumbnail != null) { + JSONObject jsonThumbnail = new JSONObject(); + + jsonThumbnail.put("url", thumbnail.getUrl()); + jsonEmbed.put("thumbnail", jsonThumbnail); + } + + if (author != null) { + JSONObject jsonAuthor = new JSONObject(); + + jsonAuthor.put("name", author.getName()); + jsonAuthor.put("url", author.getUrl()); + jsonAuthor.put("icon_url", author.getIconUrl()); + jsonEmbed.put("author", jsonAuthor); + } + + List jsonFields = new ArrayList<>(); + for (EmbedObject.Field field : fields) { + JSONObject jsonField = new JSONObject(); + + jsonField.put("name", field.getName()); + jsonField.put("value", field.getValue()); + jsonField.put("inline", field.isInline()); + + jsonFields.add(jsonField); + } + + jsonEmbed.put("fields", jsonFields.toArray()); + embedObjects.add(jsonEmbed); + } + + json.put("embeds", embedObjects.toArray()); + } + + URL url = new URL(this.url); + HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); + connection.addRequestProperty("Content-Type", "application/json"); + connection.addRequestProperty("User-Agent", "Java-DiscordWebhook-BY-Gelox_"); + connection.setDoOutput(true); + connection.setRequestMethod("POST"); + + OutputStream stream = connection.getOutputStream(); + stream.write(json.toString().getBytes(StandardCharsets.UTF_8)); + stream.flush(); + stream.close(); + + connection.getInputStream().close(); //I'm not sure why but it doesn't work without getting the InputStream + connection.disconnect(); + } + + public static class EmbedObject { + private String title; + private String description; + private String url; + private Color color; + + private Footer footer; + private Thumbnail thumbnail; + private Image image; + private Author author; + private final List fields = new ArrayList<>(); + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + public String getUrl() { + return url; + } + + public Color getColor() { + return color; + } + + public Footer getFooter() { + return footer; + } + + public Thumbnail getThumbnail() { + return thumbnail; + } + + public Image getImage() { + return image; + } + + public Author getAuthor() { + return author; + } + + public List getFields() { + return fields; + } + + public EmbedObject setTitle(String title) { + this.title = title; + return this; + } + + public EmbedObject setDescription(String description) { + this.description = description; + return this; + } + + public EmbedObject setUrl(String url) { + this.url = url; + return this; + } + + public EmbedObject setColor(Color color) { + this.color = color; + return this; + } + + public EmbedObject setFooter(String text, String icon) { + this.footer = new Footer(text, icon); + return this; + } + + public EmbedObject setThumbnail(String url) { + this.thumbnail = new Thumbnail(url); + return this; + } + + public EmbedObject setImage(String url) { + this.image = new Image(url); + return this; + } + + public EmbedObject setAuthor(String name, String url, String icon) { + this.author = new Author(name, url, icon); + return this; + } + + public EmbedObject addField(String name, String value, boolean inline) { + this.fields.add(new Field(name, value, inline)); + return this; + } + + private static class Footer { + private final String text; + private final String iconUrl; + + private Footer(String text, String iconUrl) { + this.text = text; + this.iconUrl = iconUrl; + } + + private String getText() { + return text; + } + + private String getIconUrl() { + return iconUrl; + } + } + + private static class Thumbnail { + private final String url; + + private Thumbnail(String url) { + this.url = url; + } + + private String getUrl() { + return url; + } + } + + private static class Image { + private final String url; + + private Image(String url) { + this.url = url; + } + + private String getUrl() { + return url; + } + } + + private static class Author { + private final String name; + private final String url; + private final String iconUrl; + + private Author(String name, String url, String iconUrl) { + this.name = name; + this.url = url; + this.iconUrl = iconUrl; + } + + private String getName() { + return name; + } + + private String getUrl() { + return url; + } + + private String getIconUrl() { + return iconUrl; + } + } + + private static class Field { + private final String name; + private final String value; + private final boolean inline; + + private Field(String name, String value, boolean inline) { + this.name = name; + this.value = value; + this.inline = inline; + } + + private String getName() { + return name; + } + + private String getValue() { + return value; + } + + private boolean isInline() { + return inline; + } + } + } + + private static class JSONObject { + + private final HashMap map = new HashMap<>(); + + void put(String key, Object value) { + if (value != null) { + map.put(key, value); + } + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + Set> entrySet = map.entrySet(); + builder.append("{"); + + int i = 0; + for (Map.Entry entry : entrySet) { + Object val = entry.getValue(); + builder.append(quote(entry.getKey())).append(":"); + + if (val instanceof String) { + builder.append(quote(String.valueOf(val))); + } else if (val instanceof Integer) { + builder.append(Integer.valueOf(String.valueOf(val))); + } else if (val instanceof Boolean) { + builder.append(val); + } else if (val instanceof JSONObject) { + builder.append(val.toString()); + } else if (val.getClass().isArray()) { + builder.append("["); + int len = Array.getLength(val); + for (int j = 0; j < len; j++) { + builder.append(Array.get(val, j).toString()).append(j != len - 1 ? "," : ""); + } + builder.append("]"); + } + + builder.append(++i == entrySet.size() ? "}" : ","); + } + + return builder.toString(); + } + + private String quote(String string) { + return "\"" + string + "\""; + } + } + +} \ No newline at end of file diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/util/LGUtil.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/util/LGUtil.java index 9eb8d9b..d5b411c 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/util/LGUtil.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/util/LGUtil.java @@ -18,8 +18,8 @@ import java.util.Objects; public class LGUtil { - private static List offsets = new ArrayList<>(); - private static List nearbyBlocks = new ArrayList<>(); + private static final List offsets = new ArrayList<>(); + private static final List nearbyBlocks = new ArrayList<>(); private static boolean nieuweVersie = false; @@ -29,7 +29,7 @@ public class LGUtil { private static Object lampAanData; private static Object lampUitData; - public LGUtil() { + static { offsets.add(new Vector(1, 0, 0)); offsets.add(new Vector(-1, 0, 0)); offsets.add(new Vector(0, 1, 0));