From 7f5bbdf764f86bc61d685e2925c539a0c38f30f8 Mon Sep 17 00:00:00 2001 From: Bukkit/Spigot Date: Mon, 3 Jan 2011 11:01:36 +0800 Subject: [PATCH] all the fillr stuff By: Taylor Kelly --- paper-api/src/main/java/org/bukkit/Color.java | 20 ++ .../main/java/org/bukkit/fillr/Checker.java | 103 +++++++++++ .../java/org/bukkit/fillr/Downloader.java | 174 ++++++++++++++++++ .../java/org/bukkit/fillr/FillReader.java | 82 +++++++++ .../src/main/java/org/bukkit/fillr/Fillr.java | 67 +++++++ .../java/org/bukkit/fillr/PluginFilter.java | 17 ++ .../src/main/java/org/bukkit/fillr/README | 3 + .../main/java/org/bukkit/fillr/Updater.java | 102 ++++++++++ .../bukkit/plugin/PluginDescriptionFile.java | 17 +- 9 files changed, 582 insertions(+), 3 deletions(-) create mode 100644 paper-api/src/main/java/org/bukkit/Color.java create mode 100644 paper-api/src/main/java/org/bukkit/fillr/Checker.java create mode 100644 paper-api/src/main/java/org/bukkit/fillr/Downloader.java create mode 100644 paper-api/src/main/java/org/bukkit/fillr/FillReader.java create mode 100644 paper-api/src/main/java/org/bukkit/fillr/Fillr.java create mode 100644 paper-api/src/main/java/org/bukkit/fillr/PluginFilter.java create mode 100644 paper-api/src/main/java/org/bukkit/fillr/README create mode 100644 paper-api/src/main/java/org/bukkit/fillr/Updater.java diff --git a/paper-api/src/main/java/org/bukkit/Color.java b/paper-api/src/main/java/org/bukkit/Color.java new file mode 100644 index 0000000000..d751f122c8 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/Color.java @@ -0,0 +1,20 @@ +package org.bukkit; + +public class Color { + public static final String BLACK = "¤0"; + public static final String DARK_BLUE = "¤1"; + public static final String DARK_GREEN = "¤2"; + public static final String DARK_AQUA = "¤3"; + public static final String DARK_RED = "¤4"; + public static final String DARK_PURPLE = "¤5"; + public static final String GOLD = "¤6"; + public static final String GRAY = "¤7"; + public static final String DARK_GRAY = "¤8"; + public static final String BLUE = "¤9"; + public static final String GREEN = "¤a"; + public static final String AQUA = "¤b"; + public static final String RED = "¤c"; + public static final String LIGHT_PURPLE = "¤d"; + public static final String YELLOW = "¤e"; + public static final String WHITE = "¤f"; +} \ No newline at end of file diff --git a/paper-api/src/main/java/org/bukkit/fillr/Checker.java b/paper-api/src/main/java/org/bukkit/fillr/Checker.java new file mode 100644 index 0000000000..d105ad5179 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/fillr/Checker.java @@ -0,0 +1,103 @@ +package org.bukkit.fillr; + +import java.io.*; +import java.util.jar.*; +import org.bukkit.*; +import org.bukkit.plugin.*; + +public class Checker { + private static String directory = Fillr.directory; + + /** + * Checks all the .updatr files in Updatr/ for updates + * + * @param player + * The player to send info to + */ + public void check(Player player) { + File folder = new File(directory); + File[] files = folder.listFiles(new PluginFilter()); + if (files.length == 0) { + player.sendMessage("No plugins to update."); + } else { + player.sendMessage("Status for " + files.length + + " plugins:"); + for (File file : files) { + PluginDescriptionFile pdfFile = Checker.getPDF(file); + if(pdfFile == null) continue; + checkForUpdate(file, player); + } + } + } + + /** + * Checks for an update for a given .updatr file + * + * @param file + * The plugin file to check for an update + * @param player + * The player to send info to + */ + public void checkForUpdate(File file, Player player) { + PluginDescriptionFile pdfFile = Checker.getPDF(file); + FillReader reader = needsUpdate(pdfFile); + if (reader != null) { + player.sendMessage(Color.RED + reader.getName() + " " + + pdfFile.getVersion() + " has an update to " + + reader.getCurrVersion()); + } else { + player.sendMessage(reader.getName() + " " + reader.getCurrVersion() + + " is up to date!"); + } + } + + /** + * Checks if a given plugin needs an update + * + * @param file + * The .yml file to check + * @return The FillReader for the online repo info on the plugin + */ + public static FillReader needsUpdate(PluginDescriptionFile file) { + FillReader reader = new FillReader(file.getName()); + String version = file.getVersion(); + String currVersion = reader.getCurrVersion(); + String name = reader.getName(); + if (currVersion.equalsIgnoreCase(version) + && new File(directory, name + ".jar").exists()) { + return null; + } else { + return reader; + } + } + + /** + * Will grab the plugin's .yml file from the give file (hopefully a plugin). + * It'll throw it into a PluginDescriptionFile + * + * @param file + * The plugin (jar) file + * @return The PluginDescriptionFile representing the .yml + */ + public static PluginDescriptionFile getPDF(File file) { + // TODO supports only jar files for now. how will yml's be stored in + // different languages? + if (file.getName().endsWith(".jar")) { + JarFile jarFile; + try { + jarFile = new JarFile(file); + JarEntry entry = jarFile.getJarEntry("plugin.yml"); + InputStream input = jarFile.getInputStream(entry); + return new PluginDescriptionFile(input); + } catch (IOException e) { + e.printStackTrace(); + return null; + } catch (InvalidDescriptionException e) { + e.printStackTrace(); + return null; + } + } else + return null; + } + +} diff --git a/paper-api/src/main/java/org/bukkit/fillr/Downloader.java b/paper-api/src/main/java/org/bukkit/fillr/Downloader.java new file mode 100644 index 0000000000..bd055911c9 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/fillr/Downloader.java @@ -0,0 +1,174 @@ +package org.bukkit.fillr; + +import org.bukkit.*; +import org.bukkit.plugin.PluginDescriptionFile; + +import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; + +public class Downloader { + private static String directory = Fillr.directory; + private static String downloads = directory + File.separator + "downloads"; + private static String backup = "backup"; + + /** + * Downloads the jar from a given url. If it is a compressed archive, it + * tries to get the .jars out of it + * + * @param url + * The url to download from + */ + public static void downloadJar(String url) throws Exception { + int index = url.lastIndexOf('/'); + String name = url.substring(index + 1); + + File file = new File(directory, name); + if (url.endsWith(".jar") && file.exists()) + backupFile(file); + + download(new URL(url), name, directory); + file = new File("plugins", name); + /*if (name.endsWith(".zip") || name.endsWith(".tar") + || name.endsWith(".rar") || name.endsWith(".7z")) { + unzipPlugin(file); + file.delete(); + }*/ + } + + /** + * Downloads the file for a given plugin (if it's updatr file exists); + * + * @param name + * The name of the plugin to download + * @param player + * The player to send info to + */ + public void downloadFile(String name, Player player) throws Exception { + File file = new File(directory, name + ".jar"); + if (file.exists()) { + player.sendMessage("Downloading " + name + "'s file"); + PluginDescriptionFile pdfFile = Checker.getPDF(file); + FillReader reader = Checker.needsUpdate(pdfFile); + downloadFile(new URL(reader.getFile())); + player.sendMessage("Finished download"); + } else { + System.out.println("Can't find " + name); + } + } + + /** + * Downloads the file to the Updatr/downloads directory + * + * @param u + * The url of the file to download + */ + private void downloadFile(URL u) throws Exception { + String name = u.getFile(); + int index = name.lastIndexOf('/'); + name = name.substring(index + 1); + download(u, name, downloads); + } + + /** + * Downloads the file to a given directory with a given name + * + * @param u + * The url of the file to download + * @param name + * The name to give the file + * @param directory + * The directory to put the file + */ + private static void download(URL u, String name, String directory) + throws Exception { + InputStream inputStream = null; + // try { + inputStream = u.openStream(); + + if (!new File(directory).exists()) + new File(directory).mkdir(); + + File f = new File(directory, name); + if (f.exists()) + f.delete(); + f.createNewFile(); + + copyInputStream(inputStream, new BufferedOutputStream( + new FileOutputStream(f))); + + try { + if (inputStream != null) + inputStream.close(); + } catch (IOException ioe) { + System.out.println("[UPDATR]: Error closing inputStream"); + } + // } + } + + /** + * Decompresses a file! How nice. + * + * @param f + * the file to decompress + */ + private static void unzipPlugin(File f) { + try { + System.out.println("Extracting jars out of " + f.getName()); + //ExtractorUtil.extract(f, f.getAbsolutePath()); + } catch (Exception e) { + System.out.println("[UPDATR]: Error decompressing " + f.getName()); + } + } + + /** + * Copies an InputStream to an OutputStream! + * + * @param in + * InputStream + * @param out + * OutputStream + * @throws IOException + */ + public static final void copyInputStream(InputStream in, OutputStream out) + throws IOException { + byte[] buffer = new byte[1024]; + int len; + + while ((len = in.read(buffer)) >= 0) + out.write(buffer, 0, len); + + in.close(); + out.close(); + } + + /** + * Downloads the new updatr file + * + * @param url + * The url pointing to the updatr file + * @param name + * The name of the plugin + */ + public static void downloadUpdatr(String url, String name) throws Exception { + // try { + download(new URL(url), name + ".updatr", Fillr.directory); + } + + /** + * Moves the file to the backup folder. + * + * @param file + * The file to backup + */ + public static void backupFile(File file) { + if (file.exists()) { + System.out.println("Backing up old file: " + file.getName()); + if (!new File(backup).exists()) + new File(backup).mkdir(); + file.renameTo(new File(backup, file + .getName() + ".bak")); + } + } + +} \ No newline at end of file diff --git a/paper-api/src/main/java/org/bukkit/fillr/FillReader.java b/paper-api/src/main/java/org/bukkit/fillr/FillReader.java new file mode 100644 index 0000000000..58cfe5b0d2 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/fillr/FillReader.java @@ -0,0 +1,82 @@ +package org.bukkit.fillr; + +import java.util.*; +import java.io.*; +import java.net.URL; +import java.net.URLConnection; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +/** + * Grabs the latest info for a given plugin from fill.bukkit.org + */ +public class FillReader { + //TODO change this to what it will actually be... + private static String baseUrl = "http://taylorkelly.me/pnfo.php"; + + private String currVersion; + private String file; + private String name; + private String notes; + private boolean stable; + + public FillReader(String name) { + try { + String result = ""; + try { + URL url = new URL(baseUrl + "?name=" + name); + System.out.println(baseUrl + "?name=" + name); + URLConnection conn = url.openConnection(); + StringBuilder buf = new StringBuilder(); + BufferedReader rd = new BufferedReader(new InputStreamReader( + conn.getInputStream())); + String line; + while ((line = rd.readLine()) != null) { + buf.append(line); + } + result = buf.toString(); + rd.close(); + JSONParser parser = new JSONParser(); + Object obj; + obj = parser.parse(result); + JSONObject jsonObj = (JSONObject) obj; + this.currVersion = (String)jsonObj.get("plugin_version"); + this.name = (String)jsonObj.get("plugin_name"); + this.file = (String)jsonObj.get("plugin_file"); + this.stable = (Boolean)jsonObj.get("plugin_stable"); + this.notes = (String)jsonObj.get("plugin_notes"); + } catch (ParseException e) { + e.printStackTrace(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public String getCurrVersion() { + return currVersion; + } + + public String getFile() { + return file; + } + + public String getName() { + return name; + } + + public String getNotes() { + return notes; + } + + public void setStable(boolean stable) { + this.stable = stable; + } + + public boolean isStable() { + return stable; + } + +} diff --git a/paper-api/src/main/java/org/bukkit/fillr/Fillr.java b/paper-api/src/main/java/org/bukkit/fillr/Fillr.java new file mode 100644 index 0000000000..c2928a47e5 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/fillr/Fillr.java @@ -0,0 +1,67 @@ +package org.bukkit.fillr; +import org.bukkit.*; + +import java.util.logging.Logger; + +public class Fillr { + private Logger log; + private String name = "Fillr"; + public static String version = "1.0"; + public Server server; + private static Fillr singleton; + public static String directory = "plugins"; + + private Fillr(Server server) { + this.server = server; + } + + public Fillr createInstance(Server server) { + singleton = new Fillr(server); + return singleton; + } + + public static Fillr getInstance() { + return singleton; + } + + //TODO Get command hooks in somehow... + /*public class UpdatrListener extends PluginListener { + + public boolean onCommand(Player player, String[] split) { + if (split[0].equalsIgnoreCase("/check") + && player.canUseCommand("/check")) { + new Checker().check(player); + return true; + } + if (split[0].equalsIgnoreCase("/updateAll") + && player.canUseCommand("/updateAll")) { + new Updater().updateAll(player); + return true; + } + if (split[0].equalsIgnoreCase("/update") + && player.canUseCommand("/update")) { + if (split.length == 1) { + player.sendMessage(premessage + "Usage is /update "); + } else { + new Updater().update(split[1], player); + } + return true; + } + if (split[0].equalsIgnoreCase("/download") + && player.canUseCommand("/download")) { + if (split.length == 1) { + player.sendMessage(premessage + "Usage is /download "); + } else { + try { + new Downloader().downloadFile(split[1], player); + } catch(Exception e) { + player.sendMessage("There was an error downloading "+ split[1]); + } + } + return true; + } + + return false; + } + }*/ +} diff --git a/paper-api/src/main/java/org/bukkit/fillr/PluginFilter.java b/paper-api/src/main/java/org/bukkit/fillr/PluginFilter.java new file mode 100644 index 0000000000..f9a345f948 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/fillr/PluginFilter.java @@ -0,0 +1,17 @@ +package org.bukkit.fillr; +import java.io.File; +import java.io.FilenameFilter; + +/** + * Used to filter out non-updatr files + */ +public class PluginFilter implements FilenameFilter { + + public boolean accept(File file, String name) { + if(name.endsWith(".jar")) + return true; + else + return false; + } + +} diff --git a/paper-api/src/main/java/org/bukkit/fillr/README b/paper-api/src/main/java/org/bukkit/fillr/README new file mode 100644 index 0000000000..3d32f7327a --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/fillr/README @@ -0,0 +1,3 @@ +Things still needed for Fillr: + - Command hooks. Should be core or should act as a plugin? (See Fillr.java) + - hRepo info grabbing (see FillReader.java) \ No newline at end of file diff --git a/paper-api/src/main/java/org/bukkit/fillr/Updater.java b/paper-api/src/main/java/org/bukkit/fillr/Updater.java new file mode 100644 index 0000000000..8af2148116 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/fillr/Updater.java @@ -0,0 +1,102 @@ +package org.bukkit.fillr; + +import org.bukkit.*; +import org.bukkit.plugin.*; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.jar.*; + +public class Updater { + public static String directory = Fillr.directory; + + /** + * Checks and updates the plugins with updatr files + * + * @param player + * The player to send info to + */ + public void updateAll(Player player) { + File folder = new File(directory); + File[] files = folder.listFiles(new PluginFilter()); + if (files.length == 0) { + player.sendMessage("No plugins to update."); + } else { + player.sendMessage("Updating " + + files.length + " plugins:"); + for (File file : files) { + PluginDescriptionFile pdfFile = Checker.getPDF(file); + if(pdfFile == null) continue; + FillReader reader = Checker.needsUpdate(pdfFile); + if (reader != null) + update(reader, player); + } + } + } + + /** + * Checks if a given plugin needs an update, if it does, it updates it + * + * @param string + * The name of the plugin + * @param player + * The player to send info to + */ + public void update(String string, Player player) { + //TODO so much .jars + File file = new File(directory, string + ".jar"); + if (file.exists()) { + PluginDescriptionFile pdfFile = Checker.getPDF(file); + FillReader reader = Checker.needsUpdate(pdfFile); + if (reader != null) { + update(reader, player); + } else { + player.sendMessage(string + " is up to date"); + } + } else { + player.sendMessage("Can't find " + string); + } + } + + /** + * Downloads the plugin specified by the URLReader + * + * @param update + * The URLReader representing the online .updatr file + */ + public void update(FillReader update, Player player) { + disablePlugin(update); + player.sendMessage("Disabling " + update.getName() + " for update"); + player.sendMessage("Downloading " + update.getName() + " " + + update.getCurrVersion()); + try { + Downloader.downloadJar(update.getFile()); + if (update.getNotes() != null && !update.getNotes().equals("")) { + player.sendMessage("Notes: " + update.getNotes()); + } + player.sendMessage("Finished Download!"); + enablePlugin(update); + player.sendMessage("Loading " + update.getName()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void enablePlugin(FillReader update) { + final String name = update.getName(); + //TODO again with the implicit jar support... + File plugin = new File(directory, name + ".jar"); + try { + Fillr.getInstance().server.getPluginManager().loadPlugin(plugin); + } catch (InvalidPluginException e) { + e.printStackTrace(); + } + } + + private void disablePlugin(FillReader update) { + String name = update.getName(); + Plugin plugin = Fillr.getInstance().server.getPluginManager().getPlugin(name); + Fillr.getInstance().server.getPluginManager().disablePlugin(plugin); + } +} \ No newline at end of file diff --git a/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java b/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java index 78f54281ac..ed1ca0c934 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java +++ b/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java @@ -16,6 +16,7 @@ public final class PluginDescriptionFile { private static final Yaml yaml = new Yaml(new SafeConstructor()); private String name = null; private String main = null; + private String version = null; @SuppressWarnings("unchecked") public PluginDescriptionFile(final InputStream stream) throws InvalidDescriptionException { @@ -41,8 +42,9 @@ public final class PluginDescriptionFile { * @param pluginName Name of this plugin * @param mainClass Full location of the main class of this plugin */ - public PluginDescriptionFile(final String pluginName, final String mainClass) { + public PluginDescriptionFile(final String pluginName, final String pluginVersion, final String mainClass) { name = pluginName; + version = pluginVersion; main = mainClass; } @@ -63,6 +65,15 @@ public final class PluginDescriptionFile { public String getName() { return name; } + + /** + * Returns the version of a plugin + * + * @return String name + */ + public String getVersion() { + return version; + } /** * Returns the main class for a plugin @@ -76,14 +87,14 @@ public final class PluginDescriptionFile { private void loadMap(Map map) throws ClassCastException { name = (String)map.get("name"); main = (String)map.get("main"); + version = (String)map.get("version"); } private Map saveMap() { Map map = new HashMap(); - map.put("name", name); map.put("main", main); - + map.put("version", version); return map; } }