geforkt von Mirrors/Paper
#474: Add ability to set other plugin names as provided API so others can still depend on it
By: Phoenix616 <mail@moep.tv>
Dieser Commit ist enthalten in:
Ursprung
b35aa20f22
Commit
aec6ad036b
@ -45,6 +45,10 @@ public class PluginsCommand extends BukkitCommand {
|
||||
|
||||
pluginList.append(plugin.isEnabled() ? ChatColor.GREEN : ChatColor.RED);
|
||||
pluginList.append(plugin.getDescription().getName());
|
||||
|
||||
if (plugin.getDescription().getProvides().size() > 0) {
|
||||
pluginList.append(" (").append(String.join(", ", plugin.getDescription().getProvides())).append(")");
|
||||
}
|
||||
}
|
||||
|
||||
return "(" + plugins.length + "): " + pluginList.toString();
|
||||
|
@ -64,6 +64,10 @@ import org.yaml.snakeyaml.nodes.Tag;
|
||||
* <td>{@link #getName()}</td>
|
||||
* <td>The unique name of plugin</td>
|
||||
* </tr><tr>
|
||||
* <td><code>provides</code></td>
|
||||
* <td>{@link #getProvides()}</td>
|
||||
* <td>The plugin APIs which this plugin provides</td>
|
||||
* </tr><tr>
|
||||
* <td><code>version</code></td>
|
||||
* <td>{@link #getVersion()}</td>
|
||||
* <td>A plugin revision identifier</td>
|
||||
@ -130,6 +134,7 @@ import org.yaml.snakeyaml.nodes.Tag;
|
||||
* <p>
|
||||
* A plugin.yml example:<blockquote><pre>
|
||||
*name: Inferno
|
||||
*provides: [Hell]
|
||||
*version: 1.4.1
|
||||
*description: This plugin is so 31337. You can set yourself on fire.
|
||||
*# We could place every author in the authors list, but chose not to for illustrative purposes
|
||||
@ -218,6 +223,7 @@ public final class PluginDescriptionFile {
|
||||
};
|
||||
String rawName = null;
|
||||
private String name = null;
|
||||
private List<String> provides = ImmutableList.of();
|
||||
private String main = null;
|
||||
private String classLoaderOf = null;
|
||||
private List<String> depend = ImmutableList.of();
|
||||
@ -299,6 +305,37 @@ public final class PluginDescriptionFile {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the list of other plugin APIs which this plugin provides.
|
||||
* These are usable for other plugins to depend on.
|
||||
* <ul>
|
||||
* <li>Must consist of all alphanumeric characters, underscores, hyphon,
|
||||
* and period (a-z,A-Z,0-9, _.-). Any other character will cause the
|
||||
* plugin.yml to fail loading.
|
||||
* <li>A different plugin providing the same one or using it as their name
|
||||
* will not result in the plugin to fail loading.
|
||||
* <li>Case sensitive.
|
||||
* <li>An entry of this list can be referenced in {@link #getDepend()},
|
||||
* {@link #getSoftDepend()}, and {@link #getLoadBefore()}.
|
||||
* <li><code>provides</code> must be in <a
|
||||
* href="http://en.wikipedia.org/wiki/YAML#Lists">YAML list
|
||||
* format</a>.
|
||||
* </ul>
|
||||
* <p>
|
||||
* In the plugin.yml, this entry is named <code>provides</code>.
|
||||
* <p>
|
||||
* Example:
|
||||
* <blockquote><pre>provides:
|
||||
*- OtherPluginName
|
||||
*- OldPluginName</pre></blockquote>
|
||||
*
|
||||
* @return immutable list of the plugin APIs which this plugin provides
|
||||
*/
|
||||
@NotNull
|
||||
public List<String> getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the version of the plugin.
|
||||
* <ul>
|
||||
@ -459,7 +496,7 @@ public final class PluginDescriptionFile {
|
||||
* plugin in the <a
|
||||
* href=https://en.wikipedia.org/wiki/Circular_dependency>network</a>,
|
||||
* all plugins in that network will fail.
|
||||
* <li><code>depend</code> must be in must be in <a
|
||||
* <li><code>depend</code> must be in <a
|
||||
* href="http://en.wikipedia.org/wiki/YAML#Lists">YAML list
|
||||
* format</a>.
|
||||
* </ul>
|
||||
@ -923,6 +960,8 @@ public final class PluginDescriptionFile {
|
||||
throw new InvalidDescriptionException(ex, "name is of wrong type");
|
||||
}
|
||||
|
||||
provides = makePluginNameList(map, "provides");
|
||||
|
||||
try {
|
||||
version = map.get("version").toString();
|
||||
} catch (NullPointerException ex) {
|
||||
@ -1080,6 +1119,9 @@ public final class PluginDescriptionFile {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
|
||||
map.put("name", name);
|
||||
if (provides != null) {
|
||||
map.put("provides", provides);
|
||||
}
|
||||
map.put("main", main);
|
||||
map.put("version", version);
|
||||
map.put("order", order.toString());
|
||||
|
@ -123,6 +123,7 @@ public final class SimplePluginManager implements PluginManager {
|
||||
|
||||
Map<String, File> plugins = new HashMap<String, File>();
|
||||
Set<String> loadedPlugins = new HashSet<String>();
|
||||
Map<String, String> pluginsProvided = new HashMap<>();
|
||||
Map<String, Collection<String>> dependencies = new HashMap<String, Collection<String>>();
|
||||
Map<String, Collection<String>> softDependencies = new HashMap<String, Collection<String>>();
|
||||
|
||||
@ -165,6 +166,38 @@ public final class SimplePluginManager implements PluginManager {
|
||||
));
|
||||
}
|
||||
|
||||
String removedProvided = pluginsProvided.remove(description.getName());
|
||||
if (removedProvided != null) {
|
||||
server.getLogger().warning(String.format(
|
||||
"Ambiguous plugin name `%s'. It is also provided by `%s'",
|
||||
description.getName(),
|
||||
removedProvided
|
||||
));
|
||||
}
|
||||
|
||||
for (String provided : description.getProvides()) {
|
||||
File pluginFile = plugins.get(provided);
|
||||
if (pluginFile != null) {
|
||||
server.getLogger().warning(String.format(
|
||||
"`%s provides `%s' while this is also the name of `%s' in `%s'",
|
||||
file.getPath(),
|
||||
provided,
|
||||
pluginFile.getPath(),
|
||||
directory.getPath()
|
||||
));
|
||||
} else {
|
||||
String replacedPlugin = pluginsProvided.put(provided, description.getName());
|
||||
if (replacedPlugin != null) {
|
||||
server.getLogger().warning(String.format(
|
||||
"`%s' is provided by both `%s' and `%s'",
|
||||
provided,
|
||||
description.getName(),
|
||||
replacedPlugin
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collection<String> softDependencySet = description.getSoftDepend();
|
||||
if (softDependencySet != null && !softDependencySet.isEmpty()) {
|
||||
if (softDependencies.containsKey(description.getName())) {
|
||||
@ -224,7 +257,7 @@ public final class SimplePluginManager implements PluginManager {
|
||||
dependencyIterator.remove();
|
||||
|
||||
// We have a dependency not found
|
||||
} else if (!plugins.containsKey(dependency)) {
|
||||
} else if (!plugins.containsKey(dependency) && !pluginsProvided.containsKey(dependency)) {
|
||||
missingDependency = false;
|
||||
pluginIterator.remove();
|
||||
softDependencies.remove(plugin);
|
||||
@ -249,7 +282,7 @@ public final class SimplePluginManager implements PluginManager {
|
||||
String softDependency = softDependencyIterator.next();
|
||||
|
||||
// Soft depend is no longer around
|
||||
if (!plugins.containsKey(softDependency)) {
|
||||
if (!plugins.containsKey(softDependency) && !pluginsProvided.containsKey(softDependency)) {
|
||||
softDependencyIterator.remove();
|
||||
}
|
||||
}
|
||||
@ -265,8 +298,14 @@ public final class SimplePluginManager implements PluginManager {
|
||||
missingDependency = false;
|
||||
|
||||
try {
|
||||
result.add(loadPlugin(file));
|
||||
loadedPlugins.add(plugin);
|
||||
Plugin loadedPlugin = loadPlugin(file);
|
||||
if (loadedPlugin != null) {
|
||||
result.add(loadedPlugin);
|
||||
loadedPlugins.add(loadedPlugin.getName());
|
||||
loadedPlugins.addAll(loadedPlugin.getDescription().getProvides());
|
||||
} else {
|
||||
server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'");
|
||||
}
|
||||
continue;
|
||||
} catch (InvalidPluginException ex) {
|
||||
server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'", ex);
|
||||
@ -290,8 +329,14 @@ public final class SimplePluginManager implements PluginManager {
|
||||
pluginIterator.remove();
|
||||
|
||||
try {
|
||||
result.add(loadPlugin(file));
|
||||
loadedPlugins.add(plugin);
|
||||
Plugin loadedPlugin = loadPlugin(file);
|
||||
if (loadedPlugin != null) {
|
||||
result.add(loadedPlugin);
|
||||
loadedPlugins.add(loadedPlugin.getName());
|
||||
loadedPlugins.addAll(loadedPlugin.getDescription().getProvides());
|
||||
} else {
|
||||
server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'");
|
||||
}
|
||||
break;
|
||||
} catch (InvalidPluginException ex) {
|
||||
server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'", ex);
|
||||
@ -352,6 +397,9 @@ public final class SimplePluginManager implements PluginManager {
|
||||
if (result != null) {
|
||||
plugins.add(result);
|
||||
lookupNames.put(result.getDescription().getName(), result);
|
||||
for (String provided : result.getDescription().getProvides()) {
|
||||
lookupNames.putIfAbsent(provided, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -796,7 +844,17 @@ public final class SimplePluginManager implements PluginManager {
|
||||
Preconditions.checkArgument(plugin != null, "plugin");
|
||||
Preconditions.checkArgument(depend != null, "depend");
|
||||
|
||||
return dependencyGraph.nodes().contains(plugin.getName()) && Graphs.reachableNodes(dependencyGraph, plugin.getName()).contains(depend.getName());
|
||||
if (dependencyGraph.nodes().contains(plugin.getName())) {
|
||||
if (Graphs.reachableNodes(dependencyGraph, plugin.getName()).contains(depend.getName())) {
|
||||
return true;
|
||||
}
|
||||
for (String provided : depend.getProvides()) {
|
||||
if (Graphs.reachableNodes(dependencyGraph, plugin.getName()).contains(provided)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren