Peel IModLocator into the SPI package and extract a small IModFile

interface as well. This allows building external IModLocator
implementations.

Signed-off-by: cpw <cpw+github@weeksfamily.ca>
This commit is contained in:
cpw 2019-09-01 11:31:09 -04:00
parent a4aa85259e
commit 734a3d76aa
No known key found for this signature in database
GPG Key ID: 8EB3DF749553B1B7
11 changed files with 56 additions and 81 deletions

View File

@ -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'

View File

@ -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<ModFile, FileSystem> modJars;
protected final Map<IModFile, FileSystem> 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<Path> pathConsumer) {
@Override
public void scanFile(final IModFile file, final Consumer<Path> 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<Manifest> 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;
}
}

View File

@ -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<Pair<Path,List<Path>>> rootDirs;
private final Map<ModFile, Pair<Path,List<Path>>> mods;
private final Map<IModFile, Pair<Path,List<Path>>> mods;
public ExplodedDirectoryLocator() {
this.rootDirs = new ArrayList<>();
@ -44,7 +46,7 @@ public class ExplodedDirectoryLocator implements IModLocator {
}
@Override
public List<ModFile> scanMods() {
public List<IModFile> 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<Path> pathConsumer) {
public void scanFile(final IModFile modFile, final Consumer<Path> pathConsumer) {
LOGGER.debug(SCAN,"Scanning exploded directory {}", modFile.getFilePath().toString());
final Pair<Path, List<Path>> 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;
}
}

View File

@ -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<ModFile> scanMods();
String name();
Path findPath(ModFile modFile, String... path);
void scanFile(final ModFile modFile, Consumer<Path> pathConsumer);
Optional<Manifest> findManifest(Path file);
void initArguments(Map<String, ?> arguments);
boolean isValid(ModFile modFile);
}

View File

@ -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<Path> modCoords;
@Override
public List<ModFile> scanMods() {
return modCoords.stream().
map(mc -> new ModFile(mc, this)).
peek(f->modJars.compute(f, (mf, fs)->createFileSystem(mf))).
collect(Collectors.toList());
public List<IModFile> scanMods() {
return modCoords.stream()
.map(mc -> new ModFile(mc, this))
.peek(f->modJars.compute(f, (mf, fs)->createFileSystem(mf)))
.collect(Collectors.toList());
}
@Override

View File

@ -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<ModFile.Type, List<ModFile>> modFiles = locatorList.stream()
final Map<IModFile.Type, List<ModFile>> 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<ModFile> mods = modFiles.getOrDefault(ModFile.Type.MOD, Collections.emptyList());
final List<ModFile> mods = modFiles.getOrDefault(IModFile.Type.MOD, Collections.emptyList());
final List<ModFile> brokenFiles = new ArrayList<>();
for (Iterator<ModFile> iterator = mods.iterator(); iterator.hasNext(); )
{
@ -122,7 +125,7 @@ public class ModDiscoverer {
}
@Override
public List<ModFile> scanMods() {
public List<IModFile> 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<Path> pathConsumer) {
public void scanFile(final IModFile modFile, final Consumer<Path> 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;
}
}

View File

@ -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<Map<String,Object>> getSubstitutionMap() {
return () -> ImmutableMap.<String,Object>builder().put("jarVersion", jarVersion).putAll(fileProperties).build();
}
@Override
public Type getType() {
return modFileType;
}
@Override
public Path getFilePath() {
return filePath;
}
@Override
public List<IModInfo> getModInfos() {
return modFileInfo.getMods();
}
@ -122,6 +126,7 @@ public class ModFile
public Optional<Path> 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<CoreModFile> getCoreMods() {
return coreMods;
}
@ -147,11 +151,13 @@ public class ModFile
public void scanFile(Consumer<Path> pathConsumer) {
locator.scanFile(this, pathConsumer);
}
public void setFutureScanResult(CompletableFuture<ModFileScanData> 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;
}

View File

@ -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<ModFile> scanMods() {
public List<IModFile> scanMods() {
LOGGER.debug(SCAN,"Scanning mods dir {} for mods", this.modFolder);
List<Path> excluded = new ModDirTransformerDiscoverer().candidates(FMLPaths.GAMEDIR.get());
return uncheck(()-> Files.list(this.modFolder)).

View File

@ -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<Path> modCoords;
@Override
public List<ModFile> scanMods() {
public List<IModFile> scanMods() {
return modCoords.stream().
map(mc -> new ModFile(mc, this)).
peek(f->modJars.compute(f, (mf, fs)->createFileSystem(mf))).