From 734a3d76aa738b25e134789cb1305cc0c7c44e37 Mon Sep 17 00:00:00 2001 From: cpw Date: Sun, 1 Sep 2019 11:31:09 -0400 Subject: [PATCH] Peel IModLocator into the SPI package and extract a small IModFile interface as well. This allows building external IModLocator implementations. Signed-off-by: cpw --- build.gradle | 2 +- .../moddiscovery/AbstractJarFileLocator.java | 15 ++++-- .../ExplodedDirectoryLocator.java | 12 +++-- .../fml/loading/moddiscovery/IModLocator.java | 47 ------------------- .../moddiscovery/MavenDirectoryLocator.java | 11 +++-- .../loading/moddiscovery/ModDiscoverer.java | 23 +++++---- .../fml/loading/moddiscovery/ModFile.java | 21 ++++++--- .../moddiscovery/ModsFolderLocator.java | 3 +- ...ecraftforge.forgespi.locating.IModLocator} | 0 .../userdev/ClasspathLocator.java | 3 +- ...ecraftforge.forgespi.locating.IModLocator} | 0 11 files changed, 56 insertions(+), 81 deletions(-) delete mode 100644 src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/IModLocator.java rename src/fmllauncher/resources/META-INF/services/{net.minecraftforge.fml.loading.moddiscovery.IModLocator => net.minecraftforge.forgespi.locating.IModLocator} (100%) rename src/userdev/resources/META-INF/services/{net.minecraftforge.fml.loading.moddiscovery.IModLocator => net.minecraftforge.forgespi.locating.IModLocator} (100%) diff --git a/build.gradle b/build.gradle index edc05df7c..12b03c6ed 100644 --- a/build.gradle +++ b/build.gradle @@ -408,7 +408,7 @@ project(':forge') { installer 'cpw.mods:grossjava9hacks:1.1.+' installer 'net.minecraftforge:accesstransformers:1.0.+:shadowed' installer 'net.minecraftforge:eventbus:1.0.+:service' - installer 'net.minecraftforge:forgespi:1.1.+' + installer 'net.minecraftforge:forgespi:1.2.+' installer 'net.minecraftforge:coremods:1.0.+' installer 'net.minecraftforge:unsafe:0.2.+' installer 'com.electronwill.night-config:core:3.6.0' diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/AbstractJarFileLocator.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/AbstractJarFileLocator.java index cd4bb297e..fd1ed3b47 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/AbstractJarFileLocator.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/AbstractJarFileLocator.java @@ -19,6 +19,8 @@ package net.minecraftforge.fml.loading.moddiscovery; +import net.minecraftforge.forgespi.locating.IModFile; +import net.minecraftforge.forgespi.locating.IModLocator; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -41,13 +43,13 @@ import static net.minecraftforge.fml.loading.LogMarkers.SCAN; public abstract class AbstractJarFileLocator implements IModLocator { private static final Logger LOGGER = LogManager.getLogger(); - protected final Map modJars; + protected final Map modJars; public AbstractJarFileLocator() { this.modJars = new HashMap<>(); } - protected FileSystem createFileSystem(ModFile modFile) { + protected FileSystem createFileSystem(IModFile modFile) { try { return FileSystems.newFileSystem(modFile.getFilePath(), modFile.getClass().getClassLoader()); } catch (ZipError | IOException e) { @@ -56,14 +58,16 @@ public abstract class AbstractJarFileLocator implements IModLocator { } } - public Path findPath(final ModFile modFile, final String... path) { + @Override + public Path findPath(final IModFile modFile, final String... path) { if (path.length < 1) { throw new IllegalArgumentException("Missing path"); } return modJars.get(modFile).getPath(path[0], Arrays.copyOfRange(path, 1, path.length)); } - public void scanFile(final ModFile file, final Consumer pathConsumer) { + @Override + public void scanFile(final IModFile file, final Consumer pathConsumer) { LOGGER.debug(SCAN,"Scan started: {}", file); FileSystem fs = modJars.get(file); fs.getRootDirectories().forEach(path -> { @@ -76,6 +80,7 @@ public abstract class AbstractJarFileLocator implements IModLocator { LOGGER.debug(SCAN,"Scan finished: {}", file); } + @Override public Optional findManifest(final Path file) { try (JarFile jf = new JarFile(file.toFile())) @@ -89,7 +94,7 @@ public abstract class AbstractJarFileLocator implements IModLocator { } @Override - public boolean isValid(final ModFile modFile) { + public boolean isValid(final IModFile modFile) { return modJars.get(modFile) != null; } } diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ExplodedDirectoryLocator.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ExplodedDirectoryLocator.java index c439acbf0..50f7aa81a 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ExplodedDirectoryLocator.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ExplodedDirectoryLocator.java @@ -19,6 +19,8 @@ package net.minecraftforge.fml.loading.moddiscovery; +import net.minecraftforge.forgespi.locating.IModFile; +import net.minecraftforge.forgespi.locating.IModLocator; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -36,7 +38,7 @@ import static net.minecraftforge.fml.loading.LogMarkers.SCAN; public class ExplodedDirectoryLocator implements IModLocator { private static final Logger LOGGER = LogManager.getLogger(); private final List>> rootDirs; - private final Map>> mods; + private final Map>> mods; public ExplodedDirectoryLocator() { this.rootDirs = new ArrayList<>(); @@ -44,7 +46,7 @@ public class ExplodedDirectoryLocator implements IModLocator { } @Override - public List scanMods() { + public List scanMods() { final Path modstoml = Paths.get("META-INF", "mods.toml"); // Collect all the mods.toml files found rootDirs.forEach(pathPathPair -> { @@ -67,7 +69,7 @@ public class ExplodedDirectoryLocator implements IModLocator { } @Override - public Path findPath(final ModFile modFile, final String... path) { + public Path findPath(final IModFile modFile, final String... path) { if (path.length < 1) { throw new IllegalArgumentException("Missing path"); } @@ -81,7 +83,7 @@ public class ExplodedDirectoryLocator implements IModLocator { } @Override - public void scanFile(final ModFile modFile, final Consumer pathConsumer) { + public void scanFile(final IModFile modFile, final Consumer pathConsumer) { LOGGER.debug(SCAN,"Scanning exploded directory {}", modFile.getFilePath().toString()); final Pair> pathPathPair = mods.get(modFile); // classes are in the right branch of the pair @@ -119,7 +121,7 @@ public class ExplodedDirectoryLocator implements IModLocator { } @Override - public boolean isValid(final ModFile modFile) { + public boolean isValid(final IModFile modFile) { return mods.get(modFile) != null; } } diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/IModLocator.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/IModLocator.java deleted file mode 100644 index caaaff683..000000000 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/IModLocator.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2019. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.loading.moddiscovery; - -import java.nio.file.Path; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.jar.Manifest; - -/** - * Loaded as a ServiceLoader. Takes mechanisms for locating candidate "mods" - * and transforms them into {@link ModFile} objects. - */ -public interface IModLocator { - List scanMods(); - - String name(); - - Path findPath(ModFile modFile, String... path); - - void scanFile(final ModFile modFile, Consumer pathConsumer); - - Optional findManifest(Path file); - - void initArguments(Map arguments); - - boolean isValid(ModFile modFile); -} diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/MavenDirectoryLocator.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/MavenDirectoryLocator.java index 5d7b3b914..6eba075d8 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/MavenDirectoryLocator.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/MavenDirectoryLocator.java @@ -21,6 +21,7 @@ package net.minecraftforge.fml.loading.moddiscovery; import net.minecraftforge.fml.loading.FMLPaths; import net.minecraftforge.fml.loading.MavenCoordinateResolver; +import net.minecraftforge.forgespi.locating.IModFile; import java.nio.file.Files; import java.nio.file.Path; @@ -33,11 +34,11 @@ public class MavenDirectoryLocator extends AbstractJarFileLocator { private List modCoords; @Override - public List scanMods() { - return modCoords.stream(). - map(mc -> new ModFile(mc, this)). - peek(f->modJars.compute(f, (mf, fs)->createFileSystem(mf))). - collect(Collectors.toList()); + public List scanMods() { + return modCoords.stream() + .map(mc -> new ModFile(mc, this)) + .peek(f->modJars.compute(f, (mf, fs)->createFileSystem(mf))) + .collect(Collectors.toList()); } @Override diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java index bf39d442c..49b596d7a 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java @@ -23,6 +23,8 @@ import cpw.mods.modlauncher.ServiceLoaderStreamUtils; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.LoadingModList; import net.minecraftforge.fml.loading.ModSorter; +import net.minecraftforge.forgespi.locating.IModFile; +import net.minecraftforge.forgespi.locating.IModLocator; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -75,16 +77,17 @@ public class ModDiscoverer { public BackgroundScanHandler discoverMods() { LOGGER.debug(SCAN,"Scanning for mods and other resources to load. We know {} ways to find mods", locatorList.size()); - final Map> modFiles = locatorList.stream() + final Map> modFiles = locatorList.stream() .peek(loc -> LOGGER.debug(SCAN,"Trying locator {}", loc)) .map(IModLocator::scanMods) .flatMap(Collection::stream) .peek(mf -> LOGGER.debug(SCAN,"Found mod file {} of type {} with locator {}", mf.getFileName(), mf.getType(), mf.getLocator())) - .collect(Collectors.groupingBy(ModFile::getType)); + .map(ModFile.class::cast) + .collect(Collectors.groupingBy(IModFile::getType)); - FMLLoader.getLanguageLoadingProvider().addAdditionalLanguages(modFiles.get(ModFile.Type.LANGPROVIDER)); + FMLLoader.getLanguageLoadingProvider().addAdditionalLanguages(modFiles.get(IModFile.Type.LANGPROVIDER)); BackgroundScanHandler backgroundScanHandler = new BackgroundScanHandler(); - final List mods = modFiles.getOrDefault(ModFile.Type.MOD, Collections.emptyList()); + final List mods = modFiles.getOrDefault(IModFile.Type.MOD, Collections.emptyList()); final List brokenFiles = new ArrayList<>(); for (Iterator iterator = mods.iterator(); iterator.hasNext(); ) { @@ -122,7 +125,7 @@ public class ModDiscoverer { } @Override - public List scanMods() { + public List scanMods() { return Collections.singletonList(new ModFile(mcJar, this)); } @@ -132,7 +135,7 @@ public class ModDiscoverer { } @Override - public Path findPath(final ModFile modFile, final String... path) { + public Path findPath(final IModFile modFile, final String... path) { String[] newPath = Arrays.copyOf(path, path.length); if (path.length == 2 && Objects.equals(path[1], "mods.toml")) { final URI jarFileURI; @@ -152,7 +155,7 @@ public class ModDiscoverer { return findPathJar(modFile, path); } - private Path findPathDirectory(final ModFile modFile, final String... path) { + private Path findPathDirectory(final IModFile modFile, final String... path) { if (path.length < 1) { throw new IllegalArgumentException("Missing path"); } @@ -161,11 +164,11 @@ public class ModDiscoverer { return mcJar.resolve(target); } - private Path findPathJar(final ModFile modFile, final String... path) { + private Path findPathJar(final IModFile modFile, final String... path) { return fileSystem.getPath(path[0], Arrays.copyOfRange(path, 1, path.length)); } @Override - public void scanFile(final ModFile modFile, final Consumer pathConsumer) { + public void scanFile(final IModFile modFile, final Consumer pathConsumer) { LOGGER.debug(SCAN,"Scan started: {}", modFile); Path path; if (Files.isDirectory(mcJar)) @@ -191,7 +194,7 @@ public class ModDiscoverer { } @Override - public boolean isValid(final ModFile modFile) { + public boolean isValid(final IModFile modFile) { return true; } } diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java index 2b4a2cee4..e1a925e1e 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java @@ -25,6 +25,8 @@ import net.minecraftforge.forgespi.language.IModInfo; import net.minecraftforge.forgespi.language.ModFileScanData; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.forgespi.language.IModLanguageProvider; +import net.minecraftforge.forgespi.locating.IModFile; +import net.minecraftforge.forgespi.locating.IModLocator; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -44,8 +46,7 @@ import java.util.jar.Manifest; import static net.minecraftforge.fml.loading.LogMarkers.LOADING; import static net.minecraftforge.fml.loading.LogMarkers.SCAN; -public class ModFile -{ +public class ModFile implements IModFile { private static final Manifest DEFAULTMANIFEST; private static final Logger LOGGER = LogManager.getLogger(); @@ -64,11 +65,13 @@ public class ModFile this.fileProperties = fileProperties; } + @Override public IModLanguageProvider getLoader() { return loader; } + @Override public Path findResource(String className) { return locator.findPath(this, className); @@ -78,9 +81,6 @@ public class ModFile this.loader = FMLLoader.getLanguageLoadingProvider().findLanguage(this, this.modFileInfo.getModLoader(), this.modFileInfo.getModLoaderVersion()); } - public enum Type { - MOD, LIBRARY, LANGPROVIDER - } private final Path filePath; private final Type modFileType; private final Manifest manifest; @@ -104,17 +104,21 @@ public class ModFile jarVersion = Optional.ofNullable(manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION)).orElse("NONE"); } + @Override public Supplier> getSubstitutionMap() { return () -> ImmutableMap.builder().put("jarVersion", jarVersion).putAll(fileProperties).build(); } + @Override public Type getType() { return modFileType; } + @Override public Path getFilePath() { return filePath; } + @Override public List getModInfos() { return modFileInfo.getMods(); } @@ -122,6 +126,7 @@ public class ModFile public Optional getAccessTransformer() { return Optional.ofNullable(Files.exists(accessTransformer) ? accessTransformer : null); } + public boolean identifyMods() { this.modFileInfo = ModFileParser.readModList(this); if (this.modFileInfo == null) return false; @@ -132,7 +137,6 @@ public class ModFile return true; } - public List getCoreMods() { return coreMods; } @@ -147,11 +151,13 @@ public class ModFile public void scanFile(Consumer pathConsumer) { locator.scanFile(this, pathConsumer); } + public void setFutureScanResult(CompletableFuture future) { this.futureScanResult = future; } + @Override public ModFileScanData getScanResult() { if (this.futureScanResult != null) { try { @@ -179,14 +185,17 @@ public class ModFile return "Mod File: " + Objects.toString(this.filePath); } + @Override public String getFileName() { return getFilePath().getFileName().toString(); } + @Override public IModLocator getLocator() { return locator; } + @Override public IModFileInfo getModFileInfo() { return modFileInfo; } diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModsFolderLocator.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModsFolderLocator.java index e361c9b58..4b4d679ca 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModsFolderLocator.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModsFolderLocator.java @@ -22,6 +22,7 @@ package net.minecraftforge.fml.loading.moddiscovery; import net.minecraftforge.fml.loading.ModDirTransformerDiscoverer; import net.minecraftforge.fml.loading.StringUtils; import net.minecraftforge.fml.loading.FMLPaths; +import net.minecraftforge.forgespi.locating.IModFile; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -53,7 +54,7 @@ public class ModsFolderLocator extends AbstractJarFileLocator { } @Override - public List scanMods() { + public List scanMods() { LOGGER.debug(SCAN,"Scanning mods dir {} for mods", this.modFolder); List excluded = new ModDirTransformerDiscoverer().candidates(FMLPaths.GAMEDIR.get()); return uncheck(()-> Files.list(this.modFolder)). diff --git a/src/fmllauncher/resources/META-INF/services/net.minecraftforge.fml.loading.moddiscovery.IModLocator b/src/fmllauncher/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator similarity index 100% rename from src/fmllauncher/resources/META-INF/services/net.minecraftforge.fml.loading.moddiscovery.IModLocator rename to src/fmllauncher/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator diff --git a/src/userdev/java/net/minecraftforge/userdev/ClasspathLocator.java b/src/userdev/java/net/minecraftforge/userdev/ClasspathLocator.java index 264bf7d46..2c7f2e74c 100644 --- a/src/userdev/java/net/minecraftforge/userdev/ClasspathLocator.java +++ b/src/userdev/java/net/minecraftforge/userdev/ClasspathLocator.java @@ -31,6 +31,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import net.minecraftforge.forgespi.locating.IModFile; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -44,7 +45,7 @@ public class ClasspathLocator extends AbstractJarFileLocator { private List modCoords; @Override - public List scanMods() { + public List scanMods() { return modCoords.stream(). map(mc -> new ModFile(mc, this)). peek(f->modJars.compute(f, (mf, fs)->createFileSystem(mf))). diff --git a/src/userdev/resources/META-INF/services/net.minecraftforge.fml.loading.moddiscovery.IModLocator b/src/userdev/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator similarity index 100% rename from src/userdev/resources/META-INF/services/net.minecraftforge.fml.loading.moddiscovery.IModLocator rename to src/userdev/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator