diff --git a/patches/api/0008-Paper-Plugins.patch b/patches/api/0008-Paper-Plugins.patch index 4c6ce22600..d73b50e2ac 100644 --- a/patches/api/0008-Paper-Plugins.patch +++ b/patches/api/0008-Paper-Plugins.patch @@ -1218,72 +1218,6 @@ index 0000000000000000000000000000000000000000..44d630c3eb2670c36134b9907519dc98 + boolean hasDependency(@NotNull String pluginIdentifier); + +} -diff --git a/src/main/java/io/papermc/paper/plugin/provider/util/DummyBukkitPluginLoader.java b/src/main/java/io/papermc/paper/plugin/provider/util/DummyBukkitPluginLoader.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c912ee020937f1ce16481c108e332e45acba5ff9 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/provider/util/DummyBukkitPluginLoader.java -@@ -0,0 +1,60 @@ -+package io.papermc.paper.plugin.provider.util; -+ -+import org.bukkit.Bukkit; -+import org.bukkit.event.Event; -+import org.bukkit.event.Listener; -+import org.bukkit.plugin.InvalidDescriptionException; -+import org.bukkit.plugin.InvalidPluginException; -+import org.bukkit.plugin.Plugin; -+import org.bukkit.plugin.PluginDescriptionFile; -+import org.bukkit.plugin.PluginLoader; -+import org.bukkit.plugin.RegisteredListener; -+import org.bukkit.plugin.UnknownDependencyException; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+ -+import java.io.File; -+import java.util.Map; -+import java.util.Set; -+import java.util.regex.Pattern; -+ -+/** -+ * A purely internal type that implements the now deprecated {@link PluginLoader} after the implementation -+ * of papers new plugin system. -+ * -+ * @param plugin the loaded plugin that should be wrapped by this NOOP implementation -+ */ -+@ApiStatus.Internal -+public record DummyBukkitPluginLoader(Plugin plugin) implements PluginLoader { -+ -+ -+ @Override -+ public @NotNull Plugin loadPlugin(@NotNull File file) throws InvalidPluginException, UnknownDependencyException { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public @NotNull PluginDescriptionFile getPluginDescription(@NotNull File file) throws InvalidDescriptionException { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public @NotNull Pattern[] getPluginFileFilters() { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public @NotNull Map, Set> createRegisteredListeners(@NotNull Listener listener, @NotNull Plugin plugin) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public void enablePlugin(@NotNull Plugin plugin) { -+ Bukkit.getPluginManager().enablePlugin(plugin); -+ } -+ -+ @Override -+ public void disablePlugin(@NotNull Plugin plugin) { -+ Bukkit.getPluginManager().disablePlugin(plugin); -+ } -+} diff --git a/src/main/java/io/papermc/paper/plugin/provider/util/ProviderUtil.java b/src/main/java/io/papermc/paper/plugin/provider/util/ProviderUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..6bf3d212a6156ad9ab0e82d1ca0a04f83f6e4b83 @@ -1901,7 +1835,7 @@ index a80251eff75430863b37db1c131e22593f3fcd5e..310c4041963a3f1e0a26e39a6da12a9b + // Paper end } diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java -index 669a70faa95d0d6525a731d73499ed6fb0b48320..a5636b1f223dd37420a4acbccf28f7198a7eee98 100644 +index 669a70faa95d0d6525a731d73499ed6fb0b48320..6175b04327b12e74140a0885f7326546dfaf269a 100644 --- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java +++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java @@ -38,6 +38,7 @@ public abstract class JavaPlugin extends PluginBase { @@ -1977,7 +1911,7 @@ index 669a70faa95d0d6525a731d73499ed6fb0b48320..a5636b1f223dd37420a4acbccf28f719 if (isEnabled != enabled) { isEnabled = enabled; -@@ -268,9 +283,14 @@ public abstract class JavaPlugin extends PluginBase { +@@ -268,9 +283,18 @@ public abstract class JavaPlugin extends PluginBase { } } @@ -1985,17 +1919,21 @@ index 669a70faa95d0d6525a731d73499ed6fb0b48320..a5636b1f223dd37420a4acbccf28f719 - final void init(@NotNull PluginLoader loader, @NotNull Server server, @NotNull PluginDescriptionFile description, @NotNull File dataFolder, @NotNull File file, @NotNull ClassLoader classLoader) { - this.loader = loader; + // Paper start ++ private static class DummyPluginLoaderImplHolder { ++ private static final PluginLoader INSTANCE = net.kyori.adventure.util.Services.service(PluginLoader.class) ++ .orElseThrow(); ++ } + public final void init(@NotNull PluginLoader loader, @NotNull Server server, @NotNull PluginDescriptionFile description, @NotNull File dataFolder, @NotNull File file, @NotNull ClassLoader classLoader) { + init(server, description, dataFolder, file, classLoader, description); + this.pluginMeta = description; + } + public final void init(@NotNull Server server, @NotNull PluginDescriptionFile description, @NotNull File dataFolder, @NotNull File file, @NotNull ClassLoader classLoader, @Nullable io.papermc.paper.plugin.configuration.PluginMeta configuration) { + // Paper end -+ this.loader = new io.papermc.paper.plugin.provider.util.DummyBukkitPluginLoader(this); ++ this.loader = DummyPluginLoaderImplHolder.INSTANCE; // Paper this.server = server; this.file = file; this.description = description; -@@ -278,6 +298,7 @@ public abstract class JavaPlugin extends PluginBase { +@@ -278,6 +302,7 @@ public abstract class JavaPlugin extends PluginBase { this.classLoader = classLoader; this.configFile = new File(dataFolder, "config.yml"); this.logger = new PluginLogger(this); @@ -2049,7 +1987,7 @@ index 6d634b0ea813ccb19f1562a7d0e5a59cea4eab21..f9e67e20133d349e43d126dbb48b34d4 private final Logger logger; diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -index 2f74ec96ece706de23156ebabfe493211bc05391..e721c58eafee2180d4ba1a73002cf850355a366e 100644 +index 2f74ec96ece706de23156ebabfe493211bc05391..2c3d2f60d3f2f55a1a90791d37521c61f96ab4b3 100644 --- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java @@ -29,7 +29,8 @@ import org.jetbrains.annotations.Nullable; @@ -2134,7 +2072,7 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..e721c58eafee2180d4ba1a73002cf850 if (result != null) { // If the class was loaded from a library instead of a PluginClassLoader, we can assume that its associated plugin is a transitive dependency and can therefore skip this check. -@@ -128,7 +153,7 @@ final class PluginClassLoader extends URLClassLoader { +@@ -128,14 +153,14 @@ final class PluginClassLoader extends URLClassLoader { if (provider != description && !seenIllegalAccess.contains(provider.getName()) @@ -2143,6 +2081,14 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..e721c58eafee2180d4ba1a73002cf850 seenIllegalAccess.add(provider.getName()); if (plugin != null) { + plugin.getLogger().log(Level.WARNING, "Loaded class {0} from {1} which is not a depend or softdepend of this plugin.", new Object[]{name, provider.getFullName()}); + } else { + // In case the bad access occurs on construction +- loader.server.getLogger().log(Level.WARNING, "[{0}] Loaded class {1} from {2} which is not a depend or softdepend of this plugin.", new Object[]{description.getName(), name, provider.getFullName()}); ++ org.bukkit.Bukkit.getLogger().log(Level.WARNING, "[{0}] Loaded class {1} from {2} which is not a depend or softdepend of this plugin.", new Object[]{description.getName(), name, provider.getFullName()}); // Paper + } + } + } @@ -167,7 +192,7 @@ final class PluginClassLoader extends URLClassLoader { throw new ClassNotFoundException(name, ex); } diff --git a/patches/api/0070-Handle-plugin-prefixes-in-implementation-logging-con.patch b/patches/api/0070-Handle-plugin-prefixes-in-implementation-logging-con.patch index 692bbf51ef..bdc3a0e82f 100644 --- a/patches/api/0070-Handle-plugin-prefixes-in-implementation-logging-con.patch +++ b/patches/api/0070-Handle-plugin-prefixes-in-implementation-logging-con.patch @@ -17,7 +17,7 @@ The implementation should handle plugin prefixes by displaying logger names when appropriate. diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java -index a5636b1f223dd37420a4acbccf28f7198a7eee98..accac9527b1c267b75774532b85f28c868b06c28 100644 +index 6175b04327b12e74140a0885f7326546dfaf269a..79df67daf2fe8193fd83dd6a7bfc78b3f6e524c2 100644 --- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java +++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java @@ -44,7 +44,7 @@ public abstract class JavaPlugin extends PluginBase { @@ -29,7 +29,7 @@ index a5636b1f223dd37420a4acbccf28f7198a7eee98..accac9527b1c267b75774532b85f28c8 public JavaPlugin() { // Paper start -@@ -297,8 +297,8 @@ public abstract class JavaPlugin extends PluginBase { +@@ -301,8 +301,8 @@ public abstract class JavaPlugin extends PluginBase { this.dataFolder = dataFolder; this.classLoader = classLoader; this.configFile = new File(dataFolder, "config.yml"); diff --git a/patches/api/0072-Add-workaround-for-plugins-modifying-the-parent-of-t.patch b/patches/api/0072-Add-workaround-for-plugins-modifying-the-parent-of-t.patch index eadb0c1fc9..d35399c155 100644 --- a/patches/api/0072-Add-workaround-for-plugins-modifying-the-parent-of-t.patch +++ b/patches/api/0072-Add-workaround-for-plugins-modifying-the-parent-of-t.patch @@ -67,7 +67,7 @@ index 0000000000000000000000000000000000000000..087ee57fe5485bc760fadd45a176d4d9 + +} diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java -index accac9527b1c267b75774532b85f28c868b06c28..a536c47fb5f05cad046c2f3374c69f4f83f7f32c 100644 +index 79df67daf2fe8193fd83dd6a7bfc78b3f6e524c2..0e4cedc005466c600ff6b9d500febf338b12a842 100644 --- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java +++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java @@ -44,7 +44,7 @@ public abstract class JavaPlugin extends PluginBase { @@ -79,7 +79,7 @@ index accac9527b1c267b75774532b85f28c868b06c28..a536c47fb5f05cad046c2f3374c69f4f public JavaPlugin() { // Paper start -@@ -298,7 +298,11 @@ public abstract class JavaPlugin extends PluginBase { +@@ -302,7 +302,11 @@ public abstract class JavaPlugin extends PluginBase { this.classLoader = classLoader; this.configFile = new File(dataFolder, "config.yml"); this.pluginMeta = configuration; // Paper @@ -93,7 +93,7 @@ index accac9527b1c267b75774532b85f28c868b06c28..a536c47fb5f05cad046c2f3374c69f4f /** diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -index 39c9253d03bae99f8b5b19d22295f6172606d57b..a657654079c40a0fee6f70c7d72df24b3827b911 100644 +index c5f49ba2d0cc5cdf127670ea2be59f1b174dc94b..1c6542bb9ce13781c8f3b84330b5ef5aa52d0348 100644 --- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java @@ -66,7 +66,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm diff --git a/patches/api/0386-Add-system-property-to-print-stacktrace-on-bad-plugi.patch b/patches/api/0386-Add-system-property-to-print-stacktrace-on-bad-plugi.patch index 62749287b8..ab80103802 100644 --- a/patches/api/0386-Add-system-property-to-print-stacktrace-on-bad-plugi.patch +++ b/patches/api/0386-Add-system-property-to-print-stacktrace-on-bad-plugi.patch @@ -6,16 +6,16 @@ Subject: [PATCH] Add system property to print stacktrace on bad plugin class diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -index 4cb4e28c9b0dfdac45c4129fb0325e6afe5cb131..4b3380a42b4be54ef4df806c5db0d3a1be5909a6 100644 +index e9fbf5fd2c86150561468f2c061b75004b123952..e0e69b5639eeb424cb55b0be24a7e938e45fbb26 100644 --- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java @@ -184,6 +184,11 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm // In case the bad access occurs on construction - loader.server.getLogger().log(Level.WARNING, "[{0}] Loaded class {1} from {2} which is not a depend or softdepend of this plugin.", new Object[]{description.getName(), name, provider.getFullName()}); + org.bukkit.Bukkit.getLogger().log(Level.WARNING, "[{0}] Loaded class {1} from {2} which is not a depend or softdepend of this plugin.", new Object[]{description.getName(), name, provider.getFullName()}); // Paper } + // Paper start + if (Boolean.getBoolean("Paper.printStacktraceOnBadPluginClassAccess")) { -+ (plugin != null ? plugin.getLogger() : loader.server.getLogger()).log(Level.WARNING, "Stacktrace", new Exception()); ++ (plugin != null ? plugin.getLogger() : org.bukkit.Bukkit.getLogger()).log(Level.WARNING, "Stacktrace", new Exception()); + } + // Paper end } diff --git a/patches/server/0013-Paper-Plugins.patch b/patches/server/0013-Paper-Plugins.patch index 701ff50329..dbe2760025 100644 --- a/patches/server/0013-Paper-Plugins.patch +++ b/patches/server/0013-Paper-Plugins.patch @@ -457,13 +457,14 @@ index 0000000000000000000000000000000000000000..254854646b748e5bb47657625315ced5 +} diff --git a/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..85fa762d7d3476510886a7cc7b3bc79acfce4425 +index 0000000000000000000000000000000000000000..9926eb59b83abffffb578356f148f045edc027cb --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java -@@ -0,0 +1,78 @@ +@@ -0,0 +1,88 @@ +package io.papermc.paper.plugin; + +import com.mojang.logging.LogUtils; ++import io.papermc.paper.configuration.PaperConfigurations; +import joptsimple.OptionSet; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; @@ -482,45 +483,54 @@ index 0000000000000000000000000000000000000000..85fa762d7d3476510886a7cc7b3bc79a + private final Path pluginDirectory; + private final Path updateDirectory; + -+ PluginInitializerManager(@NotNull OptionSet minecraftOptionSet) { -+ // We have to load the bukkit configuration inorder to get the update folder location. -+ File configFileLocationBukkit = (File) minecraftOptionSet.valueOf("bukkit-settings"); -+ this.pluginDirectory = ((File) minecraftOptionSet.valueOf("plugins")).toPath(); -+ -+ String updateDirectory = YamlConfiguration.loadConfiguration(configFileLocationBukkit).getString("settings.update-folder", "update"); -+ if (updateDirectory.isBlank()) { -+ this.updateDirectory = null; -+ } else { -+ Path resolvedUpdateDirectory = this.pluginDirectory.resolve(updateDirectory); -+ if (!Files.isDirectory(resolvedUpdateDirectory)) { -+ this.updateDirectory = null; -+ return; -+ } -+ -+ boolean isSameFile = true; -+ try { -+ isSameFile = Files.isSameFile(resolvedUpdateDirectory, this.pluginDirectory); -+ } catch (IOException e) { -+ LOGGER.error("Misconfigured update directory!"); -+ LOGGER.error("Failed to compare update/plugin directory", e); -+ } -+ -+ if (isSameFile) { -+ LOGGER.error("Misconfigured update directory!"); -+ LOGGER.error(("Your configured update directory (%s) in bukkit.yml is pointing to the same location as the plugin directory (%s). " + -+ "Disabling auto updating functionality.").formatted(resolvedUpdateDirectory, this.pluginDirectory)); -+ -+ this.updateDirectory = null; -+ } else { -+ this.updateDirectory = resolvedUpdateDirectory; -+ } -+ -+ } -+ ++ PluginInitializerManager(final Path pluginDirectory, final Path updateDirectory) { ++ this.pluginDirectory = pluginDirectory; ++ this.updateDirectory = updateDirectory; + } + -+ public static PluginInitializerManager init(OptionSet optionSet) { -+ impl = new PluginInitializerManager(optionSet); ++ private static PluginInitializerManager parse(@NotNull final OptionSet minecraftOptionSet) throws Exception { ++ // We have to load the bukkit configuration inorder to get the update folder location. ++ final File configFileLocationBukkit = (File) minecraftOptionSet.valueOf("bukkit-settings"); ++ ++ final Path pluginDirectory = ((File) minecraftOptionSet.valueOf("plugins")).toPath(); ++ ++ final YamlConfiguration configuration = PaperConfigurations.loadLegacyConfigFile(configFileLocationBukkit); ++ ++ final String updateDirectoryName = configuration.getString("settings.update-folder", "update"); ++ if (updateDirectoryName.isBlank()) { ++ return new PluginInitializerManager(pluginDirectory, null); ++ } ++ ++ final Path resolvedUpdateDirectory = pluginDirectory.resolve(updateDirectoryName); ++ if (!Files.isDirectory(resolvedUpdateDirectory)) { ++ LOGGER.error("Misconfigured update directory!"); ++ LOGGER.error(("Your configured update directory (%s) in bukkit.yml is pointing to a non-directory path. " + ++ "Disabling auto updating functionality.").formatted(resolvedUpdateDirectory)); ++ return new PluginInitializerManager(pluginDirectory, null); ++ } ++ ++ boolean isSameFile; ++ try { ++ isSameFile = Files.isSameFile(resolvedUpdateDirectory, pluginDirectory); ++ } catch (final IOException e) { ++ LOGGER.error("Misconfigured update directory!"); ++ LOGGER.error("Failed to compare update/plugin directory", e); ++ return new PluginInitializerManager(pluginDirectory, null); ++ } ++ ++ if (isSameFile) { ++ LOGGER.error("Misconfigured update directory!"); ++ LOGGER.error(("Your configured update directory (%s) in bukkit.yml is pointing to the same location as the plugin directory (%s). " + ++ "Disabling auto updating functionality.").formatted(resolvedUpdateDirectory, pluginDirectory)); ++ ++ return new PluginInitializerManager(pluginDirectory, null); ++ } ++ ++ return new PluginInitializerManager(pluginDirectory, resolvedUpdateDirectory); ++ } ++ ++ public static PluginInitializerManager init(final OptionSet optionSet) throws Exception { ++ impl = parse(optionSet); + return impl; + } + @@ -2033,7 +2043,7 @@ index 0000000000000000000000000000000000000000..22189a1c42459c00d3e8bdeb980d15a6 +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/LegacyPluginLoadingStrategy.java b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/LegacyPluginLoadingStrategy.java new file mode 100644 -index 0000000000000000000000000000000000000000..8bc11d7e9341a31382c1b055565cc8d5fd3203ea +index 0000000000000000000000000000000000000000..c337852883f38f6c2d8d5afbed0c848b047701d9 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/LegacyPluginLoadingStrategy.java @@ -0,0 +1,260 @@ @@ -2069,8 +2079,8 @@ index 0000000000000000000000000000000000000000..8bc11d7e9341a31382c1b055565cc8d5 + } + + @Override -+ public List loadProviders(List> providers) { -+ List javapluginsLoaded = new ArrayList<>(); ++ public List> loadProviders(List> providers) { ++ List> javapluginsLoaded = new ArrayList<>(); + MutableGraph dependencyGraph = GraphBuilder.directed().build(); + GraphDependencyContext dependencyContext = new GraphDependencyContext(dependencyGraph); + @@ -2240,7 +2250,7 @@ index 0000000000000000000000000000000000000000..8bc11d7e9341a31382c1b055565cc8d5 + if (this.configuration.load(file, loadedPlugin)) { + loadedPlugins.add(file.getMeta().getName()); + loadedPlugins.addAll(file.getMeta().getProvidedPlugins()); -+ javapluginsLoaded.add(loadedPlugin); ++ javapluginsLoaded.add(new ProviderPair<>(file, loadedPlugin)); + } + + } catch (Exception ex) { @@ -2271,7 +2281,7 @@ index 0000000000000000000000000000000000000000..8bc11d7e9341a31382c1b055565cc8d5 + if (this.configuration.load(file, loadedPlugin)) { + loadedPlugins.add(file.getMeta().getName()); + loadedPlugins.addAll(file.getMeta().getProvidedPlugins()); -+ javapluginsLoaded.add(loadedPlugin); ++ javapluginsLoaded.add(new ProviderPair<>(file, loadedPlugin)); + } + break; + } catch (Exception ex) { @@ -2299,7 +2309,7 @@ index 0000000000000000000000000000000000000000..8bc11d7e9341a31382c1b055565cc8d5 +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ModernPluginLoadingStrategy.java b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ModernPluginLoadingStrategy.java new file mode 100644 -index 0000000000000000000000000000000000000000..a0363af157131a2b42c00028a260e9c3d3c543de +index 0000000000000000000000000000000000000000..30e56289cccc09456b3421f7960d8647b6610639 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ModernPluginLoadingStrategy.java @@ -0,0 +1,143 @@ @@ -2332,7 +2342,7 @@ index 0000000000000000000000000000000000000000..a0363af157131a2b42c00028a260e9c3 + } + + @Override -+ public List loadProviders(List> pluginProviders) { ++ public List> loadProviders(List> pluginProviders) { + MutableGraph dependencyGraph = GraphBuilder.directed().build(); + Map> providerMap = new HashMap<>(); + List> validatedProviders = new ArrayList<>(); @@ -2408,7 +2418,7 @@ index 0000000000000000000000000000000000000000..a0363af157131a2b42c00028a260e9c3 + } + + GraphDependencyContext graphDependencyContext = new GraphDependencyContext(dependencyGraph); -+ List loadedPlugins = new ArrayList<>(); ++ List> loadedPlugins = new ArrayList<>(); + for (String providerIdentifier : reversedTopographicSort) { + // It's possible that this will be null because the above dependencies for soft/load before aren't validated if they exist. + // The graph could be MutableGraph>, but we would have to check if each dependency exists there... just @@ -2426,7 +2436,7 @@ index 0000000000000000000000000000000000000000..a0363af157131a2b42c00028a260e9c3 + + T instance = retrievedProvider.createInstance(); + if (this.configuration.load(retrievedProvider, instance)) { -+ loadedPlugins.add(instance); ++ loadedPlugins.add(new ProviderPair<>(retrievedProvider, instance)); + } + } catch (Exception ex) { + LOGGER.error("Could not load plugin '%s' in folder '%s'".formatted(retrievedProvider.getFileName(), retrievedProvider.getParentSource()), ex); // Paper @@ -2505,10 +2515,10 @@ index 0000000000000000000000000000000000000000..5e18616160014d70df2b539d7e65bb00 +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ProviderLoadingStrategy.java b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ProviderLoadingStrategy.java new file mode 100644 -index 0000000000000000000000000000000000000000..e8d5ce5f137a960e353c6722e1f20f9b342d4ba5 +index 0000000000000000000000000000000000000000..dee83e821dcc9baf3a3e5ca8325b03ed2d5eb81c --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ProviderLoadingStrategy.java -@@ -0,0 +1,16 @@ +@@ -0,0 +1,20 @@ +package io.papermc.paper.plugin.entrypoint.strategy; + +import io.papermc.paper.plugin.provider.PluginProvider; @@ -2523,7 +2533,11 @@ index 0000000000000000000000000000000000000000..e8d5ce5f137a960e353c6722e1f20f9b + */ +public interface ProviderLoadingStrategy

{ + -+ List

loadProviders(List> providers); ++ List> loadProviders(List> providers); ++ ++ record ProviderPair

(PluginProvider

provider, P provided) { ++ ++ } +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/TopographicGraphSorter.java b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/TopographicGraphSorter.java new file mode 100644 @@ -2594,7 +2608,7 @@ index 0000000000000000000000000000000000000000..0720af0d48b39ca46e7d3aba08d7b359 +} diff --git a/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java b/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java new file mode 100644 -index 0000000000000000000000000000000000000000..d49dd7d17ce7ac17efb19b33de163015787213f7 +index 0000000000000000000000000000000000000000..f38ecd7f65dc24e4a3f0bc675e3730287ac353f1 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java @@ -0,0 +1,64 @@ @@ -2656,7 +2670,7 @@ index 0000000000000000000000000000000000000000..d49dd7d17ce7ac17efb19b33de163015 + } + + try { -+ return new PaperPluginClassLoader(logger, source, jarFile, configuration, this.getClass().getClassLoader(), new URLClassLoader(urls)); ++ return new PaperPluginClassLoader(logger, source, jarFile, configuration, this.getClass().getClassLoader(), new URLClassLoader(urls, getClass().getClassLoader())); + } catch (IOException exception) { + throw new RuntimeException(exception); + } @@ -2689,9 +2703,72 @@ index 0000000000000000000000000000000000000000..5fcce65009f715d46dd3013f1f92ec83 + return this.paths; + } +} +diff --git a/src/main/java/io/papermc/paper/plugin/manager/DummyBukkitPluginLoader.java b/src/main/java/io/papermc/paper/plugin/manager/DummyBukkitPluginLoader.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ea37ace14849ef4589a4f97287e6dcd64351370f +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/manager/DummyBukkitPluginLoader.java +@@ -0,0 +1,57 @@ ++package io.papermc.paper.plugin.manager; ++ ++import org.bukkit.Bukkit; ++import org.bukkit.event.Event; ++import org.bukkit.event.Listener; ++import org.bukkit.plugin.InvalidDescriptionException; ++import org.bukkit.plugin.InvalidPluginException; ++import org.bukkit.plugin.Plugin; ++import org.bukkit.plugin.PluginDescriptionFile; ++import org.bukkit.plugin.PluginLoader; ++import org.bukkit.plugin.RegisteredListener; ++import org.bukkit.plugin.UnknownDependencyException; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++import java.io.File; ++import java.util.Map; ++import java.util.Set; ++import java.util.regex.Pattern; ++ ++/** ++ * A purely internal type that implements the now deprecated {@link PluginLoader} after the implementation ++ * of papers new plugin system. ++ */ ++@ApiStatus.Internal ++public class DummyBukkitPluginLoader implements PluginLoader { ++ ++ @Override ++ public @NotNull Plugin loadPlugin(@NotNull File file) throws InvalidPluginException, UnknownDependencyException { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public @NotNull PluginDescriptionFile getPluginDescription(@NotNull File file) throws InvalidDescriptionException { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public @NotNull Pattern[] getPluginFileFilters() { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public @NotNull Map, Set> createRegisteredListeners(@NotNull Listener listener, @NotNull Plugin plugin) { ++ return PaperPluginManagerImpl.getInstance().paperEventManager.createRegisteredListeners(listener, plugin); ++ } ++ ++ @Override ++ public void enablePlugin(@NotNull Plugin plugin) { ++ Bukkit.getPluginManager().enablePlugin(plugin); ++ } ++ ++ @Override ++ public void disablePlugin(@NotNull Plugin plugin) { ++ Bukkit.getPluginManager().disablePlugin(plugin); ++ } ++} diff --git a/src/main/java/io/papermc/paper/plugin/manager/MultiRuntimePluginProviderStorage.java b/src/main/java/io/papermc/paper/plugin/manager/MultiRuntimePluginProviderStorage.java new file mode 100644 -index 0000000000000000000000000000000000000000..a47c0c1dedf5f8cd7006b170639676429c17d74d +index 0000000000000000000000000000000000000000..b532e35505d5fffd4c525109f273012e2652f777 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/manager/MultiRuntimePluginProviderStorage.java @@ -0,0 +1,49 @@ @@ -2729,8 +2806,8 @@ index 0000000000000000000000000000000000000000..a47c0c1dedf5f8cd7006b17063967642 + } + + @Override -+ public void processProvided(JavaPlugin provided) { -+ super.processProvided(provided); ++ public void processProvided(PluginProvider provider, JavaPlugin provided) { ++ super.processProvided(provider, provided); + this.provided.add(provided); + } + @@ -3512,7 +3589,7 @@ index 0000000000000000000000000000000000000000..c0e896343c22badd97c774c4ed1daa4e +} diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginManagerImpl.java b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginManagerImpl.java new file mode 100644 -index 0000000000000000000000000000000000000000..cdc3f6c5c845fe00478c41a22d39d7b348673559 +index 0000000000000000000000000000000000000000..dab211c458311869c61779305580a1c7da830f71 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginManagerImpl.java @@ -0,0 +1,241 @@ @@ -3548,9 +3625,9 @@ index 0000000000000000000000000000000000000000..cdc3f6c5c845fe00478c41a22d39d7b3 + +public class PaperPluginManagerImpl implements PluginManager, DependencyContext { + -+ private final PaperPluginInstanceManager instanceManager; -+ private final PaperEventManager paperEventManager; -+ private PermissionManager permissionManager; ++ final PaperPluginInstanceManager instanceManager; ++ final PaperEventManager paperEventManager; ++ PermissionManager permissionManager; + + public PaperPluginManagerImpl(Server server, CommandMap commandMap, @Nullable SimplePluginManager permissionManager) { + this.instanceManager = new PaperPluginInstanceManager(this, commandMap, server); @@ -3812,7 +3889,7 @@ index 0000000000000000000000000000000000000000..5d50d1d312388e979c0e1cd53a6bf597 +} diff --git a/src/main/java/io/papermc/paper/plugin/manager/SingularRuntimePluginProviderStorage.java b/src/main/java/io/papermc/paper/plugin/manager/SingularRuntimePluginProviderStorage.java new file mode 100644 -index 0000000000000000000000000000000000000000..ebc01cbffdc55ca9664897ff10ef14ad6c5ab726 +index 0000000000000000000000000000000000000000..194f1439e322cb6b3433a72f80a8a4c7624b20d5 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/manager/SingularRuntimePluginProviderStorage.java @@ -0,0 +1,80 @@ @@ -3882,8 +3959,8 @@ index 0000000000000000000000000000000000000000..ebc01cbffdc55ca9664897ff10ef14ad + } + + @Override -+ public void processProvided(JavaPlugin provided) { -+ super.processProvided(provided); ++ public void processProvided(PluginProvider provider, JavaPlugin provided) { ++ super.processProvided(provider, provided); + this.singleLoaded = provided; + } + @@ -5720,10 +5797,10 @@ index 0000000000000000000000000000000000000000..374e7d3d69fc8603ecf54999f173123d +} diff --git a/src/main/java/io/papermc/paper/plugin/storage/ServerPluginProviderStorage.java b/src/main/java/io/papermc/paper/plugin/storage/ServerPluginProviderStorage.java new file mode 100644 -index 0000000000000000000000000000000000000000..b049691292fb9d53ac598cb333fa408b043e7bc5 +index 0000000000000000000000000000000000000000..8b47e585c85e54a71e34aa57d61c1b2b8c9edfdf --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/storage/ServerPluginProviderStorage.java -@@ -0,0 +1,82 @@ +@@ -0,0 +1,85 @@ +package io.papermc.paper.plugin.storage; + +import com.mojang.logging.LogUtils; @@ -5761,18 +5838,9 @@ index 0000000000000000000000000000000000000000..b049691292fb9d53ac598cb333fa408b + + @Override + public boolean load(PluginProvider provider, JavaPlugin provided) { -+ try { -+ provided.getLogger().info(String.format("Loading server plugin %s", provided.getPluginMeta().getDisplayName())); -+ PaperPluginManagerImpl.getInstance().loadPlugin(provided); // We have to add it to the map before the plugin is loaded -+ provided.onLoad(); -+ return true; -+ } catch (Throwable ex) { -+ if (provider instanceof ProviderStatusHolder statusHolder) { -+ statusHolder.setStatus(ProviderStatus.ERRORED); -+ } -+ LOGGER.error("Could not load server plugin '%s' in folder '%s' (Is it up to date?)".formatted(provider.getFileName(), provider.getParentSource()), ex); -+ return false; -+ } ++ // Add it to the map here, we have to run the actual loading logic later. ++ PaperPluginManagerImpl.getInstance().loadPlugin(provided); ++ return true; + } + + @Override @@ -5801,6 +5869,18 @@ index 0000000000000000000000000000000000000000..b049691292fb9d53ac598cb333fa408b + pluginProviders.removeIf((provider) -> (provider instanceof PaperPluginParent.PaperServerPluginProvider pluginProvider && pluginProvider.shouldSkipCreation())); + } + ++ // We need to call the load methods AFTER all plugins are constructed ++ @Override ++ public void processProvided(PluginProvider provider, JavaPlugin provided) { ++ try { ++ provided.getLogger().info(String.format("Loading server plugin %s", provided.getPluginMeta().getDisplayName())); ++ provided.onLoad(); ++ } catch (Throwable ex) { ++ // Don't mark that provider as ERRORED, as this apparently still needs to run the onEnable logic. ++ provided.getSLF4JLogger().error("Error initializing plugin '%s' in folder '%s' (Is it up to date?)".formatted(provider.getFileName(), provider.getParentSource()), ex); ++ } ++ } ++ + @Override + public String toString() { + return "PLUGIN:" + super.toString(); @@ -5808,7 +5888,7 @@ index 0000000000000000000000000000000000000000..b049691292fb9d53ac598cb333fa408b +} diff --git a/src/main/java/io/papermc/paper/plugin/storage/SimpleProviderStorage.java b/src/main/java/io/papermc/paper/plugin/storage/SimpleProviderStorage.java new file mode 100644 -index 0000000000000000000000000000000000000000..ac263f02a9a79fb3db24c4daa16c405f9b0f7459 +index 0000000000000000000000000000000000000000..1c4c344eb65dd90e1d3698908b0d9b46262c9540 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/storage/SimpleProviderStorage.java @@ -0,0 +1,57 @@ @@ -5841,8 +5921,8 @@ index 0000000000000000000000000000000000000000..ac263f02a9a79fb3db24c4daa16c405f + this.filterLoadingProviders(providerList); + + try { -+ for (T plugin : this.strategy.loadProviders(providerList)) { -+ this.processProvided(plugin); ++ for (ProviderLoadingStrategy.ProviderPair providerPair : this.strategy.loadProviders(providerList)) { ++ this.processProvided(providerPair.provider(), providerPair.provided()); + } + } catch (PluginGraphCycleException exception) { + this.handleCycle(exception); @@ -5854,7 +5934,7 @@ index 0000000000000000000000000000000000000000..ac263f02a9a79fb3db24c4daa16c405f + return this.providers; + } + -+ public void processProvided(T provided) {} ++ public void processProvided(PluginProvider provider, T provided) {} + + // Mutable enter + protected void filterLoadingProviders(List> providers) {} @@ -6157,6 +6237,13 @@ index 0000000000000000000000000000000000000000..a22647244037cd92262b3b5a6582f0a1 +++ b/src/main/resources/META-INF/services/io.papermc.paper.plugin.provider.classloader.PaperClassLoaderStorage @@ -0,0 +1 @@ +io.papermc.paper.plugin.entrypoint.classloader.group.PaperPluginClassLoaderStorage +diff --git a/src/main/resources/META-INF/services/org.bukkit.plugin.PluginLoader b/src/main/resources/META-INF/services/org.bukkit.plugin.PluginLoader +new file mode 100644 +index 0000000000000000000000000000000000000000..4f78bc62d03460463b9694de933e5b73da8df6e3 +--- /dev/null ++++ b/src/main/resources/META-INF/services/org.bukkit.plugin.PluginLoader +@@ -0,0 +1 @@ ++io.papermc.paper.plugin.manager.DummyBukkitPluginLoader diff --git a/src/test/java/io/papermc/paper/plugin/PaperTestPlugin.java b/src/test/java/io/papermc/paper/plugin/PaperTestPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..1d14f530ef888102e47eeeaf0d1a6076e51871c4