From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Tue, 18 May 2021 14:42:26 -0700 Subject: [PATCH] Add command line option to load extra plugin jars not in the plugins folder ex: java -jar paperclip.jar nogui -add-plugin=/path/to/plugin.jar -add-plugin=/path/to/another/plugin_jar.jar diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java index 35de49ea52b507dd925ed3c118518a335035a710..5c6b7f5095a5bb7290e1edefb0c9e985123f80d8 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -75,6 +75,20 @@ public final class Bukkit { return server; } + /** + * Returns the de facto plugins directory, generally used for storing plugin jars to be loaded, + * as well as their {@link org.bukkit.plugin.Plugin#getDataFolder() data folders}. + * + *

Plugins should use {@link org.bukkit.plugin.Plugin#getDataFolder()} rather than traversing this + * directory manually when determining the location in which to store their data and configuration files.

+ * + * @return plugins directory + */ + @NotNull + public static File getPluginsFolder() { + return server.getPluginsFolder(); + } + /** * Attempts to set the {@link Server} singleton. *

diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java index bbb4eb3c4e46ade7dd939c2b0e4436161d6f8a1e..1dedbea03e259679e101a8443b662b20375adfd0 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -60,6 +60,18 @@ import org.jetbrains.annotations.Nullable; */ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audience.ForwardingAudience { // Paper + /** + * Returns the de facto plugins directory, generally used for storing plugin jars to be loaded, + * as well as their {@link org.bukkit.plugin.Plugin#getDataFolder() data folders}. + * + *

Plugins should use {@link org.bukkit.plugin.Plugin#getDataFolder()} rather than traversing this + * directory manually when determining the location in which to store their data and configuration files.

+ * + * @return plugins directory + */ + @NotNull + File getPluginsFolder(); + /** * Used for all administrative messages, such as an operator using a * command. diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java index fca73778c341df36becbf1ad1ad42ce8d1aa634c..50a2e8c138c677c91dad65c850acf840f7517e86 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -110,6 +110,12 @@ public final class SimplePluginManager implements PluginManager { @Override @NotNull public Plugin[] loadPlugins(@NotNull File directory) { + // Paper start - extra jars + return this.loadPlugins(directory, java.util.Collections.emptyList()); + } + @NotNull + public Plugin[] loadPlugins(final @NotNull File directory, final @NotNull List extraPluginJars) { + // Paper end Preconditions.checkArgument(directory != null, "Directory cannot be null"); Preconditions.checkArgument(directory.isDirectory(), "Directory must be a directory"); @@ -127,7 +133,11 @@ public final class SimplePluginManager implements PluginManager { Map> softDependencies = new HashMap>(); // This is where it figures out all possible plugins - for (File file : directory.listFiles()) { + // Paper start - extra jars + final List pluginJars = new ArrayList<>(java.util.Arrays.asList(directory.listFiles())); + pluginJars.addAll(extraPluginJars); + for (File file : pluginJars) { + // Paper end PluginLoader loader = null; for (Pattern filter : filters) { Matcher match = filter.matcher(file.getName()); @@ -143,14 +153,14 @@ public final class SimplePluginManager implements PluginManager { description = loader.getPluginDescription(file); String name = description.getName(); if (name.equalsIgnoreCase("bukkit") || name.equalsIgnoreCase("minecraft") || name.equalsIgnoreCase("mojang")) { - server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': Restricted Name"); + server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + file.getParentFile().getPath() + "': Restricted Name"); // Paper continue; } else if (description.rawName.indexOf(' ') != -1) { - server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': uses the space-character (0x20) in its name"); + server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + file.getParentFile().getPath() + "': uses the space-character (0x20) in its name"); // Paper continue; } } catch (InvalidDescriptionException 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 '" + file.getParentFile().getPath() + "'", ex); // Paper continue; } @@ -161,7 +171,7 @@ public final class SimplePluginManager implements PluginManager { description.getName(), file.getPath(), replacedFile.getPath(), - directory.getPath() + file.getParentFile().getPath() // Paper )); } @@ -182,7 +192,7 @@ public final class SimplePluginManager implements PluginManager { file.getPath(), provided, pluginFile.getPath(), - directory.getPath() + file.getParentFile().getPath() // Paper )); } else { String replacedPlugin = pluginsProvided.put(provided, description.getName()); @@ -264,7 +274,7 @@ public final class SimplePluginManager implements PluginManager { server.getLogger().log( Level.SEVERE, - "Could not load '" + entry.getValue().getPath() + "' in folder '" + directory.getPath() + "'", + "Could not load '" + entry.getValue().getPath() + "' in folder '" + entry.getValue().getParentFile().getPath() + "'", // Paper new UnknownDependencyException("Unknown dependency " + dependency + ". Please download and install " + dependency + " to run this plugin.")); break; } @@ -303,11 +313,11 @@ public final class SimplePluginManager implements PluginManager { loadedPlugins.add(loadedPlugin.getName()); loadedPlugins.addAll(loadedPlugin.getDescription().getProvides()); } else { - server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'"); + server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + file.getParentFile().getPath() + "'"); // Paper } continue; } 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 '" + file.getParentFile().getPath() + "'", ex); // Paper } } } @@ -334,11 +344,11 @@ public final class SimplePluginManager implements PluginManager { loadedPlugins.add(loadedPlugin.getName()); loadedPlugins.addAll(loadedPlugin.getDescription().getProvides()); } else { - server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'"); + server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + file.getParentFile().getPath() + "'"); // Paper } break; } 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 '" + file.getParentFile().getPath() + "'", ex); // Paper } } } @@ -351,7 +361,7 @@ public final class SimplePluginManager implements PluginManager { while (failedPluginIterator.hasNext()) { File file = failedPluginIterator.next(); failedPluginIterator.remove(); - server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': circular dependency detected"); + server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + file.getParentFile().getPath() + "': circular dependency detected"); // Paper } } } diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java index 5c1b8b05d8a5408bb4830942c74ebfe400ab5a32..333c47a1f7e9d7ddf91aad5ec15163427f7b8039 100644 --- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -91,7 +91,7 @@ public final class JavaPluginLoader implements PluginLoader { throw new InvalidPluginException(ex); } - final File parentFile = file.getParentFile(); + final File parentFile = this.server.getPluginsFolder(); // Paper final File dataFolder = new File(parentFile, description.getName()); @SuppressWarnings("deprecation") final File oldDataFolder = new File(parentFile, description.getRawName());