From 5402bd2cb1b9b0962910f683d69740d019a4c529 Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 10 Jan 2013 20:41:05 +1100 Subject: [PATCH] Add plugin loading. --- .../java/net/md_5/bungee/api/ProxyServer.java | 27 ++++++++---- .../net/md_5/bungee/api/plugin/Plugin.java | 21 ++++++---- .../bungee/api/plugin/PluginDescription.java | 1 - .../md_5/bungee/api/plugin/PluginManager.java | 41 +++++++++++++++++-- 4 files changed, 69 insertions(+), 21 deletions(-) diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyServer.java b/api/src/main/java/net/md_5/bungee/api/ProxyServer.java index 19f08dcc..f5a71978 100644 --- a/api/src/main/java/net/md_5/bungee/api/ProxyServer.java +++ b/api/src/main/java/net/md_5/bungee/api/ProxyServer.java @@ -5,12 +5,21 @@ import com.google.common.base.Preconditions; import java.util.Collection; import java.util.logging.Logger; import lombok.Getter; +import org.yaml.snakeyaml.Yaml; public abstract class ProxyServer { @Getter private static ProxyServer instance; + private ThreadLocal yaml = new ThreadLocal() + { + @Override + protected Yaml initialValue() + { + return new Yaml(); + } + }; /** * Sets the proxy instance. This method may only be called once per an @@ -25,6 +34,16 @@ public abstract class ProxyServer ProxyServer.instance = instance; } + /** + * Gets a reusable, thread safe {@link Yaml} instance. + * + * @return an {@link Yaml} instance + */ + public Yaml getYaml() + { + return yaml.get(); + } + /** * Gets the name of the currently running proxy software. * @@ -39,14 +58,6 @@ public abstract class ProxyServer */ public abstract String getVersion(); - /** - * The current number of players connected to this proxy. This total should - * include virtual players that may be connected from other servers. - * - * @return current player count - */ - public abstract int playerCount(); - /** * Gets the main logger which can be used as a suitable replacement for * {@link System#out} and {@link System#err}. diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/Plugin.java b/api/src/main/java/net/md_5/bungee/api/plugin/Plugin.java index a304b273..5d50ef98 100644 --- a/api/src/main/java/net/md_5/bungee/api/plugin/Plugin.java +++ b/api/src/main/java/net/md_5/bungee/api/plugin/Plugin.java @@ -1,7 +1,6 @@ package net.md_5.bungee.api.plugin; -import java.util.logging.Logger; -import net.md_5.bungee.api.ProxyServer; +import lombok.Getter; /** * Represents any Plugin that may be loaded at runtime to enhance existing @@ -10,12 +9,8 @@ import net.md_5.bungee.api.ProxyServer; public class Plugin { - /** - * Called when this plugin is loaded. - */ - public void onLoad() - { - } + @Getter + private PluginDescription description; /** * Called when this plugin is enabled. @@ -30,4 +25,14 @@ public class Plugin public void onDisable() { } + + /** + * Called by the loader to initialize the fields in this plugin. + * + * @param description the description that describes this plugin + */ + final void init(PluginDescription description) + { + this.description = description; + } } diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/PluginDescription.java b/api/src/main/java/net/md_5/bungee/api/plugin/PluginDescription.java index d9d9c6a0..6f124efa 100644 --- a/api/src/main/java/net/md_5/bungee/api/plugin/PluginDescription.java +++ b/api/src/main/java/net/md_5/bungee/api/plugin/PluginDescription.java @@ -10,5 +10,4 @@ public class PluginDescription private final String main; private final String version; private final String author; - private final String id; } diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java index 8c0e24dc..72f58ff3 100644 --- a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java +++ b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java @@ -4,9 +4,16 @@ import com.google.common.base.Preconditions; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import java.io.File; +import java.io.InputStream; +import java.net.URL; +import java.net.URLClassLoader; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.logging.Level; +import net.md_5.bungee.api.ProxyServer; /** * Class to manage bridging between plugin duties and implementation duties, for @@ -40,15 +47,35 @@ public class PluginManager } /** - * Load a plugin from the specified file. This file must be in jar or zip - * format. + * Load a plugin from the specified file. This file must be in jar format. * * @param file the file to load from + * @throws Exception Any exceptions encountered when loading a plugin from + * this file. */ - public void load(File file) + public void load(File file) throws Exception { Preconditions.checkNotNull(file, "file"); Preconditions.checkArgument(file.isFile(), "Must load from file"); + + try (JarFile jar = new JarFile(file)) + { + JarEntry pdf = jar.getJarEntry("plugin.yml"); + try (InputStream in = jar.getInputStream(pdf)) + { + PluginDescription desc = ProxyServer.getInstance().getYaml().loadAs(in, PluginDescription.class); + URLClassLoader loader = new URLClassLoader(new URL[] + { + file.toURI().toURL() + }); + Class main = loader.loadClass(desc.getMain()); + Plugin plugin = (Plugin) main.getDeclaredConstructor().newInstance(); + + plugin.init(desc); + plugins.put(pdf.getName(), plugin); + plugin.onEnable(); + } + } } /** @@ -65,7 +92,13 @@ public class PluginManager { if (file.getName().endsWith(".jar")) { - load(file); + try + { + load(file); + } catch (Exception ex) + { + ProxyServer.getInstance().getLogger().log(Level.WARNING, "Could not load plugin from file " + file, ex); + } } } }