2021-06-11 12:02:28 +00:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2021-06-17 09:37:24 +00:00
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
2021-06-11 12:02:28 +00:00
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
2021-10-15 21:54:22 +00:00
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
2022-08-09 07:18:08 +00:00
index 557cf1ff29e16fa942545ceca14696c2a50b2d4d..a5c02f744664248f46aa35452318b6a728cd4afd 100644
2021-10-15 21:54:22 +00:00
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
2022-08-09 07:18:08 +00:00
@@ -76,6 +76,20 @@ public final class Bukkit {
2021-11-24 01:09:49 +00:00
return server;
2021-10-15 21:54:22 +00:00
}
+ /**
+ * 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}.
+ *
+ * <p>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.</p>
+ *
+ * @return plugins directory
+ */
+ @NotNull
+ public static File getPluginsFolder() {
+ return server.getPluginsFolder();
+ }
+
/**
2021-11-24 01:09:49 +00:00
* Attempts to set the {@link Server} singleton.
* <p>
2021-10-15 21:54:22 +00:00
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
2022-08-09 07:18:08 +00:00
index a2ae6b84fe20e43292f1442401a472dcce1600ec..da13ae75ca1892c21a35aff02f92b91783a868bf 100644
2021-10-15 21:54:22 +00:00
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
2022-08-09 07:18:08 +00:00
@@ -61,6 +61,18 @@ import org.jetbrains.annotations.Nullable;
2021-11-24 01:09:49 +00:00
*/
2022-03-04 21:19:57 +00:00
public interface Server extends PluginMessageRecipient, net.kyori.adventure.audience.ForwardingAudience { // Paper
2021-10-15 21:54:22 +00:00
+ /**
+ * 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}.
+ *
+ * <p>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.</p>
+ *
+ * @return plugins directory
+ */
+ @NotNull
+ File getPluginsFolder();
+
/**
2021-11-24 01:09:49 +00:00
* Used for all administrative messages, such as an operator using a
* command.
2021-06-11 12:02:28 +00:00
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
2022-07-21 19:53:04 +00:00
index 763b3e9ea24b14c54abf94048931f29228c76df5..1bfa9fcb1b803eecfe33156f81ee88d2922ca88a 100644
2021-06-11 12:02:28 +00:00
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
2022-07-21 19:53:04 +00:00
@@ -111,6 +111,12 @@ public final class SimplePluginManager implements PluginManager {
2021-06-11 12:02:28 +00:00
@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<File> extraPluginJars) {
+ // Paper end
2022-06-07 17:20:30 +00:00
Preconditions.checkArgument(directory != null, "Directory cannot be null");
Preconditions.checkArgument(directory.isDirectory(), "Directory must be a directory");
2021-06-11 12:02:28 +00:00
2022-07-21 19:53:04 +00:00
@@ -128,7 +134,11 @@ public final class SimplePluginManager implements PluginManager {
2021-06-11 12:02:28 +00:00
Map<String, Collection<String>> softDependencies = new HashMap<String, Collection<String>>();
// This is where it figures out all possible plugins
- for (File file : directory.listFiles()) {
+ // Paper start - extra jars
+ final List<File> 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());
2022-07-21 19:53:04 +00:00
@@ -144,14 +154,14 @@ public final class SimplePluginManager implements PluginManager {
2021-06-11 12:02:28 +00:00
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;
}
2022-07-21 19:53:04 +00:00
@@ -162,7 +172,7 @@ public final class SimplePluginManager implements PluginManager {
2021-06-11 12:02:28 +00:00
description.getName(),
file.getPath(),
replacedFile.getPath(),
- directory.getPath()
+ file.getParentFile().getPath() // Paper
));
}
2022-07-21 19:53:04 +00:00
@@ -183,7 +193,7 @@ public final class SimplePluginManager implements PluginManager {
2021-06-11 12:02:28 +00:00
file.getPath(),
provided,
pluginFile.getPath(),
- directory.getPath()
+ file.getParentFile().getPath() // Paper
));
} else {
String replacedPlugin = pluginsProvided.put(provided, description.getName());
2022-07-21 19:53:04 +00:00
@@ -265,7 +275,7 @@ public final class SimplePluginManager implements PluginManager {
2021-06-11 12:02:28 +00:00
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;
}
2022-07-21 19:53:04 +00:00
@@ -304,11 +314,11 @@ public final class SimplePluginManager implements PluginManager {
2021-06-11 12:02:28 +00:00
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
}
}
}
2022-07-21 19:53:04 +00:00
@@ -335,11 +345,11 @@ public final class SimplePluginManager implements PluginManager {
2021-06-11 12:02:28 +00:00
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
}
}
}
2022-07-21 19:53:04 +00:00
@@ -352,7 +362,7 @@ public final class SimplePluginManager implements PluginManager {
2021-06-11 12:02:28 +00:00
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
2022-06-07 17:20:30 +00:00
index 5c1b8b05d8a5408bb4830942c74ebfe400ab5a32..333c47a1f7e9d7ddf91aad5ec15163427f7b8039 100644
2021-06-11 12:02:28 +00:00
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
2021-11-24 01:09:49 +00:00
@@ -91,7 +91,7 @@ public final class JavaPluginLoader implements PluginLoader {
2021-06-11 12:02:28 +00:00
throw new InvalidPluginException(ex);
}
- final File parentFile = file.getParentFile();
2021-10-15 21:54:22 +00:00
+ final File parentFile = this.server.getPluginsFolder(); // Paper
2021-06-11 12:02:28 +00:00
final File dataFolder = new File(parentFile, description.getName());
@SuppressWarnings("deprecation")
final File oldDataFolder = new File(parentFile, description.getRawName());