Created
July 9, 2014 10:36
-
-
Save Skyost/3403a315d0677cfd9247 to your computer and use it in GitHub Desktop.
From Project BungeeGames.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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