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.isEnabled() ? ChatColor.GREEN : ChatColor.RED);
|
||||||
pluginList.append(plugin.getDescription().getName());
|
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();
|
return "(" + plugins.length + "): " + pluginList.toString();
|
||||||
|
@ -64,6 +64,10 @@ import org.yaml.snakeyaml.nodes.Tag;
|
|||||||
* <td>{@link #getName()}</td>
|
* <td>{@link #getName()}</td>
|
||||||
* <td>The unique name of plugin</td>
|
* <td>The unique name of plugin</td>
|
||||||
* </tr><tr>
|
* </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><code>version</code></td>
|
||||||
* <td>{@link #getVersion()}</td>
|
* <td>{@link #getVersion()}</td>
|
||||||
* <td>A plugin revision identifier</td>
|
* <td>A plugin revision identifier</td>
|
||||||
@ -130,6 +134,7 @@ import org.yaml.snakeyaml.nodes.Tag;
|
|||||||
* <p>
|
* <p>
|
||||||
* A plugin.yml example:<blockquote><pre>
|
* A plugin.yml example:<blockquote><pre>
|
||||||
*name: Inferno
|
*name: Inferno
|
||||||
|
*provides: [Hell]
|
||||||
*version: 1.4.1
|
*version: 1.4.1
|
||||||
*description: This plugin is so 31337. You can set yourself on fire.
|
*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
|
*# 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;
|
String rawName = null;
|
||||||
private String name = null;
|
private String name = null;
|
||||||
|
private List<String> provides = ImmutableList.of();
|
||||||
private String main = null;
|
private String main = null;
|
||||||
private String classLoaderOf = null;
|
private String classLoaderOf = null;
|
||||||
private List<String> depend = ImmutableList.of();
|
private List<String> depend = ImmutableList.of();
|
||||||
@ -299,6 +305,37 @@ public final class PluginDescriptionFile {
|
|||||||
return name;
|
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.
|
* Gives the version of the plugin.
|
||||||
* <ul>
|
* <ul>
|
||||||
@ -459,7 +496,7 @@ public final class PluginDescriptionFile {
|
|||||||
* plugin in the <a
|
* plugin in the <a
|
||||||
* href=https://en.wikipedia.org/wiki/Circular_dependency>network</a>,
|
* href=https://en.wikipedia.org/wiki/Circular_dependency>network</a>,
|
||||||
* all plugins in that network will fail.
|
* 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
|
* href="http://en.wikipedia.org/wiki/YAML#Lists">YAML list
|
||||||
* format</a>.
|
* format</a>.
|
||||||
* </ul>
|
* </ul>
|
||||||
@ -923,6 +960,8 @@ public final class PluginDescriptionFile {
|
|||||||
throw new InvalidDescriptionException(ex, "name is of wrong type");
|
throw new InvalidDescriptionException(ex, "name is of wrong type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
provides = makePluginNameList(map, "provides");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
version = map.get("version").toString();
|
version = map.get("version").toString();
|
||||||
} catch (NullPointerException ex) {
|
} catch (NullPointerException ex) {
|
||||||
@ -1080,6 +1119,9 @@ public final class PluginDescriptionFile {
|
|||||||
Map<String, Object> map = new HashMap<String, Object>();
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
|
|
||||||
map.put("name", name);
|
map.put("name", name);
|
||||||
|
if (provides != null) {
|
||||||
|
map.put("provides", provides);
|
||||||
|
}
|
||||||
map.put("main", main);
|
map.put("main", main);
|
||||||
map.put("version", version);
|
map.put("version", version);
|
||||||
map.put("order", order.toString());
|
map.put("order", order.toString());
|
||||||
|
@ -123,6 +123,7 @@ public final class SimplePluginManager implements PluginManager {
|
|||||||
|
|
||||||
Map<String, File> plugins = new HashMap<String, File>();
|
Map<String, File> plugins = new HashMap<String, File>();
|
||||||
Set<String> loadedPlugins = new HashSet<String>();
|
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>> dependencies = new HashMap<String, Collection<String>>();
|
||||||
Map<String, Collection<String>> softDependencies = 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();
|
Collection<String> softDependencySet = description.getSoftDepend();
|
||||||
if (softDependencySet != null && !softDependencySet.isEmpty()) {
|
if (softDependencySet != null && !softDependencySet.isEmpty()) {
|
||||||
if (softDependencies.containsKey(description.getName())) {
|
if (softDependencies.containsKey(description.getName())) {
|
||||||
@ -224,7 +257,7 @@ public final class SimplePluginManager implements PluginManager {
|
|||||||
dependencyIterator.remove();
|
dependencyIterator.remove();
|
||||||
|
|
||||||
// We have a dependency not found
|
// We have a dependency not found
|
||||||
} else if (!plugins.containsKey(dependency)) {
|
} else if (!plugins.containsKey(dependency) && !pluginsProvided.containsKey(dependency)) {
|
||||||
missingDependency = false;
|
missingDependency = false;
|
||||||
pluginIterator.remove();
|
pluginIterator.remove();
|
||||||
softDependencies.remove(plugin);
|
softDependencies.remove(plugin);
|
||||||
@ -249,7 +282,7 @@ public final class SimplePluginManager implements PluginManager {
|
|||||||
String softDependency = softDependencyIterator.next();
|
String softDependency = softDependencyIterator.next();
|
||||||
|
|
||||||
// Soft depend is no longer around
|
// Soft depend is no longer around
|
||||||
if (!plugins.containsKey(softDependency)) {
|
if (!plugins.containsKey(softDependency) && !pluginsProvided.containsKey(softDependency)) {
|
||||||
softDependencyIterator.remove();
|
softDependencyIterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,8 +298,14 @@ public final class SimplePluginManager implements PluginManager {
|
|||||||
missingDependency = false;
|
missingDependency = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
result.add(loadPlugin(file));
|
Plugin loadedPlugin = loadPlugin(file);
|
||||||
loadedPlugins.add(plugin);
|
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;
|
continue;
|
||||||
} catch (InvalidPluginException ex) {
|
} catch (InvalidPluginException ex) {
|
||||||
server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'", 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();
|
pluginIterator.remove();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
result.add(loadPlugin(file));
|
Plugin loadedPlugin = loadPlugin(file);
|
||||||
loadedPlugins.add(plugin);
|
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;
|
break;
|
||||||
} catch (InvalidPluginException ex) {
|
} catch (InvalidPluginException ex) {
|
||||||
server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'", 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) {
|
if (result != null) {
|
||||||
plugins.add(result);
|
plugins.add(result);
|
||||||
lookupNames.put(result.getDescription().getName(), result);
|
lookupNames.put(result.getDescription().getName(), result);
|
||||||
|
for (String provided : result.getDescription().getProvides()) {
|
||||||
|
lookupNames.putIfAbsent(provided, result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -796,7 +844,17 @@ public final class SimplePluginManager implements PluginManager {
|
|||||||
Preconditions.checkArgument(plugin != null, "plugin");
|
Preconditions.checkArgument(plugin != null, "plugin");
|
||||||
Preconditions.checkArgument(depend != null, "depend");
|
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
|
@Override
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren