diff --git a/patches/server/Paper-Plugins.patch b/patches/server/Paper-Plugins.patch index d9059bfa72..9d50e6a278 100644 --- a/patches/server/Paper-Plugins.patch +++ b/patches/server/Paper-Plugins.patch @@ -561,11 +561,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public static void load(OptionSet optionSet) throws Exception { + // We have to load the bukkit configuration inorder to get the update folder location. + io.papermc.paper.plugin.PluginInitializerManager pluginSystem = io.papermc.paper.plugin.PluginInitializerManager.init(optionSet); ++ + // Register the default plugin directory + io.papermc.paper.plugin.util.EntrypointUtil.registerProvidersFromSource(io.papermc.paper.plugin.provider.source.DirectoryProviderSource.INSTANCE, pluginSystem.pluginDirectoryPath()); -+ @SuppressWarnings("unchecked") -+ java.util.List files = (java.util.List) optionSet.valuesOf("add-plugin"); ++ + // Register plugins from the flag ++ @SuppressWarnings("unchecked") ++ java.util.List files = ((java.util.List) optionSet.valuesOf("add-plugin")).stream().map(File::toPath).toList(); + io.papermc.paper.plugin.util.EntrypointUtil.registerProvidersFromSource(io.papermc.paper.plugin.provider.source.PluginFlagProviderSource.INSTANCE, files); + } + @@ -3876,14 +3878,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + RuntimePluginEntrypointHandler runtimePluginEntrypointHandler = new RuntimePluginEntrypointHandler<>(new SingularRuntimePluginProviderStorage(this.dependencyTree)); + + try { ++ path = FILE_PROVIDER_SOURCE.prepareContext(path); + FILE_PROVIDER_SOURCE.registerProviders(runtimePluginEntrypointHandler, path); + } catch (IllegalArgumentException exception) { + return null; // Return null when the plugin file is not valid / plugin type is unknown + } catch (PluginGraphCycleException exception) { + throw new InvalidPluginException("Cannot import plugin that causes cyclic dependencies!"); -+ } catch (SerializationException | -+ InvalidDescriptionException ex) { // The spigot implementation wraps it in an invalid plugin exception -+ throw new InvalidPluginException(ex); + } catch (Exception e) { + throw new InvalidPluginException(e); + } @@ -3904,6 +3904,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + RuntimePluginEntrypointHandler runtimePluginEntrypointHandler = new RuntimePluginEntrypointHandler<>(new MultiRuntimePluginProviderStorage(this.dependencyTree)); + try { ++ directory = DIRECTORY_PROVIDER_SOURCE.prepareContext(directory); + DIRECTORY_PROVIDER_SOURCE.registerProviders(runtimePluginEntrypointHandler, directory); + runtimePluginEntrypointHandler.enter(Entrypoint.PLUGIN); + } catch (Exception e) { @@ -5487,6 +5488,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + +import com.mojang.logging.LogUtils; +import io.papermc.paper.plugin.entrypoint.EntrypointHandler; ++import java.io.IOException; ++import java.util.function.Consumer; +import org.slf4j.Logger; + +import java.nio.file.FileVisitOption; @@ -5506,23 +5509,39 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public void registerProviders(EntrypointHandler entrypointHandler, Path context) throws Exception { -+ // Sym link happy, create file if missing. ++ public Path prepareContext(Path context) throws IOException { ++ // Symlink happy, create file if missing. + if (!Files.isDirectory(context)) { + Files.createDirectories(context); + } + ++ this.walkFiles(context, path -> { ++ try { ++ super.prepareContext(path); ++ } catch (IOException e) { ++ throw new RuntimeException(e); ++ } ++ }); ++ return context; ++ } ++ ++ @Override ++ public void registerProviders(EntrypointHandler entrypointHandler, Path context) throws IOException { ++ this.walkFiles(context, path -> { ++ try { ++ super.registerProviders(entrypointHandler, path); ++ } catch (IllegalArgumentException ignored) { ++ // Ignore initial argument exceptions ++ } catch (Exception e) { ++ LOGGER.error("Error loading plugin: " + e.getMessage(), e); ++ } ++ }); ++ } ++ ++ private void walkFiles(Path context, Consumer consumer) throws IOException { + Files.walk(context, 1, FileVisitOption.FOLLOW_LINKS) + .filter(this::isValidFile) -+ .forEach((path) -> { -+ try { -+ super.registerProviders(entrypointHandler, path); -+ } catch (IllegalArgumentException ignored) { -+ // Ignore initial argument exceptions -+ } catch (Exception e) { -+ LOGGER.error("Error loading plugin: " + e.getMessage(), e); -+ } -+ }); ++ .forEach(consumer); + } + + public boolean isValidFile(Path path) { @@ -5568,7 +5587,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public void registerProviders(EntrypointHandler entrypointHandler, Path context) throws Exception { ++ public Path prepareContext(Path context) throws IOException { + String source = this.contextChecker.apply(context); + + if (Files.notExists(context)) { @@ -5585,17 +5604,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + try { + context = this.checkUpdate(context); -+ -+ JarFile file = new JarFile(context.toFile(), true, JarFile.OPEN_READ, JarFile.runtimeVersion()); -+ PluginFileType type = PluginFileType.guessType(file); -+ if (type == null) { -+ throw new IllegalArgumentException(source + " does not contain a " + String.join(" or ", PluginFileType.getConfigTypes()) + "! Could not determine plugin type, cannot load a plugin from it!"); -+ } -+ -+ type.register(entrypointHandler, file, context); + } catch (Exception exception) { -+ throw new RuntimeException(source + " failed to load!", exception); ++ throw new RuntimeException(source + " failed to update!", exception); + } ++ return context; ++ } ++ ++ @Override ++ public void registerProviders(EntrypointHandler entrypointHandler, Path context) throws Exception { ++ String source = this.contextChecker.apply(context); ++ ++ JarFile file = new JarFile(context.toFile(), true, JarFile.OPEN_READ, JarFile.runtimeVersion()); ++ PluginFileType type = PluginFileType.guessType(file); ++ if (type == null) { ++ throw new IllegalArgumentException(source + " does not contain a " + String.join(" or ", PluginFileType.getConfigTypes()) + "! Could not determine plugin type, cannot load a plugin from it!"); ++ } ++ ++ type.register(entrypointHandler, file, context); + } + + /** @@ -5603,7 +5628,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * + * @param file + */ -+ private Path checkUpdate(Path file) throws Exception { ++ private Path checkUpdate(Path file) throws InvalidPluginException { + PluginInitializerManager pluginSystem = PluginInitializerManager.instance(); + Path updateDirectory = pluginSystem.pluginUpdatePath(); + if (updateDirectory == null || !Files.isDirectory(updateDirectory)) { @@ -5703,25 +5728,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + +import com.mojang.logging.LogUtils; +import io.papermc.paper.plugin.entrypoint.EntrypointHandler; ++import java.nio.file.Path; +import org.slf4j.Logger; + -+import java.io.File; +import java.util.List; + +/** + * Registers providers at the provided files in the add-plugin argument. + */ -+public class PluginFlagProviderSource implements ProviderSource> { ++public class PluginFlagProviderSource implements ProviderSource> { + + public static final PluginFlagProviderSource INSTANCE = new PluginFlagProviderSource(); + private static final Logger LOGGER = LogUtils.getClassLogger(); + private final FileProviderSource providerSource = new FileProviderSource("File '%s' specified through 'add-plugin' argument"::formatted); + + @Override -+ public void registerProviders(EntrypointHandler entrypointHandler, List context) { -+ for (File file : context) { ++ public List prepareContext(List context) { ++ return context; ++ } ++ ++ @Override ++ public void registerProviders(EntrypointHandler entrypointHandler, List context) { ++ for (Path path : context) { + try { -+ this.providerSource.registerProviders(entrypointHandler, file.toPath()); ++ this.providerSource.registerProviders(entrypointHandler, path); + } catch (Exception e) { + LOGGER.error("Error loading plugin: " + e.getMessage(), e); + } @@ -5737,6 +5767,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +package io.papermc.paper.plugin.provider.source; + +import io.papermc.paper.plugin.entrypoint.EntrypointHandler; ++import java.io.IOException; + +/** + * A provider source is responsible for giving PluginTypes an EntrypointHandler for @@ -5746,6 +5777,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + */ +public interface ProviderSource { + ++ C prepareContext(C context) throws IOException; ++ + void registerProviders(EntrypointHandler entrypointHandler, C context) throws Throwable; +} diff --git a/src/main/java/io/papermc/paper/plugin/provider/type/PluginFileType.java b/src/main/java/io/papermc/paper/plugin/provider/type/PluginFileType.java @@ -6273,7 +6306,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +class PaperPluginProviderFactory implements PluginTypeFactory { + + @Override -+ public PaperPluginParent build(JarFile file, PaperPluginMeta configuration, Path source) throws Exception { ++ public PaperPluginParent build(JarFile file, PaperPluginMeta configuration, Path source) { + Logger jul = PaperPluginLogger.getLogger(configuration); + ComponentLogger logger = ComponentLogger.logger(jul.getName()); + PluginProviderContext context = PluginProviderContextImpl.create(configuration, logger, source); @@ -6296,7 +6329,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public PaperPluginMeta create(JarFile file, JarEntry config) throws Exception { ++ public PaperPluginMeta create(JarFile file, JarEntry config) throws IOException { + PaperPluginMeta configuration; + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(file.getInputStream(config)))) { + configuration = PaperPluginMeta.create(bufferedReader); @@ -6609,7 +6642,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +class SpigotPluginProviderFactory implements PluginTypeFactory { + + @Override -+ public SpigotPluginProvider build(JarFile file, PluginDescriptionFile configuration, Path source) throws Exception { ++ public SpigotPluginProvider build(JarFile file, PluginDescriptionFile configuration, Path source) throws InvalidDescriptionException { + // Copied from SimplePluginManager#loadPlugins + // Spigot doesn't validate the name when the config is created, and instead when the plugin is loaded. + // Paper plugin configuration will do these checks in config serializer instead of when this is created. @@ -6624,7 +6657,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public PluginDescriptionFile create(JarFile file, JarEntry config) throws Exception { ++ public PluginDescriptionFile create(JarFile file, JarEntry config) throws InvalidDescriptionException { + PluginDescriptionFile descriptionFile; + try (InputStream inputStream = file.getInputStream(config)) { + descriptionFile = new PluginDescriptionFile(inputStream); @@ -6956,12 +6989,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import io.papermc.paper.plugin.provider.source.ProviderSource; +import org.slf4j.Logger; + -+public class EntrypointUtil { ++public final class EntrypointUtil { + + private static final Logger LOGGER = LogUtils.getClassLogger(); + + public static void registerProvidersFromSource(ProviderSource source, C context) { + try { ++ context = source.prepareContext(context); + source.registerProviders(LaunchEntryPointHandler.INSTANCE, context); + } catch (Throwable e) { + LOGGER.error(e.getMessage(), e);