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:
parent
a4aa85259e
commit
734a3d76aa
11 changed files with 56 additions and 81 deletions
|
@ -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'
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)).
|
||||
|
|
|
@ -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))).
|
||||
|
|
Loading…
Reference in a new issue