Rewrite version checker.

This commit is contained in:
Andreas Troelsen
2013-02-15 22:41:59 +01:00
parent 523c345102
commit cc1187b7f6
3 changed files with 112 additions and 85 deletions
@@ -31,6 +31,7 @@ import com.garbagemule.MobArena.listeners.MagicSpellsListener;
import com.garbagemule.MobArena.listeners.SpoutScreenListener; import com.garbagemule.MobArena.listeners.SpoutScreenListener;
import com.garbagemule.MobArena.metrics.Metrics; import com.garbagemule.MobArena.metrics.Metrics;
import com.garbagemule.MobArena.util.FileUtils; import com.garbagemule.MobArena.util.FileUtils;
import com.garbagemule.MobArena.util.VersionChecker;
import com.garbagemule.MobArena.util.config.Config; import com.garbagemule.MobArena.util.config.Config;
import com.garbagemule.MobArena.util.config.ConfigUtils; import com.garbagemule.MobArena.util.config.ConfigUtils;
import com.garbagemule.MobArena.util.inventory.InventoryManager; import com.garbagemule.MobArena.util.inventory.InventoryManager;
@@ -95,6 +96,11 @@ public class MobArena extends JavaPlugin
// Announce enable! // Announce enable!
Messenger.info("v" + this.getDescription().getVersion() + " enabled."); Messenger.info("v" + this.getDescription().getVersion() + " enabled.");
// Check for updates
if (config.getBoolean("global-settings.update-notification", false)) {
VersionChecker.checkForUpdates(this, null);
}
} }
public void onDisable() { public void onDisable() {
@@ -1,7 +1,6 @@
package com.garbagemule.MobArena.listeners; package com.garbagemule.MobArena.listeners;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@@ -231,18 +230,7 @@ public class MAGlobalListener implements Listener
InventoryManager.restoreFromFile(plugin, event.getPlayer()); InventoryManager.restoreFromFile(plugin, event.getPlayer());
if (!am.notifyOnUpdates() || !event.getPlayer().isOp()) return; if (!am.notifyOnUpdates() || !event.getPlayer().isOp()) return;
final Player p = event.getPlayer(); VersionChecker.checkForUpdates(plugin, event.getPlayer());
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin,
new Runnable()
{
public void run()
{
if (plugin.getMAConfig().getBoolean("global-settings.update-notification", false)
&& !VersionChecker.isLatest(plugin)) {
Messenger.tellPlayer(p, "There is a new version of MobArena available!");
}
}
}, 60);
} }
@EventHandler(priority = EventPriority.NORMAL) @EventHandler(priority = EventPriority.NORMAL)
@@ -1,90 +1,123 @@
package com.garbagemule.MobArena.util; package com.garbagemule.MobArena.util;
import java.net.HttpURLConnection; import java.io.InputStream;
import java.net.URI; import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilderFactory;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import com.garbagemule.MobArena.Messenger;
import com.garbagemule.MobArena.MobArena; import com.garbagemule.MobArena.MobArena;
public class VersionChecker public class VersionChecker
{ {
public static String site = "http://forums.bukkit.org/threads/19144/"; public static final String url = "http://dev.bukkit.org/server-mods/mobarena/files.rss";
/** public static void checkForUpdates(final MobArena plugin, final Player player) {
* Check if the current plugin version is the latest version. // Thread the entire thing to avoid lag
* @param plugin a MobArena instance Thread thread = new Thread(new Runnable() {
* @return false, if the version is not the latest, true otherwise @Override
*/ public void run() {
public static boolean isLatest(MobArena plugin) { // Grab the version string from the feed
if (!plugin.getMAConfig().getBoolean("global-settings.update-notification", false)) { final String latestVersion = getLatestVersion();
return true; if (latestVersion == null) return;
// First check equality with the current version
final String currentVersion = plugin.getDescription().getVersion();
if (currentVersion.equals(latestVersion)) {
return;
}
// Split into major-minor-patch
String[] latestParts = latestVersion.split("\\.");
String[] currentParts = currentVersion.split("\\.");
// Number of comparisons
int parts = Math.max(latestParts.length, currentParts.length);
// Check version numbers
for (int i = 0; i < parts; i++) {
int latest = getPart(latestParts, i);
int current = getPart(currentParts, i);
// Early returns
if (current > latest) {
return;
}
if (current < latest) {
// Use the scheduler to avoid concurrency complaints
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
if (player == null) {
Messenger.info("MobArena v" + latestVersion + " is now available!");
Messenger.info("Your version: v" + currentVersion);
} else if (player.isOnline()) {
Messenger.tellPlayer(player, "MobArena v" + latestVersion + " is now available!");
Messenger.tellPlayer(player, "Your version: v" + currentVersion);
}
}
}, (player == null ? 0 : 60));
return;
}
}
Messenger.info("Later!");
}
});
// Start the damn thing.
thread.start();
}
private static int getPart(String[] parts, int index) {
try {
return Integer.parseInt(parts[index]);
} catch (Exception e) {
return 0;
} }
}
// Format is "<MAJOR>.<MINOR>.<PATCH>"
private static String getLatestVersion() {
// Input stream for the feed
InputStream is = null;
// The version string
String version = null;
try { try {
// Make a URI of the site address // Open the stream
URI baseURI = new URI(site); is = new URL(url).openStream();
// Open the connection and don't redirect. // Build the document
HttpURLConnection con = (HttpURLConnection) baseURI.toURL().openConnection(); Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
con.setConnectTimeout(5000);
con.setInstanceFollowRedirects(false);
String header = con.getHeaderField("Location"); // Get all the "title" elements (where the version string will be)
NodeList list = doc.getElementsByTagName("title");
// If something's wrong with the connection... // Loop through the items, and break when a version string has been found.
if (header == null) { for (int i = 0; i < list.getLength(); i++) {
return true; String line = list.item(i).getTextContent();
if (line.matches("MobArena v.*")) {
version = line.substring("MobArena v".length(), line.length());
break;
}
} }
} catch (Exception e) {
// Otherwise, grab the location header to get the real URI. Messenger.warning("The version checker failed.");
String url = new URI(con.getHeaderField("Location")).toString(); Messenger.warning("This is harmless, but check for updates manually!");
} finally {
// Set up the regex and matcher try {
Pattern regex = Pattern.compile("v([0-9]+-)*[0-9]+"); if (is != null) is.close();
Matcher matcher = regex.matcher(url); } catch (Exception ex) {
if (!matcher.find()) { Messenger.severe("Failed to close the version checker stream!");
return true;
}
String thisVersion = plugin.getDescription().getVersion();
String forumVersion = matcher.group().substring(1).replace("-", ".");
return isLatest(thisVersion, forumVersion);
}
catch (Exception e) {
e.printStackTrace();
}
return true;
}
/**
* Check if thisVersion is newer than or equal to forumVersion
* @param thisVersion a version string
* @param forumVersion a version string
* @return true, if thisVersion is newer than or equal to forumVersion, false otherwise
*/
public static boolean isLatest(String thisVersion, String forumVersion) {
String[] forumParts = forumVersion.split("\\.");
String[] thisParts = thisVersion.split("\\.");
int current, forum;
boolean thisIsNewer = false;
for (int i = 0; i < Math.max(forumParts.length, thisParts.length); i++) {
forum = forumParts.length <= i ? 0 : Integer.parseInt(forumParts[i]);
current = thisParts.length <= i ? 0 : Integer.parseInt(thisParts[i]);
if (forum < current) {
thisIsNewer = true;
}
if (forum > current && !thisIsNewer) {
return false;
} }
} }
return version;
return true;
} }
} }