From da37e187fa4946b5156e6a045514967780de1bee Mon Sep 17 00:00:00 2001 From: stijnb1234 Date: Sun, 15 Nov 2020 14:40:34 +0100 Subject: [PATCH] Added auto updates --- .../themeparkplus/ThemeParkPlus.java | 2 +- .../themeparkplus/sbutils/UpdateManager.java | 125 ++++++++++++------ 2 files changed, 89 insertions(+), 38 deletions(-) diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java index 3d85318..4e02603 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/ThemeParkPlus.java @@ -99,7 +99,7 @@ public final class ThemeParkPlus extends JavaPlugin { } else if (downloadResponse == UpdateManager.DownloadResponse.ERROR) { Bukkit.getLogger().severe("[ThemeParkPlus] Something went wrong when trying downloading the latest version."); } else if (downloadResponse == UpdateManager.DownloadResponse.UNAVAILABLE) { - Bukkit.getLogger().warning("[ThemeParkPlus] Unable to download the latest version. The paid plugins will support this feature soon."); + Bukkit.getLogger().warning("[ThemeParkPlus] Unable to download the latest version."); } }).runUpdate(); } diff --git a/src/main/lombok/nl/sbdeveloper/themeparkplus/sbutils/UpdateManager.java b/src/main/lombok/nl/sbdeveloper/themeparkplus/sbutils/UpdateManager.java index 11dc583..6882ca8 100644 --- a/src/main/lombok/nl/sbdeveloper/themeparkplus/sbutils/UpdateManager.java +++ b/src/main/lombok/nl/sbdeveloper/themeparkplus/sbutils/UpdateManager.java @@ -1,7 +1,9 @@ package nl.sbdeveloper.themeparkplus.sbutils; +import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import nl.sbdeveloper.themeparkplus.ThemeParkPlus; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; @@ -14,31 +16,33 @@ import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; import java.nio.channels.Channels; +import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; +import java.nio.charset.StandardCharsets; import java.util.function.BiConsumer; /** * Update class for SBDevelopment * @author Stijn [SBDeveloper] * @since 05-03-2020 - * @version 1.4 + * @version 1.6 * * © Stijn Bannink - All rights reserved. */ public class UpdateManager { private static final String SPIGOT_API = "https://api.spigotmc.org/legacy/update.php?resource=%d"; + private static final String SPIGOT_DOWNLOAD = "http://api.spiget.org/v2/resources/%s/download"; /* Port 4000 is now legacy, 4443 has a SSL cert */ /* As of 24-05-2020, using the legacy port because of SSL errors */ private static final String SBDPLUGINS_API = "http://updates.sbdplugins.nl:4000/api/resources/%d"; + private static final String SBDPLUGINS_DOWNLOAD = "http://updates.sbdplugins.nl:4000/api/download/%d"; - private static final String RESOURCE_DOWNLOAD = "http://api.spiget.org/v2/resources/%s/download"; - - private Plugin plugin; - private Version currentVersion; - private int resourceID; - private CheckType type; + private final Plugin plugin; + private final Version currentVersion; + private final int resourceID; + private final CheckType type; private BiConsumer versionResponse; private BiConsumer downloadResponse; @@ -103,10 +107,13 @@ public class UpdateManager { } in.close(); + JsonParser parser = new JsonParser(); + if (type == CheckType.SPIGOT) { - version = response.toString(); + JsonArray array = parser.parse(response.toString()).getAsJsonArray(); + + version = array.get(0).getAsJsonObject().get("name").getAsString(); } else if (type == CheckType.SBDPLUGINS) { - JsonParser parser = new JsonParser(); JsonObject object = parser.parse(response.toString()).getAsJsonObject(); version = object.get("data").getAsJsonObject().get("version").getAsString(); @@ -116,9 +123,9 @@ public class UpdateManager { Version onlineVersion = new Version(version); - boolean latestVersion = this.currentVersion.compareTo(onlineVersion) < 0; + VersionResponse verRes = this.currentVersion.check(onlineVersion); - Bukkit.getScheduler().runTask(this.plugin, () -> this.versionResponse.accept(latestVersion ? VersionResponse.LATEST : VersionResponse.FOUND_NEW, latestVersion ? this.currentVersion : onlineVersion)); + Bukkit.getScheduler().runTask(this.plugin, () -> this.versionResponse.accept(verRes, onlineVersion)); } catch (IOException | NullPointerException e) { e.printStackTrace(); Bukkit.getScheduler().runTask(this.plugin, () -> this.versionResponse.accept(VersionResponse.UNAVAILABLE, null)); @@ -130,44 +137,94 @@ public class UpdateManager { File pluginFile = getPluginFile();// /plugins/XXX.jar if (pluginFile == null) { this.downloadResponse.accept(DownloadResponse.ERROR, null); + Bukkit.getLogger().info("Pluginfile is null"); return; } File updateFolder = Bukkit.getUpdateFolderFile(); if (!updateFolder.exists()) { if (!updateFolder.mkdirs()) { this.downloadResponse.accept(DownloadResponse.ERROR, null); + Bukkit.getLogger().info("Updatefolder doesn't exists, and can't be made"); return; } } final File updateFile = new File(updateFolder, pluginFile.getName()); Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> { - if (this.type == CheckType.SBDPLUGINS) { - Bukkit.getScheduler().runTask(this.plugin, () -> this.downloadResponse.accept(DownloadResponse.UNAVAILABLE, null)); - return; - } - ReadableByteChannel channel; try { //https://stackoverflow.com/questions/921262/how-to-download-and-save-a-file-from-internet-using-java - HttpURLConnection connection = (HttpURLConnection) new URL(String.format(RESOURCE_DOWNLOAD, this.resourceID)).openConnection(); - connection.setRequestProperty("User-Agent", "Mozilla/5.0"); + HttpURLConnection connection; + if (type == CheckType.SBDPLUGINS) { + connection = (HttpURLConnection) new URL(String.format(SBDPLUGINS_DOWNLOAD, this.resourceID)).openConnection(); + + String urlParameters = "license=" + ThemeParkPlus.getSConfig().getFile().getString("License") + "&port=" + Bukkit.getPort(); + byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8); + int postDataLength = postData.length; + + connection.setRequestMethod("GET"); + connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + connection.setRequestProperty("charset", "utf-8"); + connection.setRequestProperty("Content-Length", Integer.toString(postDataLength)); + connection.setRequestProperty("User-Agent", "Mozilla/5.0"); + connection.setDoOutput(true); + + DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); + wr.write(postData); + wr.close(); + } else { + connection = (HttpURLConnection) new URL(String.format(SPIGOT_DOWNLOAD, this.resourceID)).openConnection(); + connection.setRequestProperty("User-Agent", "Mozilla/5.0"); + } + if (connection.getResponseCode() != 200) { + BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + String inputLine; + StringBuilder response = new StringBuilder(); + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + + Bukkit.getLogger().info(response.toString()); + throw new RuntimeException("Download returned status #" + connection.getResponseCode()); } + channel = Channels.newChannel(connection.getInputStream()); } catch (IOException e) { Bukkit.getScheduler().runTask(this.plugin, () -> this.downloadResponse.accept(DownloadResponse.ERROR, null)); + e.printStackTrace(); return; } + + FileChannel fileChannel = null; try { - FileOutputStream output = new FileOutputStream(updateFile); - output.getChannel().transferFrom(channel, 0, Long.MAX_VALUE); - output.flush(); - output.close(); + FileOutputStream fosForDownloadedFile = new FileOutputStream(updateFile); + fileChannel = fosForDownloadedFile.getChannel(); + + fileChannel.transferFrom(channel, 0, Long.MAX_VALUE); } catch (IOException e) { Bukkit.getScheduler().runTask(this.plugin, () -> this.downloadResponse.accept(DownloadResponse.ERROR, null)); + e.printStackTrace(); return; + } finally { + if (channel != null) { + try { + channel.close(); + } catch (IOException ioe) { + System.out.println("Error while closing response body channel"); + } + } + + if (fileChannel != null) { + try { + fileChannel.close(); + } catch (IOException ioe) { + System.out.println("Error while closing file channel for downloaded file"); + } + } } Bukkit.getScheduler().runTask(this.plugin, () -> this.downloadResponse.accept(DownloadResponse.DONE, updateFile.getPath())); @@ -191,14 +248,17 @@ public class UpdateManager { } public enum VersionResponse { - LATEST, FOUND_NEW, UNAVAILABLE + LATEST, //Latest version + FOUND_NEW, //Newer available + THIS_NEWER, //Local version is newer? + UNAVAILABLE //Error } public enum DownloadResponse { DONE, ERROR, UNAVAILABLE } - public static class Version implements Comparable { + public static class Version { private String version; @@ -214,8 +274,7 @@ public class UpdateManager { this.version = version; } - @Override - public int compareTo(@NotNull Version that) { + public VersionResponse check(@NotNull Version that) { String[] thisParts = this.get().split("\\."); String[] thatParts = that.get().split("\\."); @@ -224,19 +283,11 @@ public class UpdateManager { int thisPart = i < thisParts.length ? Integer.parseInt(thisParts[i]) : 0; int thatPart = i < thatParts.length ? Integer.parseInt(thatParts[i]) : 0; if(thisPart < thatPart) - return -1; + return VersionResponse.FOUND_NEW; if(thisPart > thatPart) - return 1; + return VersionResponse.THIS_NEWER; } - return 0; - } - - @Override - public boolean equals(Object that) { - if (this == that) return true; - if (that == null) return false; - if (this.getClass() != that.getClass()) return false; - return this.compareTo((UpdateManager.Version) that) == 0; + return VersionResponse.LATEST; } } } \ No newline at end of file