diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ClasspathLocatorUtils.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ClasspathLocatorUtils.java new file mode 100644 index 0000000000..da89557f02 --- /dev/null +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ClasspathLocatorUtils.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.fml.loading; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class ClasspathLocatorUtils { + + private static final Logger LOGGER = LogManager.getLogger(); + + public static Path findJarPathFor(final String resourceName, final String jarName, final URL resource) { + try { + Path path; + final URI uri = resource.toURI(); + if (uri.getScheme().equals("jar") && uri.getRawSchemeSpecificPart().contains("!/")) { + int lastExcl = uri.getRawSchemeSpecificPart().lastIndexOf("!/"); + path = Paths.get(new URI(uri.getRawSchemeSpecificPart().substring(0, lastExcl))); + } else { + path = Paths.get(new URI("file://"+uri.getRawSchemeSpecificPart().substring(0, uri.getRawSchemeSpecificPart().length()-resourceName.length()))); + } + //LOGGER.debug(CORE, "Found JAR {} at path {}", jarName, path.toString()); + return path; + } catch (NullPointerException | URISyntaxException e) { + LOGGER.fatal(LogMarkers.SCAN, "Failed to find JAR for class {} - {}", resourceName, jarName); + throw new RuntimeException("Unable to locate "+resourceName+" - "+jarName, e); + } + } +} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ClasspathTransformerDiscoverer.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ClasspathTransformerDiscoverer.java new file mode 100644 index 0000000000..6b8bbf1dfd --- /dev/null +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ClasspathTransformerDiscoverer.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.fml.loading; + +import cpw.mods.modlauncher.api.NamedPath; +import cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService; +import org.apache.logging.log4j.LogManager; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; + +public class ClasspathTransformerDiscoverer implements ITransformerDiscoveryService { + + private final List legacyClasspath = Arrays.stream(System.getProperty("legacyClassPath", "").split(File.pathSeparator)).map(Path::of).toList(); + + @Override + public List candidates(Path gameDirectory) { + return Collections.emptyList(); + } + + @Override + public List candidates(final Path gameDirectory, final String launchTarget) { + if (launchTarget != null && launchTarget.contains("dev")) { + this.scan(gameDirectory); + } + return List.copyOf(found); + } + + private final static List found = new ArrayList<>(); + + public static List allExcluded() { + return found.stream().map(np->np.paths()[0]).toList(); + } + + private void scan(final Path gameDirectory) { + try { + locateTransformers("META-INF/services/cpw.mods.modlauncher.api.ITransformationService"); + locateTransformers("META-INF/services/net.minecraftforge.forgespi.locating.IModLocator"); + } catch (IOException e) { + LogManager.getLogger().error("Error during discovery of transform services from the classpath", e); + } + } + + private void locateTransformers(String resource) throws IOException { + final Enumeration resources = ClassLoader.getSystemClassLoader().getResources(resource); + while (resources.hasMoreElements()) { + URL url = resources.nextElement(); + Path path = ClasspathLocatorUtils.findJarPathFor(resource, url.toString(), url); + if (legacyClasspath.stream().anyMatch(path::equals) || !Files.exists(path) || Files.isDirectory(path)) + continue; + found.add(new NamedPath(path.toUri().toString(), path)); + } + } +} diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java index 849ff43ac5..44b4a9015a 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ClasspathLocator.java @@ -5,18 +5,16 @@ package net.minecraftforge.fml.loading.moddiscovery; +import net.minecraftforge.fml.loading.ClasspathLocatorUtils; import net.minecraftforge.fml.loading.LogMarkers; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.File; import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; @@ -58,7 +56,7 @@ public class ClasspathLocator extends AbstractJarFileModLocator { final Enumeration resources = ClassLoader.getSystemClassLoader().getResources(resource); while (resources.hasMoreElements()) { URL url = resources.nextElement(); - Path path = findJarPathFor(resource, resource, url); + Path path = ClasspathLocatorUtils.findJarPathFor(resource, resource, url); if (claimed.stream().anyMatch(path::equals) || !Files.exists(path) || Files.isDirectory(path)) continue; ret.add(path); @@ -71,22 +69,4 @@ public class ClasspathLocator extends AbstractJarFileModLocator { var launchTarget = (String) arguments.get("launchTarget"); enabled = launchTarget != null && launchTarget.contains("dev"); } - - private Path findJarPathFor(final String resourceName, final String jarName, final URL resource) { - try { - Path path; - final URI uri = resource.toURI(); - if (uri.getScheme().equals("jar") && uri.getRawSchemeSpecificPart().contains("!/")) { - int lastExcl = uri.getRawSchemeSpecificPart().lastIndexOf("!/"); - path = Paths.get(new URI(uri.getRawSchemeSpecificPart().substring(0, lastExcl))); - } else { - path = Paths.get(new URI("file://"+uri.getRawSchemeSpecificPart().substring(0, uri.getRawSchemeSpecificPart().length()-resourceName.length()))); - } - //LOGGER.debug(CORE, "Found JAR {} at path {}", jarName, path.toString()); - return path; - } catch (NullPointerException | URISyntaxException e) { - LOGGER.fatal(LogMarkers.SCAN, "Failed to find JAR for class {} - {}", resourceName, jarName); - throw new RuntimeException("Unable to locate "+resourceName+" - "+jarName, e); - } - } } diff --git a/fmlloader/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService b/fmlloader/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService index 48b92283d6..8838a64024 100644 --- a/fmlloader/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService +++ b/fmlloader/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService @@ -1 +1,2 @@ -net.minecraftforge.fml.loading.ModDirTransformerDiscoverer \ No newline at end of file +net.minecraftforge.fml.loading.ModDirTransformerDiscoverer +net.minecraftforge.fml.loading.ClasspathTransformerDiscoverer \ No newline at end of file