- All rights reserved.
+ * © Stijn Bannink [stijnbannink23@gmail.com] - All rights reserved.
*/
public class UpdateManager {
- private static String SPIGOT_API = "http://api.spiget.org/v2/resources/%d/versions?size=1&sort=-releaseDate";
- private static String SBDPLUGINS_API = "http://updates.sbdplugins.nl:4000/api/resources/%d";
+ 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";
- private Plugin plugin;
- private String currentVersion;
- private int resourceID;
- private CheckType type;
- private BiConsumer versionResponse;
+ private static final String SBDPLUGINS_API = "https://updates.sbdplugins.nl/api/v2/plugins/%d";
+ private static final String SBDPLUGINS_DOWNLOAD = "https://updates.sbdplugins.nl/api/v2/download/%d";
+
+ private final Plugin plugin;
+ private final Version currentVersion;
+ private final int resourceID;
+ private final CheckType type;
+ private final String license;
+
+ private BiConsumer versionResponse;
+ private BiConsumer downloadResponse;
/**
- * Construct a new UpdateManager
+ * Construct a new UpdateManager for Spigot
*
* @param plugin The javaplugin (Main class)
* @param resourceID The resourceID on spigot/sbdplugins
- * @param type The check type
*/
- public UpdateManager(Plugin plugin, int resourceID, CheckType type) {
+ public UpdateManager(Plugin plugin, int resourceID) {
this.plugin = plugin;
- this.currentVersion = plugin.getDescription().getVersion();
+ this.currentVersion = new Version(plugin.getDescription().getVersion());
this.resourceID = resourceID;
- this.type = type;
+ this.type = CheckType.SPIGOT;
+ this.license = null;
+ }
+
+ /**
+ * Construct a new UpdateManager for SBDPlugins
+ *
+ * @param plugin The javaplugin (Main class)
+ * @param resourceID The resourceID on spigot/sbdplugins
+ * @param license The license for the download
+ */
+ public UpdateManager(Plugin plugin, int resourceID, String license) {
+ this.plugin = plugin;
+ this.currentVersion = new Version(plugin.getDescription().getVersion());
+ this.resourceID = resourceID;
+ this.type = CheckType.SBDPLUGINS;
+ this.license = license;
}
/**
@@ -51,32 +76,41 @@ public class UpdateManager {
* @param versionResponse The response
* @return The updatemanager
*/
- public UpdateManager handleResponse(BiConsumer versionResponse) {
+ public UpdateManager handleResponse(BiConsumer versionResponse) {
this.versionResponse = versionResponse;
return this;
}
+ public UpdateManager handleDownloadResponse(BiConsumer downloadResponse) {
+ this.downloadResponse = downloadResponse;
+ return this;
+ }
+
/**
* Check for a new version
*/
public void check() {
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
try {
- HttpURLConnection con = null;
+ BufferedReader in = null;
if (type == CheckType.SPIGOT) {
- con = (HttpURLConnection) new URL(String.format(SPIGOT_API, this.resourceID)).openConnection();
+ HttpsURLConnection con = (HttpsURLConnection) new URL(String.format(SPIGOT_API, this.resourceID)).openConnection();
+ con.setRequestMethod("GET");
+ con.setRequestProperty("User-Agent", "Mozilla/5.0");
+
+ in = new BufferedReader(new InputStreamReader(con.getInputStream()));
} else if (type == CheckType.SBDPLUGINS) {
- con = (HttpURLConnection) new URL(String.format(SBDPLUGINS_API, this.resourceID)).openConnection();
+ HttpsURLConnection con = (HttpsURLConnection) new URL(String.format(SBDPLUGINS_API, this.resourceID)).openConnection();
+ con.setRequestMethod("GET");
+ con.setRequestProperty("User-Agent", "Mozilla/5.0");
+
+ in = new BufferedReader(new InputStreamReader(con.getInputStream()));
}
- if (con == null) return;
+ if (in == null) return;
- con.setRequestMethod("GET");
- con.setRequestProperty("User-Agent", "Mozilla/5.0");
+ String version;
- String version = null;
-
- BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
@@ -90,18 +124,19 @@ public class UpdateManager {
JsonArray array = parser.parse(response.toString()).getAsJsonArray();
version = array.get(0).getAsJsonObject().get("name").getAsString();
- } else if (type == CheckType.SBDPLUGINS) {
+ } else {
JsonObject object = parser.parse(response.toString()).getAsJsonObject();
- version = object.get("data").getAsJsonObject().get("version").getAsString();
+ version = object.get("version").getAsString();
}
if (version == null) return;
- boolean latestVersion = version.equalsIgnoreCase(this.currentVersion);
+ Version onlineVersion = new Version(version);
- String finalVersion = version;
- Bukkit.getScheduler().runTask(this.plugin, () -> this.versionResponse.accept(latestVersion ? VersionResponse.LATEST : VersionResponse.FOUND_NEW, latestVersion ? this.currentVersion : finalVersion));
+ VersionResponse verRes = this.currentVersion.check(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));
@@ -109,12 +144,165 @@ public class UpdateManager {
});
}
- public enum CheckType {
+ public void runUpdate() {
+ 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, () -> {
+ ReadableByteChannel channel;
+ try {
+ //https://stackoverflow.com/questions/921262/how-to-download-and-save-a-file-from-internet-using-java
+ int response;
+ InputStream stream;
+ if (type == CheckType.SBDPLUGINS) {
+ HttpURLConnection connection = (HttpURLConnection) new URL(String.format(SBDPLUGINS_DOWNLOAD, this.resourceID)).openConnection();
+
+ String urlParameters = "license=" + 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();
+
+ response = connection.getResponseCode();
+ stream = connection.getInputStream();
+ } else {
+ HttpsURLConnection connection = (HttpsURLConnection) new URL(String.format(SPIGOT_DOWNLOAD, this.resourceID)).openConnection();
+ connection.setRequestProperty("User-Agent", "Mozilla/5.0");
+
+ response = connection.getResponseCode();
+ stream = connection.getInputStream();
+ }
+
+ if (response != 200) {
+ BufferedReader in = new BufferedReader(new InputStreamReader(stream));
+
+ String inputLine;
+ StringBuilder responsestr = new StringBuilder();
+ while ((inputLine = in.readLine()) != null) {
+ responsestr.append(inputLine);
+ }
+ in.close();
+
+ throw new RuntimeException("Download returned status #" + response, new Throwable(responsestr.toString()));
+ }
+
+ channel = Channels.newChannel(stream);
+ } catch (IOException e) {
+ Bukkit.getScheduler().runTask(this.plugin, () -> this.downloadResponse.accept(DownloadResponse.ERROR, null));
+ e.printStackTrace();
+ return;
+ }
+
+ FileChannel fileChannel = null;
+ try {
+ 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()));
+ });
+ }
+
+ private File getPluginFile() {
+ if (!(this.plugin instanceof JavaPlugin)) { return null; }
+ try {
+ Method method = JavaPlugin.class.getDeclaredMethod("getFile");
+ method.setAccessible(true);
+ return (File) method.invoke(this.plugin);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException("Could not get plugin file", e);
+ }
+ }
+
+ private enum CheckType {
SPIGOT, SBDPLUGINS
}
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 {
+
+ private final String version;
+
+ public final String get() {
+ return this.version;
+ }
+
+ private Version(String version) {
+ if(version == null)
+ throw new IllegalArgumentException("Version can not be null");
+ if(!version.matches("[0-9]+(\\.[0-9]+)*"))
+ throw new IllegalArgumentException("Invalid version format");
+ this.version = version;
+ }
+
+ private VersionResponse check(Version that) {
+ String[] thisParts = this.get().split("\\.");
+ String[] thatParts = that.get().split("\\.");
+
+ int length = Math.max(thisParts.length, thatParts.length);
+ for (int i = 0; i < length; i++) {
+ int thisPart = i < thisParts.length ? Integer.parseInt(thisParts[i]) : 0;
+ int thatPart = i < thatParts.length ? Integer.parseInt(thatParts[i]) : 0;
+ if(thisPart < thatPart)
+ return VersionResponse.FOUND_NEW;
+ if(thisPart > thatPart)
+ return VersionResponse.THIS_NEWER;
+ }
+ return VersionResponse.LATEST;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 1d49add..48e4376 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,5 +1,5 @@
name: ThemeParkConnector
-version: 3.0.1
+version: 3.0.2
author: IOByte
website: 'https://www.iobyte.nl'
main: nl.iobyte.themeparkconnector.ThemeParkConnector
diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml
index ca4c29e..045c197 100644
--- a/src/main/resources/settings.yml
+++ b/src/main/resources/settings.yml
@@ -1,7 +1,11 @@
-version: 1.0
+version: 1.1
license: ''
+update:
+ check: true
+ download: true
+
socket:
id: 'themepark'
url: 'websocket.iobyte.nl'