mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-03 23:07:40 +01:00
Adds basic plugin dependencies, courtesy of Raphfrk
By: Dinnerbone <dinnerbone@dinnerbone.com>
This commit is contained in:
parent
f370268047
commit
6dc6946312
@ -8,6 +8,7 @@ import org.bukkit.*;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.InvalidDescriptionException;
|
||||
import org.bukkit.plugin.InvalidPluginException;
|
||||
import org.bukkit.plugin.UnknownDependencyException;
|
||||
|
||||
public class Getter {
|
||||
private Server server;
|
||||
@ -40,6 +41,8 @@ public class Getter {
|
||||
File plugin = new File(DIRECTORY, name + ".jar");
|
||||
try {
|
||||
server.getPluginManager().loadPlugin(plugin);
|
||||
} catch (UnknownDependencyException ex) {
|
||||
server.getLogger().log(Level.SEVERE, null, ex);
|
||||
} catch (InvalidPluginException ex) {
|
||||
server.getLogger().log(Level.SEVERE, null, ex);
|
||||
} catch (InvalidDescriptionException ex) {
|
||||
|
@ -98,6 +98,8 @@ public class Updater {
|
||||
File plugin = new File(DIRECTORY, name + ".jar");
|
||||
try {
|
||||
server.getPluginManager().loadPlugin(plugin);
|
||||
} catch (UnknownDependencyException ex) {
|
||||
server.getLogger().log(Level.SEVERE, null, ex);
|
||||
} catch (InvalidPluginException ex) {
|
||||
server.getLogger().log(Level.SEVERE, null, ex);
|
||||
} catch (InvalidDescriptionException ex) {
|
||||
|
@ -7,6 +7,7 @@ import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
@ -18,6 +19,7 @@ public final class PluginDescriptionFile {
|
||||
private static final Yaml yaml = new Yaml(new SafeConstructor());
|
||||
private String name = null;
|
||||
private String main = null;
|
||||
private ArrayList<String> depend = null;
|
||||
private String version = null;
|
||||
private Object commands = null;
|
||||
private String description = null;
|
||||
@ -99,6 +101,10 @@ public final class PluginDescriptionFile {
|
||||
return commands;
|
||||
}
|
||||
|
||||
public Object getDepend() {
|
||||
return depend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the description of this plugin
|
||||
*
|
||||
@ -149,6 +155,14 @@ public final class PluginDescriptionFile {
|
||||
}
|
||||
}
|
||||
|
||||
if (map.containsKey("depend")) {
|
||||
try {
|
||||
depend = (ArrayList<String>)map.get("depend");
|
||||
} catch (ClassCastException ex) {
|
||||
throw new InvalidDescriptionException(ex, "depend is of wrong type");
|
||||
}
|
||||
}
|
||||
|
||||
if (map.containsKey("website")) {
|
||||
try {
|
||||
website = (String)map.get("website");
|
||||
@ -191,6 +205,7 @@ public final class PluginDescriptionFile {
|
||||
map.put("version", version);
|
||||
|
||||
if (commands != null) map.put("command", commands);
|
||||
if (depend != null) map.put("depend", depend);
|
||||
if (website != null) map.put("website", website);
|
||||
if (description != null) map.put("description", description);
|
||||
|
||||
|
@ -20,7 +20,7 @@ public interface PluginLoader {
|
||||
* unsuccessful
|
||||
* @throws InvalidPluginException Thrown when the specified file is not a plugin
|
||||
*/
|
||||
public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException;
|
||||
public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException;
|
||||
|
||||
/**
|
||||
* Returns a list of all filename filters expected by this PluginLoader
|
||||
|
@ -65,7 +65,7 @@ public interface PluginManager {
|
||||
* @throws InvalidPluginException Thrown when the specified file is not a valid plugin
|
||||
* @throws InvalidDescriptionException Thrown when the specified file contains an invalid description
|
||||
*/
|
||||
public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException;
|
||||
public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException;
|
||||
|
||||
/**
|
||||
* Loads the plugins contained within the specified directory
|
||||
|
@ -12,6 +12,9 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Iterator;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
@ -88,19 +91,45 @@ public final class SimplePluginManager implements PluginManager {
|
||||
List<Plugin> result = new ArrayList<Plugin>();
|
||||
File[] files = directory.listFiles();
|
||||
|
||||
for (File file : files) {
|
||||
Plugin plugin = null;
|
||||
boolean allFailed = false;
|
||||
boolean finalPass = false;
|
||||
|
||||
try {
|
||||
plugin = loadPlugin(file);
|
||||
} catch (InvalidPluginException ex) {
|
||||
server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
|
||||
} catch (InvalidDescriptionException ex) {
|
||||
server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
|
||||
LinkedList<File> filesList = new LinkedList(Arrays.asList(files));
|
||||
|
||||
while(!allFailed || finalPass) {
|
||||
allFailed = true;
|
||||
Iterator<File> itr = filesList.iterator();
|
||||
while(itr.hasNext()) {
|
||||
File file = itr.next();
|
||||
Plugin plugin = null;
|
||||
|
||||
try {
|
||||
plugin = loadPlugin(file);
|
||||
itr.remove();
|
||||
} catch (UnknownDependencyException ex) {
|
||||
if(finalPass) {
|
||||
server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
|
||||
itr.remove();
|
||||
} else {
|
||||
plugin = null;
|
||||
}
|
||||
} catch (InvalidPluginException ex) {
|
||||
server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
|
||||
itr.remove();
|
||||
} catch (InvalidDescriptionException ex) {
|
||||
server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
|
||||
itr.remove();
|
||||
}
|
||||
|
||||
if (plugin != null) {
|
||||
result.add(plugin);
|
||||
allFailed = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin != null) {
|
||||
result.add(plugin);
|
||||
if(finalPass) {
|
||||
break;
|
||||
} else if(allFailed) {
|
||||
finalPass = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,7 +146,7 @@ public final class SimplePluginManager implements PluginManager {
|
||||
* @throws InvalidPluginException Thrown when the specified file is not a valid plugin
|
||||
* @throws InvalidDescriptionException Thrown when the specified file contains an invalid description
|
||||
*/
|
||||
public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException {
|
||||
public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
|
||||
Set<Pattern> filters = fileAssociations.keySet();
|
||||
Plugin result = null;
|
||||
|
||||
|
@ -0,0 +1,63 @@
|
||||
|
||||
package org.bukkit.plugin;
|
||||
|
||||
/**
|
||||
* Thrown when attempting to load an invalid Plugin file
|
||||
*/
|
||||
public class UnknownDependencyException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 5721389371901775894L;
|
||||
private final Throwable cause;
|
||||
private final String message;
|
||||
|
||||
/**
|
||||
* Constructs a new UnknownDependencyException based on the given Exception
|
||||
*
|
||||
* @param throwable Exception that triggered this Exception
|
||||
*/
|
||||
public UnknownDependencyException(Throwable throwable) {
|
||||
this(throwable, "Unknown dependency");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new UnknownDependencyException with the given message
|
||||
*
|
||||
* @param message Brief message explaining the cause of the exception
|
||||
*/
|
||||
public UnknownDependencyException(final String message) {
|
||||
this(null, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new UnknownDependencyException based on the given Exception
|
||||
*
|
||||
* @param message Brief message explaining the cause of the exception
|
||||
* @param throwable Exception that triggered this Exception
|
||||
*/
|
||||
public UnknownDependencyException(final Throwable throwable, final String message) {
|
||||
this.cause = null;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new UnknownDependencyException
|
||||
*/
|
||||
public UnknownDependencyException() {
|
||||
this(null, "Unknown dependency");
|
||||
}
|
||||
|
||||
/**
|
||||
* If applicable, returns the Exception that triggered this Exception
|
||||
*
|
||||
* @return Inner exception, or null if one does not exist
|
||||
*/
|
||||
@Override
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
@ -9,6 +9,9 @@ import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.regex.Pattern;
|
||||
@ -36,12 +39,13 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
Pattern.compile("\\.jar$"),
|
||||
};
|
||||
private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
|
||||
private final Map<String, File> files = new HashMap<String, File>();
|
||||
|
||||
public JavaPluginLoader(Server instance) {
|
||||
server = instance;
|
||||
}
|
||||
|
||||
public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException {
|
||||
public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
|
||||
JavaPlugin result = null;
|
||||
PluginDescriptionFile description = null;
|
||||
|
||||
@ -67,8 +71,37 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
|
||||
File dataFolder = getDataFolder(file);
|
||||
|
||||
ArrayList<String> depend;
|
||||
try {
|
||||
ClassLoader loader = new PluginClassLoader(this, new URL[]{file.toURI().toURL()}, getClass().getClassLoader());
|
||||
depend = (ArrayList)description.getDepend();
|
||||
if(depend == null) {
|
||||
depend = new ArrayList<String>();
|
||||
}
|
||||
} catch (ClassCastException ex) {
|
||||
throw new InvalidPluginException(ex);
|
||||
}
|
||||
|
||||
ArrayList<File> dependFiles = new ArrayList<File>();
|
||||
|
||||
for(String pluginName : depend) {
|
||||
if(files == null) {
|
||||
throw new UnknownDependencyException(pluginName);
|
||||
}
|
||||
File current = files.get(pluginName);
|
||||
if(current == null) {
|
||||
throw new UnknownDependencyException(pluginName);
|
||||
}
|
||||
dependFiles.add(current);
|
||||
}
|
||||
|
||||
try {
|
||||
URL[] urls = new URL[dependFiles.size() + 1];
|
||||
urls[0] = file.toURI().toURL();
|
||||
int cnt = 1;
|
||||
for(File f : dependFiles) {
|
||||
urls[cnt++] = f.toURI().toURL();
|
||||
}
|
||||
ClassLoader loader = new PluginClassLoader(this, urls, getClass().getClassLoader());
|
||||
Class<?> jarClass = Class.forName(description.getMain(), true, loader);
|
||||
Class<? extends JavaPlugin> plugin = jarClass.asSubclass(JavaPlugin.class);
|
||||
|
||||
@ -80,6 +113,8 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
throw new InvalidPluginException(ex);
|
||||
}
|
||||
|
||||
files.put(description.getName(), file);
|
||||
|
||||
return (Plugin)result;
|
||||
}
|
||||
|
||||
@ -112,7 +147,9 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
}
|
||||
|
||||
public void setClass(final String name, final Class<?> clazz) {
|
||||
classes.put(name, clazz);
|
||||
if(!classes.containsKey(name)) {
|
||||
classes.put(name, clazz);
|
||||
}
|
||||
}
|
||||
|
||||
public EventExecutor createExecutor( Event.Type type, Listener listener ) {
|
||||
@ -429,6 +466,8 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
|
||||
server.getPluginManager().callEvent(new PluginEvent(Event.Type.PLUGIN_DISABLE, plugin));
|
||||
|
||||
files.remove(jPlugin.getDescription().getName());
|
||||
|
||||
if (cloader instanceof PluginClassLoader) {
|
||||
PluginClassLoader loader = (PluginClassLoader)cloader;
|
||||
Set<String> names = loader.getClasses();
|
||||
|
@ -24,17 +24,25 @@ public class PluginClassLoader extends URLClassLoader {
|
||||
Class<?> result = classes.get(name);
|
||||
|
||||
if (result == null) {
|
||||
result = loader.getClassByName(name);
|
||||
ClassNotFoundException ex = null;
|
||||
|
||||
if (result == null) {
|
||||
try {
|
||||
result = super.findClass(name);
|
||||
|
||||
if (result != null) {
|
||||
loader.setClass(name, result);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
ex = e;
|
||||
}
|
||||
|
||||
classes.put(name, result);
|
||||
if (result != null) {
|
||||
loader.setClass(name, result);
|
||||
} else {
|
||||
result = loader.getClassByName(name);
|
||||
}
|
||||
|
||||
if (result != null ) {
|
||||
classes.put(name, result);
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
Loading…
Reference in New Issue
Block a user