Update updater

- Updated the updater to use the same system BigDoors uses. This system is much cleaner and better and it uses Spiget to check for updates instead of DBO.
- Introduced new config option "auto-update" to control if new updates are downloaded automatically or not.
This commit is contained in:
Pim van der Loos 2020-05-20 12:19:40 +02:00
parent 51854fa150
commit e093b18124
No known key found for this signature in database
GPG Key ID: C16F020ADAE6D5A8
4 changed files with 642 additions and 76 deletions

View File

@ -10,7 +10,7 @@ import nl.pim16aap2.armoredElytra.util.ArmorTier;
import nl.pim16aap2.armoredElytra.util.ArmorTierName;
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
import nl.pim16aap2.armoredElytra.util.Messages;
import nl.pim16aap2.armoredElytra.util.Update;
import nl.pim16aap2.armoredElytra.util.UpdateManager;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@ -25,10 +25,10 @@ import java.util.Objects;
import java.util.logging.Level;
import java.util.regex.Pattern;
// TODO: Use this for NBT stuff: https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/
// TODO: Figure out if the config really does read the list of enchantments accurately. A bug report with a customized config seemed to load the default settings...
// TODO: Verify enchantments on startup. Remove them from the list if they're invalid.
// TODO: Don't delete the config file. Look at BigDoors.
// TODO: Don't delete the config/translation file. Look at BigDoors.
// TODO: Enchanting should require XP.
public class ArmoredElytra extends JavaPlugin implements Listener
{
@ -36,13 +36,13 @@ public class ArmoredElytra extends JavaPlugin implements Listener
private Messages messages;
private ConfigLoader config;
// private String leatherName, ironName, goldName, chainName, diamondName;
private final Map<ArmorTier, ArmorTierName> armorTierNames = new EnumMap(ArmorTier.class);
private final Map<ArmorTier, ArmorTierName> armorTierNames = new EnumMap<>(ArmorTier.class);
private String elytraReceivedMessage;
private String usageDeniedMessage;
private String elytraLore;
private boolean upToDate;
private boolean is1_9;
private UpdateManager updateManager;
@Override
public void onEnable()
@ -52,48 +52,10 @@ public class ArmoredElytra extends JavaPlugin implements Listener
messages = new Messages(this);
readMessages();
updateManager = new UpdateManager(this, 47136);
// Check if the user allows checking for updates.
if (config.checkForUpdates())
{
// Check for updates in a new thread, so the server won't hang when it cannot contact the update servers.
final Thread thread = new Thread(
() ->
{
final ArmoredElytra plugin = getPlugin();
final Update update = new Update(278437, plugin);
final String latestVersion = update.getLatestVersion();
if (latestVersion == null)
plugin.myLogger(Level.WARNING,
"Encountered problem contacting update servers! Please check manually! The error above does not affect the plugin!");
else
{
final String thisVersion = plugin.getDescription().getVersion();
// Check if this is the latest version or not.
final int updateStatus = update.versionCompare(latestVersion, thisVersion);
if (updateStatus > 0)
{
// Load the loginHandler to show messages to the user when they join.
Bukkit.getPluginManager()
.registerEvents(new LoginHandler(plugin, "The Armored Elytra plugin is out of date!"),
plugin);
plugin.myLogger(Level.INFO, "Plugin out of date! You are using version " + thisVersion +
" but the latest version is version " + latestVersion + "!");
plugin.setUpToDate(false);
}
else
{
plugin.setUpToDate(true);
plugin.myLogger(Level.INFO, "You seem to be using the latest version of this plugin!");
}
}
});
thread.start();
}
else
myLogger(Level.INFO,
"Plugin update checking not enabled! You will not receive any messages about new updates for this plugin. Please consider turning this on in the config.");
updateManager.setEnabled(config.checkForUpdates(), config.autoDLUpdate());
if (config.allowStats())
{
@ -280,6 +242,11 @@ public class ArmoredElytra extends JavaPlugin implements Listener
player.getInventory().addItem(item);
}
public UpdateManager getUpdateManager()
{
return updateManager;
}
// Check + initialize for the correct version of Minecraft.
public boolean compatibleMCVer()
{

View File

@ -1,5 +1,9 @@
package nl.pim16aap2.armoredElytra.util;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
@ -9,11 +13,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
public class ConfigLoader
{
private final String header;
@ -25,6 +24,7 @@ public class ConfigLoader
private int IRON_TO_FULL;
private boolean uninstallMode;
private boolean checkForUpdates;
private boolean autoDLUpdate;
private int LEATHER_TO_FULL;
private int DIAMONDS_TO_FULL;
private boolean noFlightDurability;
@ -33,7 +33,7 @@ public class ConfigLoader
public boolean bypassWearPerm;
public boolean bypassCraftPerm;
private ArrayList<ConfigOption<?>> configOptionsList;
private ArrayList<nl.pim16aap2.armoredElytra.util.ConfigOption<?>> configOptionsList;
private ArmoredElytra plugin;
public ConfigLoader(ArmoredElytra plugin)
@ -73,7 +73,12 @@ public class ConfigLoader
};
String[] updateComment =
{
"Allow this plugin to check for updates on startup. It will not download new versions!"
"Allow this plugin to check for updates on startup. It will not download new versions unless \"auto-update is enabled\'!"
};
String[] autoDLUpdateComment =
{
"Allow this plugin to automatically download new updates. They will be applied on restart.",
"This option has no effect if \"checkForUpdates\" is disabled."
};
String[] bStatsComment =
{
@ -112,7 +117,8 @@ public class ConfigLoader
// Set default list of allowed enchantments.
allowedEnchantments = new ArrayList<>(Arrays.asList("DURABILITY", "PROTECTION_FIRE", "PROTECTION_EXPLOSIONS",
"PROTECTION_PROJECTILE", "PROTECTION_ENVIRONMENTAL", "THORNS",
"PROTECTION_PROJECTILE", "PROTECTION_ENVIRONMENTAL",
"THORNS",
"BINDING_CURSE", "VANISHING_CURSE", "MENDING"));
FileConfiguration config = plugin.getConfig();
@ -123,9 +129,12 @@ public class ConfigLoader
GOLD_TO_FULL = addNewConfigOption(config, "goldRepair", 5, null);
IRON_TO_FULL = addNewConfigOption(config, "ironRepair", 4, null);
DIAMONDS_TO_FULL = addNewConfigOption(config, "diamondsRepair", 3, null);
allowedEnchantments = addNewConfigOption(config, "allowedEnchantments", allowedEnchantments, enchantmentsComment);
allowMultipleProtectionEnchantments = addNewConfigOption(config, "allowMultipleProtectionEnchantments", false, allowMultipleProtectionEnchantmentsComment);
allowedEnchantments = addNewConfigOption(config, "allowedEnchantments", allowedEnchantments,
enchantmentsComment);
allowMultipleProtectionEnchantments = addNewConfigOption(config, "allowMultipleProtectionEnchantments", false,
allowMultipleProtectionEnchantmentsComment);
checkForUpdates = addNewConfigOption(config, "checkForUpdates", true, updateComment);
autoDLUpdate = addNewConfigOption(config, "auto-update", true, autoDLUpdateComment);
allowStats = addNewConfigOption(config, "allowStats", true, bStatsComment);
enableDebug = addNewConfigOption(config, "enableDebug", false, debugComment);
uninstallMode = addNewConfigOption(config, "uninstallMode", false, uninstallComment);
@ -138,7 +147,8 @@ public class ConfigLoader
private <T> T addNewConfigOption(FileConfiguration config, String optionName, T defaultValue, String[] comment)
{
ConfigOption<T> option = new ConfigOption<>(plugin, config, optionName, defaultValue, comment);
nl.pim16aap2.armoredElytra.util.ConfigOption<T> option = new nl.pim16aap2.armoredElytra.util.ConfigOption<>(
plugin, config, optionName, defaultValue, comment);
configOptionsList.add(option);
return option.getValue();
}
@ -170,15 +180,16 @@ public class ConfigLoader
for (int idx = 0; idx < configOptionsList.size(); ++idx)
pw.println(configOptionsList.get(idx).toString() +
// Only print an additional newLine if the next config option has a comment.
(idx < configOptionsList.size() - 1 && configOptionsList.get(idx + 1).getComment() == null ? ""
: "\n"));
(idx < configOptionsList.size() - 1 &&
configOptionsList.get(idx + 1).getComment() == null ? "" : "\n"));
pw.flush();
pw.close();
}
catch (IOException e)
{
Bukkit.getLogger().log(Level.SEVERE, "Could not save config.yml! Please contact pim16aap2 and show him the following code:");
Bukkit.getLogger().log(Level.SEVERE,
"Could not save config.yml! Please contact pim16aap2 and show him the following code:");
e.printStackTrace();
}
}
@ -239,6 +250,11 @@ public class ConfigLoader
return checkForUpdates;
}
public boolean autoDLUpdate()
{
return autoDLUpdate;
}
public boolean noFlightDurability()
{
return noFlightDurability;

View File

@ -0,0 +1,466 @@
package nl.pim16aap2.armoredElytra.util;
import com.google.common.base.Preconditions;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
import org.apache.commons.lang.math.NumberUtils;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.Instant;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A utility class to assist in checking for updates for plugins uploaded to
* <a href="https://spigotmc.org/resources/">SpigotMC</a>. Before any members of
* this class are accessed, {@link #init(ArmoredElytra, int)} must be invoked by the plugin, preferably in its {@link
* JavaPlugin#onEnable()} method, though that is not a requirement.
* <p>
* This class performs asynchronous queries to
* <a href="https://spiget.org">SpiGet</a>, an REST server which is updated
* periodically. If the results of {@link #requestUpdateCheck()} are inconsistent with what is published on SpigotMC, it
* may be due to SpiGet's cache. Results will be updated in due time.
* <p>
* Some modifications were made to support downloading of updates and storing the age of an update.
*
* @author Parker Hawke - 2008Choco
*/
public final class UpdateChecker
{
public static final VersionScheme VERSION_SCHEME_DECIMAL = (first, second) ->
{
String[] firstSplit = splitVersionInfo(first), secondSplit = splitVersionInfo(second);
if (firstSplit == null || secondSplit == null)
return null;
for (int i = 0; i < Math.min(firstSplit.length, secondSplit.length); i++)
{
int currentValue = NumberUtils.toInt(firstSplit[i]), newestValue = NumberUtils.toInt(secondSplit[i]);
if (newestValue > currentValue)
return second;
else if (newestValue < currentValue)
return first;
}
return (secondSplit.length > firstSplit.length) ? second : first;
};
private static final String USER_AGENT = "ArmoredElytra-update-checker";
private static final String UPDATE_URL = "https://api.spiget.org/v2/resources/%d/versions?size=1&sort=-releaseDate";
private static final Pattern DECIMAL_SCHEME_PATTERN = Pattern.compile("\\d+(?:\\.\\d+)*");
private final String downloadURL;
private static UpdateChecker instance;
private UpdateResult lastResult = null;
private final ArmoredElytra plugin;
private final int pluginID;
private final VersionScheme versionScheme;
private UpdateChecker(final ArmoredElytra plugin, final int pluginID, final VersionScheme versionScheme)
{
this.plugin = plugin;
this.pluginID = pluginID;
this.versionScheme = versionScheme;
downloadURL = "https://api.spiget.org/v2/resources/" + pluginID + "/download";
}
/**
* Requests an update check to SpiGet. This request is asynchronous and may not complete immediately as an HTTP GET
* request is published to the SpiGet API.
*
* @return a future update result
*/
public CompletableFuture<UpdateResult> requestUpdateCheck()
{
return CompletableFuture.supplyAsync(
() ->
{
int responseCode = -1;
try
{
URL url = new URL(String.format(UPDATE_URL, pluginID));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.addRequestProperty("User-Agent", USER_AGENT);
InputStreamReader reader = new InputStreamReader(connection.getInputStream());
responseCode = connection.getResponseCode();
JsonElement element = new JsonParser().parse(reader);
if (!element.isJsonArray())
return new UpdateResult(UpdateReason.INVALID_JSON);
reader.close();
JsonObject versionObject = element.getAsJsonArray().get(0).getAsJsonObject();
long age = -1;
String ageString = versionObject.get("releaseDate").getAsString();
try
{
age = getAge(Long.parseLong(ageString));
}
catch (NumberFormatException e)
{
plugin.myLogger(Level.WARNING,
"Failed to obtain age of update from ageString: \"" + ageString + "\"");
}
String current = plugin.getDescription().getVersion(), newest = versionObject.get("name")
.getAsString();
String latest = versionScheme.compareVersions(current, newest);
if (latest == null)
return new UpdateResult(UpdateReason.UNSUPPORTED_VERSION_SCHEME);
else if (latest.equals(current))
return new UpdateResult(current.equals(newest) ?
UpdateReason.UP_TO_DATE :
UpdateReason.UNRELEASED_VERSION, current, age);
else if (latest.equals(newest))
return new UpdateResult(UpdateReason.NEW_UPDATE, latest, age);
}
catch (IOException e)
{
return new UpdateResult(UpdateReason.COULD_NOT_CONNECT);
}
catch (JsonSyntaxException e)
{
return new UpdateResult(UpdateReason.INVALID_JSON);
}
return new UpdateResult(responseCode == 401 ?
UpdateReason.UNAUTHORIZED_QUERY : UpdateReason.UNKNOWN_ERROR);
});
}
/**
* Gets the difference in seconds between a given time and the current time.
*
* @param updateTime A moment in time to compare the current time to.
* @return The difference in seconds between a given time and the current time.
*/
private long getAge(final long updateTime)
{
long currentTime = Instant.now().getEpochSecond();
return currentTime - updateTime;
}
/**
* Gets the last update result that was queried by {@link #requestUpdateCheck()}. If no update check was performed
* since this class' initialization, this method will return null.
*
* @return the last update check result. null if none.
*/
public UpdateResult getLastResult()
{
return lastResult;
}
private static String[] splitVersionInfo(String version)
{
Matcher matcher = DECIMAL_SCHEME_PATTERN.matcher(version);
if (!matcher.find())
return null;
return matcher.group().split("\\.");
}
/**
* Gets the url to download the latest version from.
*
* @return The url to download the latest version from.
*/
public String getDownloadUrl()
{
return downloadURL;
}
/**
* Downloads the latest update.
*
* @return True if the download was successful.
*/
public boolean downloadUpdate()
{
boolean downloadSuccessfull = false;
try
{
File updateFolder = Bukkit.getUpdateFolderFile();
if (!updateFolder.exists())
if (!updateFolder.mkdirs())
throw new RuntimeException("Failed to create update folder!");
String fileName = plugin.getName() + ".jar";
File updateFile = new File(updateFolder + "/" + fileName);
// Follow any and all redirects until we've finally found the actual file.
String location = downloadURL;
HttpURLConnection httpConnection = null;
for (; ; )
{
URL url = new URL(location);
httpConnection = (HttpURLConnection) url.openConnection();
httpConnection.setInstanceFollowRedirects(false);
httpConnection.setRequestProperty("User-Agent", "ArmoredElytraUpdater");
String redirectLocation = httpConnection.getHeaderField("Location");
if (redirectLocation == null)
break;
location = redirectLocation;
httpConnection.disconnect();
}
if (httpConnection == null)
{
plugin.myLogger(Level.WARNING, "Failed to construct connection: " + location);
return false;
}
if (httpConnection.getResponseCode() != 200)
{
plugin.myLogger(Level.WARNING,
Util.exceptionToString(new RuntimeException("Download returned status #"
+ httpConnection
.getResponseCode() + "\n for URL: " + downloadURL)));
return false;
}
int grabSize = 4096;
BufferedInputStream in = new BufferedInputStream(httpConnection.getInputStream());
FileOutputStream fos = new FileOutputStream(updateFile);
BufferedOutputStream bout = new BufferedOutputStream(fos, grabSize);
byte[] data = new byte[grabSize];
int grab;
while ((grab = in.read(data, 0, grabSize)) >= 0)
bout.write(data, 0, grab);
bout.flush();
bout.close();
in.close();
fos.flush();
fos.close();
downloadSuccessfull = true;
}
catch (Exception e)
{
e.printStackTrace();
}
return downloadSuccessfull;
}
/**
* Initializes this update checker with the specified values and return its instance. If an instance of
* UpdateChecker has already been initialized, this method will act similarly to {@link #get()} (which is
* recommended after initialization).
*
* @param plugin the plugin for which to check updates. Cannot be null
* @param pluginID the ID of the plugin as identified in the SpigotMC resource link. For example,
* "https://www.spigotmc.org/resources/veinminer.<b>12038</b>/" would expect "12038" as a
* value. The value must be greater than 0
* @param versionScheme a custom version scheme parser. Cannot be null
* @return the UpdateChecker instance
*/
public static UpdateChecker init(final ArmoredElytra plugin, final int pluginID, final VersionScheme versionScheme)
{
Preconditions.checkArgument(pluginID > 0, "Plugin ID must be greater than 0");
return (instance == null) ? instance = new UpdateChecker(plugin, pluginID, versionScheme) : instance;
}
/**
* Initializes this update checker with the specified values and return its instance. If an instance of
* UpdateChecker has already been initialized, this method will act similarly to {@link #get()} (which is
* recommended after initialization).
*
* @param plugin the plugin for which to check updates. Cannot be null
* @param pluginID the ID of the plugin as identified in the SpigotMC resource link. For example,
* "https://www.spigotmc.org/resources/veinminer.<b>12038</b>/" would expect "12038" as a value. The
* value must be greater than 0
* @return the UpdateChecker instance
*/
public static UpdateChecker init(final ArmoredElytra plugin, final int pluginID)
{
return init(plugin, pluginID, VERSION_SCHEME_DECIMAL);
}
/**
* Gets the initialized instance of UpdateChecker. If {@link #init(ArmoredElytra, int)} has not yet been invoked,
* this method will throw an exception.
*
* @return the UpdateChecker instance
*/
public static UpdateChecker get()
{
Preconditions.checkState(instance != null,
"Instance has not yet been initialized. Be sure #init() has been invoked");
return instance;
}
/**
* Checks whether the UpdateChecker has been initialized or not (if {@link #init(ArmoredElytra, int)} has been
* invoked) and {@link #get()} is safe to use.
*
* @return true if initialized, false otherwise
*/
public static boolean isInitialized()
{
return instance != null;
}
/**
* A functional interface to compare two version Strings with similar version schemes.
*/
@FunctionalInterface
public static interface VersionScheme
{
/**
* Compare two versions and return the higher of the two. If null is returned, it is assumed that at least one
* of the two versions are unsupported by this version scheme parser.
*
* @param first the first version to check
* @param second the second version to check
* @return the greater of the two versions. null if unsupported version schemes
*/
public String compareVersions(String first, String second);
}
/**
* A constant reason for the result of {@link UpdateResult}.
*/
public static enum UpdateReason
{
/**
* A new update is available for download on SpigotMC.
*/
NEW_UPDATE, // The only reason that requires an update
/**
* A successful connection to the SpiGet API could not be established.
*/
COULD_NOT_CONNECT,
/**
* The JSON retrieved from SpiGet was invalid or malformed.
*/
INVALID_JSON,
/**
* A 401 error was returned by the SpiGet API.
*/
UNAUTHORIZED_QUERY,
/**
* The version of the plugin installed on the server is greater than the one uploaded to SpigotMC's resources
* section.
*/
UNRELEASED_VERSION,
/**
* An unknown error occurred.
*/
UNKNOWN_ERROR,
/**
* The plugin uses an unsupported version scheme, therefore a proper comparison between versions could not be
* made.
*/
UNSUPPORTED_VERSION_SCHEME,
/**
* The plugin is up to date with the version released on SpigotMC's resources section.
*/
UP_TO_DATE
}
/**
* Represents a result for an update query performed by {@link UpdateChecker#requestUpdateCheck()}.
*/
public final class UpdateResult
{
private final UpdateReason reason;
private final String newestVersion;
private final long age;
{ // An actual use for initializer blocks. This is madness!
lastResult = this;
}
private UpdateResult(final UpdateReason reason, final String newestVersion, final long age)
{
this.reason = reason;
this.newestVersion = newestVersion;
this.age = age;
}
private UpdateResult(final UpdateReason reason)
{
Preconditions
.checkArgument(reason != UpdateReason.NEW_UPDATE && reason != UpdateReason.UP_TO_DATE,
"Reasons that might require updates must also provide the latest version String");
this.reason = reason;
newestVersion = plugin.getDescription().getVersion();
age = -1;
}
/**
* Gets the constant reason of this result.
*
* @return the reason
*/
public UpdateReason getReason()
{
return reason;
}
/**
* Checks whether or not this result requires the user to update.
*
* @return true if requires update, false otherwise
*/
public boolean requiresUpdate()
{
return reason == UpdateReason.NEW_UPDATE;
}
/**
* Gets the latest version of the plugin. This may be the currently installed version, it may not be. This
* depends entirely on the result of the update.
*
* @return the newest version of the plugin
*/
public String getNewestVersion()
{
return newestVersion;
}
/**
* Gets the number of seconds since the last update was released.
*
* @return The number of seconds since the last update was released or -1 if unavailable.
*/
public long getAge()
{
return age;
}
}
}

View File

@ -0,0 +1,117 @@
package nl.pim16aap2.armoredElytra.util;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
import nl.pim16aap2.armoredElytra.util.UpdateChecker.UpdateReason;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import java.util.logging.Level;
/**
* @author Pim
*/
public final class UpdateManager
{
private final ArmoredElytra plugin;
private boolean checkForUpdates = false;
private boolean downloadUpdates = false;
private boolean updateDownloaded = false;
private UpdateChecker updater;
private BukkitTask updateRunner = null;
public UpdateManager(final ArmoredElytra plugin, final int pluginID)
{
this.plugin = plugin;
updater = UpdateChecker.init(plugin, pluginID);
}
public void setEnabled(final boolean newCheckForUpdates, final boolean newDownloadUpdates)
{
checkForUpdates = newCheckForUpdates;
downloadUpdates = newDownloadUpdates;
initUpdater();
}
public boolean hasUpdateBeenDownloaded()
{
return updateDownloaded;
}
public String getNewestVersion()
{
if (!checkForUpdates || updater.getLastResult() == null)
return null;
return updater.getLastResult().getNewestVersion();
}
public boolean updateAvailable()
{
// Updates disabled, so no new updates available by definition.
if (!checkForUpdates || updater.getLastResult() == null)
return false;
// There's a newer version available.
if (updater.getLastResult().requiresUpdate())
return true;
// The plugin is "up-to-date", but this is a dev-build, so it must be newer.
if (updater.getLastResult().getReason().equals(UpdateReason.UP_TO_DATE))
return true;
return false;
}
public void checkForUpdates()
{
updater.requestUpdateCheck().whenComplete(
(result, throwable) ->
{
boolean updateAvailable = updateAvailable();
if (updateAvailable)
plugin.myLogger(Level.INFO,
"A new update is available: " + plugin.getUpdateManager().getNewestVersion());
if (downloadUpdates && updateAvailable)
{
updateDownloaded = updater.downloadUpdate();
if (updateDownloaded)
plugin.myLogger(Level.INFO, "Update downloaded! Restart to apply it! " +
"New version is " + updater.getLastResult().getNewestVersion() +
", Currently running " + plugin.getDescription().getVersion());
else
plugin.myLogger(Level.INFO,
"Failed to download latest version! You can download it manually at: " +
updater.getDownloadUrl());
}
});
}
private void initUpdater()
{
if (checkForUpdates)
{
// Run the UpdateChecker regularly.
if (updateRunner == null)
updateRunner = new BukkitRunnable()
{
@Override
public void run()
{
checkForUpdates();
}
}.runTaskTimer(plugin, 0L, 288000L); // Run immediately, then every 4 hours.
}
else
{
plugin.myLogger(Level.INFO,
"Plugin update checking not enabled! You will not receive any messages about new updates " +
"for this plugin. Please consider turning this on in the config.");
if (updateRunner != null)
{
updateRunner.cancel();
updateRunner = null;
}
}
}
}