aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--patches/api/0474-Add-hook-to-remap-library-jars.patch38
-rw-r--r--patches/server/1047-Remap-plugin-libraries-with-namespace-set-to-spigot.patch210
2 files changed, 248 insertions, 0 deletions
diff --git a/patches/api/0474-Add-hook-to-remap-library-jars.patch b/patches/api/0474-Add-hook-to-remap-library-jars.patch
new file mode 100644
index 0000000000..fe1609629e
--- /dev/null
+++ b/patches/api/0474-Add-hook-to-remap-library-jars.patch
@@ -0,0 +1,38 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jason Penilla <[email protected]>
+Date: Sun, 28 Apr 2024 13:51:08 -0700
+Subject: [PATCH] Add hook to remap library jars
+
+
+diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
+index 5b0203e908f84c531886b8ea8faeb591eb045636..8e1b6be2462aaa692efa1f72986921a6dc357196 100644
+--- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
++++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
+@@ -47,6 +47,7 @@ public class LibraryLoader
+ private final DefaultRepositorySystemSession session;
+ private final List<RemoteRepository> repositories;
+ public static java.util.function.BiFunction<URL[], ClassLoader, URLClassLoader> LIBRARY_LOADER_FACTORY; // Paper - rewrite reflection in libraries
++ public static java.util.function.Function<List<java.nio.file.Path>, List<java.nio.file.Path>> REMAPPER; // Paper - remap libraries
+
+ public LibraryLoader(@NotNull Logger logger)
+ {
+@@ -111,9 +112,18 @@ public class LibraryLoader
+ }
+
+ List<URL> jarFiles = new ArrayList<>();
++ List<java.nio.file.Path> jarPaths = new ArrayList<>(); // Paper - remap libraries
+ for ( ArtifactResult artifact : result.getArtifactResults() )
+ {
+- File file = artifact.getArtifact().getFile();
++ // Paper start - remap libraries
++ jarPaths.add(artifact.getArtifact().getFile().toPath());
++ }
++ if (REMAPPER != null) {
++ jarPaths = REMAPPER.apply(jarPaths);
++ }
++ for (java.nio.file.Path path : jarPaths) {
++ File file = path.toFile();
++ // Paper end - remap libraries
+
+ URL url;
+ try
diff --git a/patches/server/1047-Remap-plugin-libraries-with-namespace-set-to-spigot.patch b/patches/server/1047-Remap-plugin-libraries-with-namespace-set-to-spigot.patch
new file mode 100644
index 0000000000..03df91b0f9
--- /dev/null
+++ b/patches/server/1047-Remap-plugin-libraries-with-namespace-set-to-spigot.patch
@@ -0,0 +1,210 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jason Penilla <[email protected]>
+Date: Sun, 28 Apr 2024 13:54:18 -0700
+Subject: [PATCH] Remap plugin libraries with namespace set to spigot
+
+
+diff --git a/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
+index bb1cfa8ea8b11fc36ea72c8e382b8554bccd0ce5..6f14cb9a73faa1d0ae2939d08809d9f6c2a99e1d 100644
+--- a/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
++++ b/src/main/java/io/papermc/paper/plugin/PluginInitializerManager.java
+@@ -7,9 +7,11 @@ import io.papermc.paper.plugin.entrypoint.LaunchEntryPointHandler;
+ import io.papermc.paper.plugin.provider.PluginProvider;
+ import io.papermc.paper.plugin.provider.type.paper.PaperPluginParent;
+ import io.papermc.paper.pluginremap.PluginRemapper;
++import java.util.function.Function;
+ import joptsimple.OptionSet;
+ import net.minecraft.server.dedicated.DedicatedServer;
+ import org.bukkit.configuration.file.YamlConfiguration;
++import org.bukkit.plugin.java.LibraryLoader;
+ import org.jetbrains.annotations.NotNull;
+ import org.jetbrains.annotations.Nullable;
+ import org.slf4j.Logger;
+@@ -33,6 +35,7 @@ public class PluginInitializerManager {
+ this.pluginRemapper = Boolean.getBoolean("paper.disable-plugin-rewriting")
+ ? null
+ : PluginRemapper.create(pluginDirectory);
++ LibraryLoader.REMAPPER = this.pluginRemapper == null ? Function.identity() : this.pluginRemapper::remapLibraries;
+ }
+
+ private static PluginInitializerManager parse(@NotNull final OptionSet minecraftOptionSet) throws Exception {
+diff --git a/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java b/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
+index ca6cb891e9da9d7e08f1a82fab212d2063cc9ef6..82032370e7896b621e37ee3726016440e177619f 100644
+--- a/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
++++ b/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
+@@ -1,5 +1,6 @@
+ package io.papermc.paper.plugin.loader;
+
++import io.papermc.paper.plugin.PluginInitializerManager;
+ import io.papermc.paper.plugin.bootstrap.PluginProviderContext;
+ import io.papermc.paper.plugin.entrypoint.classloader.BytecodeModifyingURLClassLoader;
+ import io.papermc.paper.plugin.entrypoint.classloader.PaperPluginClassLoader;
+@@ -45,9 +46,12 @@ public class PaperClasspathBuilder implements PluginClasspathBuilder {
+ }
+
+ List<Path> paths = paperLibraryStore.getPaths();
++ if (PluginInitializerManager.instance().pluginRemapper != null) {
++ paths = PluginInitializerManager.instance().pluginRemapper.remapLibraries(paths);
++ }
+ URL[] urls = new URL[paths.size()];
+ for (int i = 0; i < paths.size(); i++) {
+- Path path = paperLibraryStore.getPaths().get(i);
++ Path path = paths.get(i);
+ try {
+ urls[i] = path.toUri().toURL();
+ } catch (MalformedURLException e) {
+diff --git a/src/main/java/io/papermc/paper/pluginremap/PluginRemapper.java b/src/main/java/io/papermc/paper/pluginremap/PluginRemapper.java
+index 6f1e4ae352dcc6aacd9703b1653701f93974d1bd..a1ce1307b2834f2415bdddbf42d80e2d69a480e1 100644
+--- a/src/main/java/io/papermc/paper/pluginremap/PluginRemapper.java
++++ b/src/main/java/io/papermc/paper/pluginremap/PluginRemapper.java
+@@ -44,6 +44,7 @@ public final class PluginRemapper {
+ public static final boolean DEBUG_LOGGING = Boolean.getBoolean("Paper.PluginRemapperDebug");
+ private static final String PAPER_REMAPPED = ".paper-remapped";
+ private static final String UNKNOWN_ORIGIN = "unknown-origin";
++ private static final String LIBRARIES = "libraries";
+ private static final String EXTRA_PLUGINS = "extra-plugins";
+ private static final String REMAP_CLASSPATH = "remap-classpath";
+ private static final String REVERSED_MAPPINGS = "mappings/reversed";
+@@ -54,6 +55,7 @@ public final class PluginRemapper {
+ private final RemappedPluginIndex remappedPlugins;
+ private final RemappedPluginIndex extraPlugins;
+ private final UnknownOriginRemappedPluginIndex unknownOrigin;
++ private final UnknownOriginRemappedPluginIndex libraries;
+ private @Nullable CompletableFuture<IMappingFile> reversedMappings;
+
+ public PluginRemapper(final Path pluginsDir) {
+@@ -65,6 +67,7 @@ public final class PluginRemapper {
+ this.remappedPlugins = new RemappedPluginIndex(remappedPlugins, false);
+ this.extraPlugins = new RemappedPluginIndex(this.remappedPlugins.dir().resolve(EXTRA_PLUGINS), true);
+ this.unknownOrigin = new UnknownOriginRemappedPluginIndex(this.remappedPlugins.dir().resolve(UNKNOWN_ORIGIN));
++ this.libraries = new UnknownOriginRemappedPluginIndex(this.remappedPlugins.dir().resolve(LIBRARIES));
+ }
+
+ public static @Nullable PluginRemapper create(final Path pluginsDir) {
+@@ -93,6 +96,7 @@ public final class PluginRemapper {
+ this.remappedPlugins.write();
+ this.extraPlugins.write();
+ this.unknownOrigin.write(clean);
++ this.libraries.write(clean);
+ }
+
+ // Called on startup and reload
+@@ -112,6 +116,29 @@ public final class PluginRemapper {
+ this.save(false);
+ }
+
++ public List<Path> remapLibraries(final List<Path> libraries) {
++ final List<CompletableFuture<Path>> tasks = new ArrayList<>();
++ for (final Path lib : libraries) {
++ if (!lib.getFileName().toString().endsWith(".jar")) {
++ if (DEBUG_LOGGING) {
++ LOGGER.info("Library '{}' is not a jar.", libraries);
++ }
++ tasks.add(CompletableFuture.completedFuture(lib));
++ continue;
++ }
++ final @Nullable Path cached = this.libraries.getIfPresent(lib);
++ if (cached != null) {
++ if (DEBUG_LOGGING) {
++ LOGGER.info("Library '{}' has not changed since last remap.", libraries);
++ }
++ tasks.add(CompletableFuture.completedFuture(cached));
++ continue;
++ }
++ tasks.add(this.remapLibrary(this.libraries, lib));
++ }
++ return waitForAll(tasks);
++ }
++
+ public Path rewritePlugin(final Path plugin) {
+ // Already remapped
+ if (plugin.getParent().equals(this.remappedPlugins.dir())
+@@ -232,6 +259,20 @@ public final class PluginRemapper {
+ }, executor).thenCompose(f -> f);
+ }
+
++ private CompletableFuture<Path> remapPlugin(
++ final RemappedPluginIndex index,
++ final Path inputFile
++ ) {
++ return this.remap(index, inputFile, false);
++ }
++
++ private CompletableFuture<Path> remapLibrary(
++ final RemappedPluginIndex index,
++ final Path inputFile
++ ) {
++ return this.remap(index, inputFile, true);
++ }
++
+ /**
+ * Returns the remapped file if remapping was necessary, otherwise null.
+ *
+@@ -239,7 +280,11 @@ public final class PluginRemapper {
+ * @param inputFile input file
+ * @return remapped file, or inputFile if no remapping was necessary
+ */
+- private CompletableFuture<Path> remapPlugin(final RemappedPluginIndex index, final Path inputFile) {
++ private CompletableFuture<Path> remap(
++ final RemappedPluginIndex index,
++ final Path inputFile,
++ final boolean library
++ ) {
+ final Path destination = index.input(inputFile);
+
+ try (final FileSystem fs = FileSystems.newFileSystem(inputFile, new HashMap<>())) {
+@@ -255,18 +300,35 @@ public final class PluginRemapper {
+ } else {
+ ns = null;
+ }
+- if (ns != null && (ns.equals(InsertManifestAttribute.MOJANG_NAMESPACE) || ns.equals(InsertManifestAttribute.MOJANG_PLUS_YARN_NAMESPACE))) {
+- if (DEBUG_LOGGING) {
+- LOGGER.info("Plugin '{}' is already Mojang mapped.", inputFile);
++ final boolean mojangMappedManifest = ns != null && (ns.equals(InsertManifestAttribute.MOJANG_NAMESPACE) || ns.equals(InsertManifestAttribute.MOJANG_PLUS_YARN_NAMESPACE));
++ if (library) {
++ if (mojangMappedManifest) {
++ if (DEBUG_LOGGING) {
++ LOGGER.info("Library '{}' is already Mojang mapped.", inputFile);
++ }
++ index.skip(inputFile);
++ return CompletableFuture.completedFuture(inputFile);
++ } else if (ns == null) {
++ if (DEBUG_LOGGING) {
++ LOGGER.info("Library '{}' does not specify a mappings namespace (not remapping).", inputFile);
++ }
++ index.skip(inputFile);
++ return CompletableFuture.completedFuture(inputFile);
+ }
+- index.skip(inputFile);
+- return CompletableFuture.completedFuture(inputFile);
+- } else if (ns == null && Files.exists(fs.getPath(PluginFileType.PAPER_PLUGIN_YML))) {
+- if (DEBUG_LOGGING) {
+- LOGGER.info("Plugin '{}' is a Paper plugin with no namespace specified.", inputFile);
++ } else {
++ if (mojangMappedManifest) {
++ if (DEBUG_LOGGING) {
++ LOGGER.info("Plugin '{}' is already Mojang mapped.", inputFile);
++ }
++ index.skip(inputFile);
++ return CompletableFuture.completedFuture(inputFile);
++ } else if (ns == null && Files.exists(fs.getPath(PluginFileType.PAPER_PLUGIN_YML))) {
++ if (DEBUG_LOGGING) {
++ LOGGER.info("Plugin '{}' is a Paper plugin with no namespace specified.", inputFile);
++ }
++ index.skip(inputFile);
++ return CompletableFuture.completedFuture(inputFile);
+ }
+- index.skip(inputFile);
+- return CompletableFuture.completedFuture(inputFile);
+ }
+ } catch (final IOException ex) {
+ throw new RuntimeException("Failed to open plugin jar " + inputFile, ex);
+@@ -290,7 +352,7 @@ public final class PluginRemapper {
+ } catch (final Exception ex) {
+ throw new RuntimeException("Failed to remap plugin jar '" + inputFile + "'", ex);
+ }
+- LOGGER.info("Done remapping plugin '{}' in {}ms.", inputFile, System.currentTimeMillis() - start);
++ LOGGER.info("Done remapping {} '{}' in {}ms.", library ? "library" : "plugin", inputFile, System.currentTimeMillis() - start);
+ return destination;
+ }, this.threadPool);
+ }