From e9f870251f5859135ce807ee7bb945ad09601ed7 Mon Sep 17 00:00:00 2001 From: Zolli Date: Mon, 18 Mar 2013 21:59:39 +0100 Subject: [PATCH] *Updater partially working --- resources/config.yml | 5 + .../Commands/command/updateCommand.java | 86 +++++++++++ src/com/Zolli/EnderCore/EnderCore.java | 13 +- .../EnderCore/Updater/updateChecker.java | 145 ++++++++++++++++++ .../Updater/updateDownloaderThread.java | 40 +++++ 5 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 src/com/Zolli/EnderCore/Commands/command/updateCommand.java create mode 100644 src/com/Zolli/EnderCore/Updater/updateDownloaderThread.java diff --git a/resources/config.yml b/resources/config.yml index 0af5203..532e26c 100644 --- a/resources/config.yml +++ b/resources/config.yml @@ -21,6 +21,11 @@ database: username: 'root' password: '' +updater: + updateChannel: 'STABLE' + autoUpdate: 'true' + notifyUpdate: 'true' + dragons: desiredDragonCount: '1' diff --git a/src/com/Zolli/EnderCore/Commands/command/updateCommand.java b/src/com/Zolli/EnderCore/Commands/command/updateCommand.java new file mode 100644 index 0000000..b9034d7 --- /dev/null +++ b/src/com/Zolli/EnderCore/Commands/command/updateCommand.java @@ -0,0 +1,86 @@ +package com.Zolli.EnderCore.Commands.command; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.command.CommandSender; + +import com.Zolli.EnderCore.EnderCore; +import com.Zolli.EnderCore.Commands.ECCommand; +import com.Zolli.EnderCore.Updater.updateChecker.updateResult; + +public class updateCommand implements ECCommand { + + List permissions = new ArrayList(); + List examples = new ArrayList(); + EnderCore plugin; + + public updateCommand(EnderCore instance) { + this.plugin = instance; + + this.examples.add("/ec update "); + this.permissions.add("ec.update"); + this.permissions.add("ec.admin"); + } + + @Override + public boolean execute(CommandSender sender, String[] args,String chainedParams) { + this.plugin.updater.checkUpdate(); + + /* STATUS subcommand */ + if(args[1].equalsIgnoreCase("status")) { + if(this.plugin.updater.getResult().equals(updateResult.SUCCESS)) { + sender.sendMessage("An update is already downloaded. Please restart, or reload the server to take effect"); + } else if(this.plugin.updater.getResult().equals(updateResult.FAILED_TO_DOWNLOAD)) { + sender.sendMessage("An update is available, but the latest download attemp is failed. Sent notification to plugin developer!"); + } else if(this.plugin.updater.getResult().equals(updateResult.FAILED_CHECK)) { + sender.sendMessage("An error has occurred while checking for updates. Sent notification to plugin developer!"); + } else if(this.plugin.updater.getResult().equals(updateResult.UPDATE_AVAILABLE)) { + sender.sendMessage("An update available for this plugin."); + sender.sendMessage("Use /ec update download command to download this update"); + } else { + sender.sendMessage("No update available for this plugin in current channel!"); + } + /* DOWNLOAD subcommand */ + } else if(args[1].equalsIgnoreCase("download")) { + if(this.plugin.updater.getResult().equals(updateResult.UPDATE_AVAILABLE)) { + this.plugin.updater.downloadUpdate(); + } else { + sender.sendMessage("No UPDATE"); + } + /* CHANGELOG subcommand */ + } else if(args[1].equalsIgnoreCase("changelog")) { + sender.sendMessage(this.plugin.updater.getChangelog()); + /* Channel subcommand */ + } else if(args[1].equalsIgnoreCase("channel")) { + sender.sendMessage("You are receivering updates from the following update channel: " + this.plugin.updater.getChannel()); + } + return false; + } + + @Override + public String getName() { + return "update"; + } + + @Override + public boolean isAccessibleFromConsole() { + return true; + } + + @Override + public List getPermission() { + return this.permissions; + } + + @Override + public int getArgsLength() { + return 1; + } + + @Override + public List getExample() { + return this.examples; + } + +} diff --git a/src/com/Zolli/EnderCore/EnderCore.java b/src/com/Zolli/EnderCore/EnderCore.java index 0252ec9..6cf5a69 100644 --- a/src/com/Zolli/EnderCore/EnderCore.java +++ b/src/com/Zolli/EnderCore/EnderCore.java @@ -13,6 +13,7 @@ import com.Zolli.EnderCore.Commands.commandHandler; import com.Zolli.EnderCore.Commands.command.infoCommand; +import com.Zolli.EnderCore.Commands.command.updateCommand; import com.Zolli.EnderCore.Configuration.Configuration; import com.Zolli.EnderCore.Economy.economyHandler; import com.Zolli.EnderCore.Listeners.blockListener; @@ -27,6 +28,8 @@ import com.Zolli.EnderCore.Permission.permissionHandler; import com.Zolli.EnderCore.Storage.Storage; import com.Zolli.EnderCore.Storage.storageActions; +import com.Zolli.EnderCore.Updater.updateChecker; +import com.Zolli.EnderCore.Updater.updateDownloaderThread; public class EnderCore extends JavaPlugin { @@ -53,7 +56,7 @@ public class EnderCore extends JavaPlugin { /** * PluginDescriptionFile object */ - private PluginDescriptionFile pluginDescription; + public PluginDescriptionFile pluginDescription; /** * Location of plugin data folder @@ -100,6 +103,11 @@ public class EnderCore extends JavaPlugin { */ public economyHandler economy; + /** + * updateChecker object + */ + public updateChecker updater; + /** * Runs when plugin initialization started */ @@ -139,6 +147,8 @@ public void onEnable() { this.registerCommands(); /* Log the successfully initialization */ + + this.updater = new updateChecker(this); this.logger.log(Level.INFO, "Sucessfully enabled!"); } @@ -168,6 +178,7 @@ private void registerListeners() { private void registerCommands() { this.getCommand("ec").setExecutor(this.command); this.command.registerCommand("info", new infoCommand(this)); + this.command.registerCommand("update", new updateCommand(this)); } /** diff --git a/src/com/Zolli/EnderCore/Updater/updateChecker.java b/src/com/Zolli/EnderCore/Updater/updateChecker.java index c6d5233..d1c5a58 100644 --- a/src/com/Zolli/EnderCore/Updater/updateChecker.java +++ b/src/com/Zolli/EnderCore/Updater/updateChecker.java @@ -1,16 +1,161 @@ package com.Zolli.EnderCore.Updater; import com.Zolli.EnderCore.EnderCore; +import com.Zolli.EnderCore.Logger.simpleLogger.Level; +import com.Zolli.EnderCore.Utils.networkUtils; public class updateChecker { private EnderCore plugin; + private String serverVersion; + private String pluginVersion; + private releaseChannel selectedChannel; + private updateResult result; + private String changelog; + private String latestVersion; + private String latestVersionBuildNumber; + private String latestVersionFile; + /** + * Constructor + * @param instance Main class instance + */ public updateChecker(EnderCore instance) { this.plugin = instance; + this.serverVersion = this.formatBukkitVersion(this.plugin.getServer().getBukkitVersion()); + this.pluginVersion = this.plugin.pluginDescription.getVersion(); + + String configValue = plugin.config.getString("updater.updateChannel"); + + if(configValue.equalsIgnoreCase("LATEST_BUILD")) { + this.selectedChannel = releaseChannel.LATEST_BUILD; + } else if(configValue.equalsIgnoreCase("RELEASE_PREVIEW")) { + this.selectedChannel = releaseChannel.RELEASE_PREVIEW; + } else if (configValue.equalsIgnoreCase("STABLE")) { + this.selectedChannel = releaseChannel.STABLE; + } else { + this.selectedChannel = releaseChannel.STABLE; + } + + this.result = updateResult.NO_UPDATE; + } + + /** + * Turn server version string into a properly formatted string, that accept the updateCheck server + * @param version The server version + * @return String Formatted value + */ + private String formatBukkitVersion(String version) { + String semiFormatted = version.replace(".", "").toString().replace("-", "").toString().replace('R', '.'); + String[] parts = semiFormatted.split("\\."); + + if(parts[0].length() < 3) { + parts[0] = parts[0] + "0"; + } + + String finalString = parts[0] + "." + parts[1]; + return finalString; } + /** + * Fetch update from update site + */ public void checkUpdate() { + String updateResponse = networkUtils.getContent("http://ec.zolli.tk/updater/publisher.php?p=" + this.pluginVersion + "&b=" + this.serverVersion + "&c=" + this.selectedChannel.getChannelId()); + String[] parts = updateResponse.split("ENDSECTION"); + + this.latestVersion = parts[1]; + this.latestVersionBuildNumber = parts[2]; + this.changelog = this.paresChangelog(parts[0].split(";")); + this.latestVersionFile = parts[3]; + + if(Double.parseDouble(this.latestVersion) > Double.parseDouble(this.pluginVersion)) { + this.result = updateResult.UPDATE_AVAILABLE; + } else if(updateResponse.equals(null)) { + this.result = updateResult.FAILED_CHECK; + } else { + this.result = updateResult.NO_UPDATE; + } + } + + /** + * Format the string returned by the updater + * @param changes Unformatted changelog + * @return string Formatted changelog + */ + private String paresChangelog(String[] changes) { + String returnString = ""; + + for(int i = 0 ; i < changes.length-1 ; i++ ) { + returnString = returnString + changes[i] + ". "; + } + return returnString; + } + + /** + * Download the selected file from update server and copy it to the update directory + */ + public void downloadUpdate() { + updateDownloaderThread downloader = new updateDownloaderThread("http://ec.zolli.tk/updater/files/EnderCore.jar", this.plugin.logger); + Thread t = new Thread(downloader); + t.start(); + try { + t.join(); + this.result = downloader.getdownloadResult(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public updateResult getResult() { + return this.result; + } + + public String getChannel() { + return this.selectedChannel.getName(); + } + + public String getLatestVersion() { + return this.latestVersion; + } + + public String getChangelog() { + return this.changelog; + } + + /** + * + * @author Zolli + */ + public enum updateResult { + SUCCESS, + NO_UPDATE, + UPDATE_AVAILABLE, + FAILED_TO_DOWNLOAD, + FAILED_CHECK, + FAILED_VERSION; + } + + public enum releaseChannel { + LATEST_BUILD("Latest build", 1), + RELEASE_PREVIEW("Release preview", 2), + STABLE("Stable", 3); + + private String channelName; + private int channelId; + + private releaseChannel(String name, int cid) { + this.channelName = name; + this.channelId = cid; + } + + public String getName() { + return this.channelName; + } + + public int getChannelId() { + return this.channelId; + } } diff --git a/src/com/Zolli/EnderCore/Updater/updateDownloaderThread.java b/src/com/Zolli/EnderCore/Updater/updateDownloaderThread.java new file mode 100644 index 0000000..d05f8bd --- /dev/null +++ b/src/com/Zolli/EnderCore/Updater/updateDownloaderThread.java @@ -0,0 +1,40 @@ +package com.Zolli.EnderCore.Updater; + +import com.Zolli.EnderCore.Logger.simpleLogger; +import com.Zolli.EnderCore.Logger.simpleLogger.Level; +import com.Zolli.EnderCore.Updater.updateChecker.updateResult; +import com.Zolli.EnderCore.Utils.networkUtils; + +public class updateDownloaderThread implements Runnable { + + String downloadUrl; + simpleLogger log; + updateResult downloadResult; + + public updateDownloaderThread(String url, simpleLogger log) { + this.downloadUrl = url; + this.log = log; + } + + public updateResult getdownloadResult() { + return this.downloadResult; + } + + @Override + public void run() { + try { + this.log.log(Level.INFO, this.downloadUrl); + if(!(networkUtils.downloadAndSave(this.downloadUrl, "./plugins/update/EnderCore.jar", log))) { + this.downloadResult = updateResult.FAILED_TO_DOWNLOAD; + } else { + this.downloadResult = updateResult.SUCCESS; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + this.log.log(Level.INFO, "Update downloaded sucessfully"); + } + } + + +}