From f2da18d62e20de6754a7d3c315de105687582092 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke <nassim@njahnke.dev> Date: Fri, 2 Feb 2024 12:44:09 +0100 Subject: [PATCH] More provider source fixup --- patches/server/Paper-Plugins.patch | 80 +++++++++++++++++++----------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/patches/server/Paper-Plugins.patch b/patches/server/Paper-Plugins.patch index 0f058ae011..5f86f5776a 100644 --- a/patches/server/Paper-Plugins.patch +++ b/patches/server/Paper-Plugins.patch @@ -3822,7 +3822,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +class PaperPluginInstanceManager { + + private static final FileProviderSource FILE_PROVIDER_SOURCE = new FileProviderSource("File '%s'"::formatted); -+ private static final DirectoryProviderSource DIRECTORY_PROVIDER_SOURCE = new DirectoryProviderSource(); + + private final List<Plugin> plugins = new ArrayList<>(); + private final Map<String, Plugin> lookupNames = new HashMap<>(); @@ -3904,8 +3903,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + RuntimePluginEntrypointHandler<MultiRuntimePluginProviderStorage> runtimePluginEntrypointHandler = new RuntimePluginEntrypointHandler<>(new MultiRuntimePluginProviderStorage(this.dependencyTree)); + try { -+ directory = DIRECTORY_PROVIDER_SOURCE.prepareContext(directory); -+ DIRECTORY_PROVIDER_SOURCE.registerProviders(runtimePluginEntrypointHandler, directory); ++ List<Path> files = DirectoryProviderSource.INSTANCE.prepareContext(directory); ++ DirectoryProviderSource.INSTANCE.registerProviders(runtimePluginEntrypointHandler, files); + runtimePluginEntrypointHandler.enter(Entrypoint.PLUGIN); + } catch (Exception e) { + // This should never happen, any errors that occur in this provider should instead be logged. @@ -5489,55 +5488,54 @@ 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; +import java.nio.file.Files; +import java.nio.file.Path; ++import java.util.ArrayList; ++import java.util.List; ++import java.util.function.Consumer; ++import org.slf4j.Logger; + +/** + * Loads all plugin providers in the given directory. + */ -+public class DirectoryProviderSource extends FileProviderSource { ++public class DirectoryProviderSource implements ProviderSource<Path, List<Path>> { + + public static final DirectoryProviderSource INSTANCE = new DirectoryProviderSource(); ++ private static final FileProviderSource FILE_PROVIDER_SOURCE = new FileProviderSource("Directory '%s'"::formatted); + private static final Logger LOGGER = LogUtils.getClassLogger(); + -+ public DirectoryProviderSource() { -+ super("Directory '%s'"::formatted); -+ } -+ + @Override -+ public Path prepareContext(Path context) throws IOException { ++ public List<Path> prepareContext(Path context) throws IOException { + // Symlink happy, create file if missing. + if (!Files.isDirectory(context)) { + Files.createDirectories(context); + } + ++ final List<Path> files = new ArrayList<>(); + this.walkFiles(context, path -> { + try { -+ super.prepareContext(path); ++ files.add(FILE_PROVIDER_SOURCE.prepareContext(path)); + } catch (IllegalArgumentException ignored) { + // Ignore illegal argument exceptions from jar checking + } catch (IOException e) { -+ throw new RuntimeException(e); ++ LOGGER.error("Error preparing plugin context: " + e.getMessage(), e); + } + }); -+ return context; ++ return files; + } + + @Override -+ public void registerProviders(EntrypointHandler entrypointHandler, Path context) throws IOException { -+ this.walkFiles(context, path -> { ++ public void registerProviders(EntrypointHandler entrypointHandler, List<Path> context) { ++ for (Path path : context) { + try { -+ super.registerProviders(entrypointHandler, path); ++ FILE_PROVIDER_SOURCE.registerProviders(entrypointHandler, path); + } catch (IllegalArgumentException ignored) { + // Ignore illegal argument exceptions from jar checking + } catch (Exception e) { + LOGGER.error("Error loading plugin: " + e.getMessage(), e); + } -+ }); ++ } + } + + private void walkFiles(Path context, Consumer<Path> consumer) throws IOException { @@ -5580,7 +5578,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +/** + * Loads a plugin provider at the given plugin jar file path. + */ -+public class FileProviderSource implements ProviderSource<Path> { ++public class FileProviderSource implements ProviderSource<Path, Path> { + + private final Function<Path, String> contextChecker; + @@ -5731,6 +5729,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import com.mojang.logging.LogUtils; +import io.papermc.paper.plugin.entrypoint.EntrypointHandler; +import java.nio.file.Path; ++import java.util.ArrayList; +import org.slf4j.Logger; + +import java.util.List; @@ -5738,22 +5737,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +/** + * Registers providers at the provided files in the add-plugin argument. + */ -+public class PluginFlagProviderSource implements ProviderSource<List<Path>> { ++public class PluginFlagProviderSource implements ProviderSource<List<Path>, List<Path>> { + + public static final PluginFlagProviderSource INSTANCE = new PluginFlagProviderSource(); ++ private static final FileProviderSource FILE_PROVIDER_SOURCE = new FileProviderSource("File '%s' specified through 'add-plugin' argument"::formatted); + private static final Logger LOGGER = LogUtils.getClassLogger(); -+ private final FileProviderSource providerSource = new FileProviderSource("File '%s' specified through 'add-plugin' argument"::formatted); + + @Override + public List<Path> prepareContext(List<Path> context) { -+ return context; ++ final List<Path> files = new ArrayList<>(); ++ for (Path path : context) { ++ try { ++ files.add(FILE_PROVIDER_SOURCE.prepareContext(path)); ++ } catch (Exception e) { ++ LOGGER.error("Error preparing plugin context: " + e.getMessage(), e); ++ } ++ } ++ return files; + } + + @Override + public void registerProviders(EntrypointHandler entrypointHandler, List<Path> context) { + for (Path path : context) { + try { -+ this.providerSource.registerProviders(entrypointHandler, path); ++ FILE_PROVIDER_SOURCE.registerProviders(entrypointHandler, path); + } catch (Exception e) { + LOGGER.error("Error loading plugin: " + e.getMessage(), e); + } @@ -5775,13 +5782,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * A provider source is responsible for giving PluginTypes an EntrypointHandler for + * registering providers at. + * ++ * @param <I> input context + * @param <C> context + */ -+public interface ProviderSource<C> { ++public interface ProviderSource<I, C> { + -+ C prepareContext(C context) throws IOException; ++ /** ++ * Prepares the context for use in {@link #registerProviders(EntrypointHandler, Object)}. ++ * ++ * @param context the context to prepare ++ * @return the prepared context, ready for use in {@link #registerProviders(EntrypointHandler, Object)} ++ * @throws IOException if an error occurs while preparing the context ++ */ ++ C prepareContext(I context) throws IOException; + -+ void registerProviders(EntrypointHandler entrypointHandler, C context) throws Throwable; ++ /** ++ * Uses the prepared context to register providers at the given entrypoint handler. ++ * ++ * @param entrypointHandler the entrypoint handler to register providers at ++ * @param context the context to register providers at ++ * @throws Exception if an error occurs while registering providers ++ */ ++ void registerProviders(EntrypointHandler entrypointHandler, C context) throws Exception; +} 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 new file mode 100644 @@ -6995,9 +7017,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + private static final Logger LOGGER = LogUtils.getClassLogger(); + -+ public static <C> void registerProvidersFromSource(ProviderSource<C> source, C context) { ++ public static <I, C> void registerProvidersFromSource(ProviderSource<I, C> source, I contextInput) { + try { -+ context = source.prepareContext(context); ++ C context = source.prepareContext(contextInput); + source.registerProviders(LaunchEntryPointHandler.INSTANCE, context); + } catch (Throwable e) { + LOGGER.error(e.getMessage(), e);