Skip to content

Instantly share code, notes, and snippets.

@Skyost
Created July 9, 2014 10:36
Show Gist options
  • Save Skyost/3403a315d0677cfd9247 to your computer and use it in GitHub Desktop.
Save Skyost/3403a315d0677cfd9247 to your computer and use it in GitHub Desktop.
From Project BungeeGames.
package fr.skyost.bungeegames.utils;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
public class Updater extends Thread {
private final Plugin plugin;
private final File pathTo;
private final Logger logger;
public static final String PAGE_URL = "http://dev.bukkit.org/bukkit-plugins/project-hungergames/pages/project-bungee-games/";
public static final String DOWNLOAD_URL = "http://files.skyost.eu/files/project-hungergames/Project%20BungeeGames.jar";
public Updater(final Plugin plugin, final File pluginFile) {
this.plugin = plugin;
final File updateFolder = Bukkit.getUpdateFolderFile();
if(!updateFolder.exists()) {
updateFolder.mkdir();
}
this.pathTo = new File(updateFolder, pluginFile.getName());
this.logger = plugin.getLogger();
}
@Override
public void run() {
try {
final Connection connection = Jsoup.connect(PAGE_URL);
connection.data("query", "java");
connection.timeout(10000);
connection.ignoreHttpErrors(true);
connection.userAgent("Project BungeeGames");
final Document page = connection.get();
String remoteVersion = null;
for(final Element element : page.select("p")) {
final String elementText = element.text();
if(elementText.contains("Current version")) {
remoteVersion = elementText.split("Current version : v")[1];
break;
}
}
if(remoteVersion == null || remoteVersion.length() == 0) {
return;
}
final String localVersion = plugin.getDescription().getVersion();
if(compareVersions(remoteVersion, localVersion)) {
logger.log(Level.INFO, "Downloading a new update : " + remoteVersion + "...");
if(download(DOWNLOAD_URL, pathTo)) {
logger.log(Level.FINE, "The new version was downloaded with success !");
logger.log(Level.INFO, "Please make a reboot (or a reload) to be able to use the downloaded version.");
}
else {
logger.log(Level.SEVERE, "Something went wrong :s");
logger.log(Level.INFO, "But you can download the update manually at '" + DOWNLOAD_URL + "'.");
}
}
}
catch(Exception ex) {
logger.log(Level.SEVERE, "Error while checking for updates : \"" + ex.getClass().getName() + "\". Please report it on Project HungerGames' BukkitDev page.");
}
}
/**
* Downloads a file.
*
* @param site The URL of the file you want to download.
* @param pathTo The path where you want the file to be downloaded.
*
* @return <b>true</b>If the download was a success.
* </b>false</b>If there is an error during the download.
*
* @throws IOException InputOutputException.
*/
private final boolean download(final String site, final File pathTo) {
try {
final HttpURLConnection connection = (HttpURLConnection)new URL(site).openConnection();
connection.addRequestProperty("User-Agent", "Project BungeeGames");
final String response = connection.getResponseCode() + " " + connection.getResponseMessage();
if(!response.startsWith("2")) {
logger.log(Level.INFO, "Bad response : '" + response + "' when trying to download the update.");
return false;
}
final long size = connection.getContentLengthLong();
final long koSize = size / 1000;
long lastPercent = 0;
long percent = 0;
float totalDataRead = 0;
final InputStream inputStream = connection.getInputStream();
final FileOutputStream fileOutputStream = new FileOutputStream(pathTo);
final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream, 1024);
final byte[] data = new byte[1024];
int i = 0;
while((i = inputStream.read(data, 0, 1024)) >= 0) {
totalDataRead += i;
bufferedOutputStream.write(data, 0, i);
percent = ((long)(totalDataRead * 100) / size);
if(lastPercent != percent) {
lastPercent = percent;
logger.log(Level.INFO, percent + "% of " + koSize + "ko...");
}
}
bufferedOutputStream.close();
fileOutputStream.close();
inputStream.close();
return true;
}
catch(Exception ex) {
logger.log(Level.SEVERE, "Exception '" + ex + "' occured when downloading update. Please check your network connection.");
ex.printStackTrace();
}
return false;
}
/**
* Compare two versions.
*
* @param version1 The version you want to compare to.
* @param version2 The version you want to compare with.
*
* @return <b>true</b> If <b>versionTo</b> is inferior than <b>versionWith</b>.
* <br><b>false</b> If <b>versionTo</b> is superior or equals to <b>versionWith</b>.
*/
public static final boolean compareVersions(final String versionTo, final String versionWith) {
return normalisedVersion(versionTo, ".", 4).compareTo(normalisedVersion(versionWith, ".", 4)) > 0;
}
/**
* Get the formatted name of a version.
* <br>Used for the method <b>compareVersions(...)</b> of this class.
*
* @param version The version you want to format.
* @param separator The separator between the numbers of this version.
* @param maxWidth The max width of the formatted version.
*
* @return A string which the formatted version of your version.
*
* @author Peter Lawrey.
*/
private static final String normalisedVersion(final String version, final String separator, final int maxWidth) {
final StringBuilder stringBuilder = new StringBuilder();
for(final String normalised : Pattern.compile(separator, Pattern.LITERAL).split(version)) {
stringBuilder.append(String.format("%" + maxWidth + 's', normalised));
}
return stringBuilder.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment