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:
		@@ -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()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
@@ -48,22 +48,22 @@ public class ConfigLoader
 | 
			
		||||
    private void makeConfig()
 | 
			
		||||
    {
 | 
			
		||||
        // All the comments for the various config options.
 | 
			
		||||
        String[] unbreakableComment    =
 | 
			
		||||
        String[] unbreakableComment =
 | 
			
		||||
            {
 | 
			
		||||
                 "Setting this to true will cause armored elytras to be unbreakable.",
 | 
			
		||||
                 "Changing this to false will NOT make unbreakable elytras breakable again!"
 | 
			
		||||
                "Setting this to true will cause armored elytras to be unbreakable.",
 | 
			
		||||
                "Changing this to false will NOT make unbreakable elytras breakable again!"
 | 
			
		||||
            };
 | 
			
		||||
        String[] flyDurabilityComment  =
 | 
			
		||||
        String[] flyDurabilityComment =
 | 
			
		||||
            {
 | 
			
		||||
             "Setting this to true will cause armored elytras to not lose any durability while flying.",
 | 
			
		||||
             "This is not a permanent option and will affect ALL elytras."
 | 
			
		||||
                "Setting this to true will cause armored elytras to not lose any durability while flying.",
 | 
			
		||||
                "This is not a permanent option and will affect ALL elytras."
 | 
			
		||||
            };
 | 
			
		||||
        String[] repairComment         =
 | 
			
		||||
        String[] repairComment =
 | 
			
		||||
            {
 | 
			
		||||
                "Amount of items it takes to fully repair an armored elytra",
 | 
			
		||||
                "Repair cost for every tier of armored elytra in number of items to repair 100%."
 | 
			
		||||
            };
 | 
			
		||||
        String[] enchantmentsComment   =
 | 
			
		||||
        String[] enchantmentsComment =
 | 
			
		||||
            {
 | 
			
		||||
                "List of enchantments that are allowed to be put on an armored elytra.",
 | 
			
		||||
                "If you do not want to allow any enchantments at all, remove them all and add \"NONE\"",
 | 
			
		||||
@@ -71,20 +71,25 @@ public class ConfigLoader
 | 
			
		||||
                "https://hub.spigotmc.org/javadocs/spigot/org/bukkit/enchantments/Enchantment.html",
 | 
			
		||||
                "Note that only 1 protection enchantment (PROTECTION_FIRE, PROTECTION_ENVIRONMENTAL etc) can be active on an elytra."
 | 
			
		||||
            };
 | 
			
		||||
        String[] updateComment         =
 | 
			
		||||
        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[] bStatsComment         =
 | 
			
		||||
        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 =
 | 
			
		||||
            {
 | 
			
		||||
                "Allow this plugin to send (anonymised) stats using bStats. Please consider keeping it enabled.",
 | 
			
		||||
                "It has a negligible impact on performance and more users on stats keeps me more motivated to support this plugin!"
 | 
			
		||||
            };
 | 
			
		||||
        String[] debugComment          =
 | 
			
		||||
        String[] debugComment =
 | 
			
		||||
            {
 | 
			
		||||
                "Print debug messages to console. You will most likely never need this."
 | 
			
		||||
            };
 | 
			
		||||
        String[] uninstallComment      =
 | 
			
		||||
        String[] uninstallComment =
 | 
			
		||||
            {
 | 
			
		||||
                "Setting this to true will disable this plugin and remove any armored elytras it can find.",
 | 
			
		||||
                "It will check player's inventories and their end chest upon login and any regular chest when it is opened.",
 | 
			
		||||
@@ -92,7 +97,7 @@ public class ConfigLoader
 | 
			
		||||
                "a lot of resources, so you can just leave the plugin enabled and ignore it.",
 | 
			
		||||
                "Please do not forget to MAKE A BACKUP before enabling this option!"
 | 
			
		||||
            };
 | 
			
		||||
        String[] languageFileComment   =
 | 
			
		||||
        String[] languageFileComment =
 | 
			
		||||
            {
 | 
			
		||||
                "Specify a language file to be used. Note that en_US.txt will get regenerated!"
 | 
			
		||||
            };
 | 
			
		||||
@@ -112,8 +117,9 @@ public class ConfigLoader
 | 
			
		||||
 | 
			
		||||
        // Set default list of allowed enchantments.
 | 
			
		||||
        allowedEnchantments = new ArrayList<>(Arrays.asList("DURABILITY", "PROTECTION_FIRE", "PROTECTION_EXPLOSIONS",
 | 
			
		||||
                                                                  "PROTECTION_PROJECTILE", "PROTECTION_ENVIRONMENTAL", "THORNS",
 | 
			
		||||
                                                                  "BINDING_CURSE", "VANISHING_CURSE", "MENDING"));
 | 
			
		||||
                                                            "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();
 | 
			
		||||
    }
 | 
			
		||||
@@ -161,7 +171,7 @@ public class ConfigLoader
 | 
			
		||||
                saveTo.delete();
 | 
			
		||||
                saveTo.createNewFile();
 | 
			
		||||
            }
 | 
			
		||||
            FileWriter  fw = new FileWriter(saveTo, true);
 | 
			
		||||
            FileWriter fw = new FileWriter(saveTo, true);
 | 
			
		||||
            PrintWriter pw = new PrintWriter(fw);
 | 
			
		||||
 | 
			
		||||
            if (header != null)
 | 
			
		||||
@@ -169,16 +179,17 @@ 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"));
 | 
			
		||||
                               // Only print an additional newLine if the next config option has a comment.
 | 
			
		||||
                               (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;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										466
									
								
								src/main/java/nl/pim16aap2/armoredElytra/util/UpdateChecker.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										466
									
								
								src/main/java/nl/pim16aap2/armoredElytra/util/UpdateChecker.java
									
									
									
									
									
										Normal 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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										117
									
								
								src/main/java/nl/pim16aap2/armoredElytra/util/UpdateManager.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/main/java/nl/pim16aap2/armoredElytra/util/UpdateManager.java
									
									
									
									
									
										Normal 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;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user