From 20f78ac724164110d80c30a19473ee0bc1d2ecc1 Mon Sep 17 00:00:00 2001 From: cpw Date: Tue, 23 Jun 2020 22:12:39 -0400 Subject: [PATCH] Modify how modfiles load slightly, for better decoupling. Signed-off-by: cpw --- build.gradle | 2 +- .../fml/loading/FMLServiceProvider.java | 2 + .../ExplodedDirectoryLocator.java | 2 +- .../moddiscovery/MavenDirectoryLocator.java | 2 +- .../loading/moddiscovery/ModDiscoverer.java | 2 +- .../fml/loading/moddiscovery/ModFile.java | 63 ++++--- .../fml/loading/moddiscovery/ModFileInfo.java | 56 +++--- .../loading/moddiscovery/ModFileParser.java | 19 +- .../fml/loading/moddiscovery/ModInfo.java | 172 +++++++++++++----- .../moddiscovery/ModsFolderLocator.java | 2 +- .../moddiscovery/NightConfigWrapper.java | 45 +++++ .../fml/client/gui/screen/ModListScreen.java | 6 +- .../userdev/ClasspathLocator.java | 2 +- 13 files changed, 261 insertions(+), 114 deletions(-) create mode 100644 src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/NightConfigWrapper.java diff --git a/build.gradle b/build.gradle index 96c4c838a..3c0c9643a 100644 --- a/build.gradle +++ b/build.gradle @@ -439,7 +439,7 @@ project(':forge') { installer 'cpw.mods:grossjava9hacks:1.3.+' installer 'net.minecraftforge:accesstransformers:2.1.+:shadowed' installer 'net.minecraftforge:eventbus:2.2.+:service' - installer 'net.minecraftforge:forgespi:2.1.+' + installer 'net.minecraftforge:forgespi:3.0.+' installer 'net.minecraftforge:coremods:2.0.+' installer 'net.minecraftforge:unsafe:0.2.+' installer 'com.electronwill.night-config:core:3.6.2' diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLServiceProvider.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLServiceProvider.java index e9ca608f4..ef7ceac72 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLServiceProvider.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/FMLServiceProvider.java @@ -79,6 +79,8 @@ public class FMLServiceProvider implements ITransformationService FMLPaths.setup(environment); LOGGER.debug(CORE, "Loading configuration"); FMLConfig.load(); + LOGGER.debug(CORE, "Preparing ModFile"); + environment.computePropertyIfAbsent(Environment.Keys.MODFILEFACTORY.get(), k->ModFile.buildFactory()); arguments = new HashMap<>(); arguments.put("modLists", modListsArgumentList); arguments.put("mods", modsArgumentList); 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 50f7aa81a..15ccf0df3 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ExplodedDirectoryLocator.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ExplodedDirectoryLocator.java @@ -54,7 +54,7 @@ public class ExplodedDirectoryLocator implements IModLocator { Path modtoml = resources.resolve(modstoml); if (Files.exists(modtoml)) { LOGGER.debug(LOADING, "Found exploded directory mod manifest at {}", modtoml.toString()); - ModFile mf = new ModFile(pathPathPair.getLeft(), this); + ModFile mf = ModFile.newFMLInstance(pathPathPair.getLeft(), this); mods.put(mf, pathPathPair); } else { LOGGER.warn(LOADING, "Failed to find exploded resource mods.toml in directory {}", resources.toString()); 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 6eba075d8..9cc163a05 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/MavenDirectoryLocator.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/MavenDirectoryLocator.java @@ -36,7 +36,7 @@ public class MavenDirectoryLocator extends AbstractJarFileLocator { @Override public List scanMods() { return modCoords.stream() - .map(mc -> new ModFile(mc, this)) + .map(mc -> ModFile.newFMLInstance(mc, this)) .peek(f->modJars.compute(f, (mf, fs)->createFileSystem(mf))) .collect(Collectors.toList()); } 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 55ef0fef6..0b63af6ea 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.java @@ -158,7 +158,7 @@ public class ModDiscoverer { @Override public List scanMods() { - return Collections.singletonList(new ModFile(mcJar, this)); + return Collections.singletonList(ModFile.newFMLInstance(mcJar, this)); } @Override 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 122c4c75a..bac5261c6 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFile.java @@ -21,13 +21,15 @@ package net.minecraftforge.fml.loading.moddiscovery; import com.google.common.collect.ImmutableMap; import net.minecraftforge.fml.loading.progress.StartupMessageManager; +import net.minecraftforge.forgespi.Environment; +import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.forgespi.language.IModFileInfo; 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.language.ModFileScanData; import net.minecraftforge.forgespi.locating.IModFile; import net.minecraftforge.forgespi.locating.IModLocator; +import net.minecraftforge.forgespi.locating.ModFileFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -57,31 +59,10 @@ public class ModFile implements IModFile { } private final String jarVersion; + private final ModFileFactory.ModFileInfoParser parser; private Map fileProperties; private IModLanguageProvider loader; private Throwable scanError; - - public void setFileProperties(Map fileProperties) - { - this.fileProperties = fileProperties; - } - - @Override - public IModLanguageProvider getLoader() - { - return loader; - } - - @Override - public Path findResource(String className) - { - return locator.findPath(this, className); - } - - public void identifyLanguage() { - this.loader = FMLLoader.getLanguageLoadingProvider().findLanguage(this, this.modFileInfo.getModLoader(), this.modFileInfo.getModLoaderVersion()); - } - private final Path filePath; private final Type modFileType; private final Manifest manifest; @@ -94,9 +75,10 @@ public class ModFile implements IModFile { public static final Attributes.Name TYPE = new Attributes.Name("FMLModType"); - public ModFile(final Path file, final IModLocator locator) { + public ModFile(final Path file, final IModLocator locator, final ModFileFactory.ModFileInfoParser parser) { this.locator = locator; this.filePath = file; + this.parser = parser; manifest = locator.findManifest(file).orElse(DEFAULTMANIFEST); if (manifest != DEFAULTMANIFEST) LOGGER.debug(SCAN,"Mod file {} has a manifest", file); else LOGGER.debug(SCAN,"Mod file {} is missing a manifest", file); @@ -129,7 +111,7 @@ public class ModFile implements IModFile { } public boolean identifyMods() { - this.modFileInfo = ModFileParser.readModList(this); + this.modFileInfo = ModFileParser.readModList(this, this.parser); if (this.modFileInfo == null) return false; LOGGER.debug(LOADING,"Loading mod file {} with language {}", this.getFilePath(), this.modFileInfo.getModLoader()); this.coreMods = ModFileParser.getCoreMods(this); @@ -182,6 +164,27 @@ public class ModFile implements IModFile { StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Completed deep scan of "+this.getFileName())); } + public void setFileProperties(Map fileProperties) + { + this.fileProperties = fileProperties; + } + + @Override + public IModLanguageProvider getLoader() + { + return loader; + } + + @Override + public Path findResource(String className) + { + return locator.findPath(this, className); + } + + public void identifyLanguage() { + this.loader = FMLLoader.getLanguageLoadingProvider().findLanguage(this, this.modFileInfo.getModLoader(), this.modFileInfo.getModLoaderVersion()); + } + @Override public String toString() { return "Mod File: " + Objects.toString(this.filePath); @@ -201,4 +204,12 @@ public class ModFile implements IModFile { public IModFileInfo getModFileInfo() { return modFileInfo; } + + public static ModFileFactory buildFactory() { + return ModFile::new; + } + + public static ModFile newFMLInstance(final Path path, final IModLocator locator) { + return (ModFile) ModFileFactory.FACTORY.build(path, locator, ModFileParser::modsTomlParser); + } } diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java index ccf131359..5b99e02c4 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileInfo.java @@ -20,25 +20,30 @@ package net.minecraftforge.fml.loading.moddiscovery; import com.electronwill.nightconfig.core.UnmodifiableConfig; -import net.minecraftforge.forgespi.language.MavenVersionAdapter; +import net.minecraftforge.fml.loading.StringUtils; +import net.minecraftforge.forgespi.language.IConfigurable; import net.minecraftforge.forgespi.language.IModFileInfo; import net.minecraftforge.forgespi.language.IModInfo; -import net.minecraftforge.fml.loading.StringUtils; +import net.minecraftforge.forgespi.language.MavenVersionAdapter; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.maven.artifact.versioning.VersionRange; import java.net.URL; -import java.util.*; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; import java.util.jar.Manifest; import java.util.stream.Collectors; import static net.minecraftforge.fml.loading.LogMarkers.LOADING; -public class ModFileInfo implements IModFileInfo +public class ModFileInfo implements IModFileInfo, IConfigurable { private static final Logger LOGGER = LogManager.getLogger(); - private final UnmodifiableConfig config; + private final IConfigurable config; private final ModFile modFile; private final URL issueURL; private final String modLoader; @@ -47,32 +52,31 @@ public class ModFileInfo implements IModFileInfo private final List mods; private final Map properties; - ModFileInfo(final ModFile modFile, final UnmodifiableConfig config) + ModFileInfo(final ModFile modFile, final IConfigurable config) { this.modFile = modFile; this.config = config; - this.modLoader = config.getOptional("modLoader"). + this.modLoader = config.getConfigElement("modLoader"). orElseThrow(()->new InvalidModFileException("Missing ModLoader in file", this)); - this.modLoaderVersion = config.getOptional("loaderVersion"). + this.modLoaderVersion = config.getConfigElement("loaderVersion"). map(MavenVersionAdapter::createFromVersionSpec). orElseThrow(()->new InvalidModFileException("Missing ModLoader version in file", this)); - this.showAsResourcePack = config.getOrElse("showAsResourcePack", false); - this.properties = config.getOptional("properties"). + this.showAsResourcePack = config.getConfigElement("showAsResourcePack").orElse(false); + this.properties = config.getConfigElement("properties"). map(UnmodifiableConfig::valueMap).orElse(Collections.emptyMap()); this.modFile.setFileProperties(this.properties); - if (config.contains("mods") && !(config.get("mods") instanceof Collection)) { - throw new InvalidModFileException("Mods list is not a list.", this); - } - final ArrayList modConfigs = config.getOrElse("mods", ArrayList::new); + this.issueURL = config.getConfigElement("issueTrackerURL").map(StringUtils::toURL).orElse(null); + final List modConfigs = config.getConfigList("mods"); if (modConfigs.isEmpty()) { throw new InvalidModFileException("Missing mods list", this); } - this.mods = modConfigs.stream().map(mi-> new ModInfo(this, mi)).collect(Collectors.toList()); - this.issueURL = config.getOptional("issueTrackerURL").map(StringUtils::toURL).orElse(null); + this.mods = modConfigs.stream() + .map(mi-> new ModInfo(this, mi)) + .collect(Collectors.toList()); LOGGER.debug(LOADING, "Found valid mod file {} with {} mods - versions {}", this.modFile::getFileName, - () -> mods.stream().map(IModInfo::getModId).collect(Collectors.joining(",", "{", "}")), - () -> mods.stream().map(IModInfo::getVersion).map(Objects::toString).collect(Collectors.joining(",", "{", "}"))); + () -> this.mods.stream().map(IModInfo::getModId).collect(Collectors.joining(",", "{", "}")), + () -> this.mods.stream().map(IModInfo::getVersion).map(Objects::toString).collect(Collectors.joining(",", "{", "}"))); } @Override @@ -86,12 +90,6 @@ public class ModFileInfo implements IModFileInfo return this.modFile; } - @Override - public UnmodifiableConfig getConfig() - { - return this.config; - } - @Override public String getModLoader() { @@ -117,4 +115,14 @@ public class ModFileInfo implements IModFileInfo public boolean showAsResourcePack() { return this.showAsResourcePack; } + + @Override + public Optional getConfigElement(final String... key) { + return this.config.getConfigElement(key); + } + + @Override + public List getConfigList(final String... key) { + return this.config.getConfigList(key); + } } diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java index 6f59590f2..6264da0c6 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModFileParser.java @@ -23,6 +23,8 @@ import com.electronwill.nightconfig.core.file.FileConfig; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import net.minecraftforge.forgespi.language.IModFileInfo; +import net.minecraftforge.forgespi.locating.IModFile; +import net.minecraftforge.forgespi.locating.ModFileFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -38,25 +40,28 @@ import java.util.stream.Collectors; import static net.minecraftforge.fml.loading.LogMarkers.LOADING; public class ModFileParser { - private static final Logger LOGGER = LogManager.getLogger(); - public static IModFileInfo readModList(final ModFile modFile) { + public static IModFileInfo readModList(final ModFile modFile, final ModFileFactory.ModFileInfoParser parser) { + return parser.build(modFile); + } + + public static IModFileInfo modsTomlParser(final IModFile imodFile) { + ModFile modFile = (ModFile) imodFile; LOGGER.debug(LOADING,"Considering mod file candidate {}", modFile.getFilePath()); final Path modsjson = modFile.getLocator().findPath(modFile, "META-INF", "mods.toml"); if (!Files.exists(modsjson)) { LOGGER.warn(LOADING, "Mod file {} is missing mods.toml file", modFile); return null; } - return loadModFile(modFile, modsjson); - } - public static IModFileInfo loadModFile(final ModFile file, final Path modsjson) - { final FileConfig fileConfig = FileConfig.builder(modsjson).build(); fileConfig.load(); fileConfig.close(); - return new ModFileInfo(file, fileConfig); + final NightConfigWrapper configWrapper = new NightConfigWrapper(fileConfig); + final ModFileInfo modFileInfo = new ModFileInfo(modFile, configWrapper); + configWrapper.setFile(modFileInfo); + return modFileInfo; } protected static List getCoreMods(final ModFile modFile) { diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java index 420e709da..ca4ef3c1a 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java @@ -19,13 +19,18 @@ package net.minecraftforge.fml.loading.moddiscovery; -import com.electronwill.nightconfig.core.UnmodifiableConfig; -import net.minecraftforge.fml.loading.StringUtils; -import net.minecraftforge.forgespi.language.IModInfo; import net.minecraftforge.fml.loading.StringSubstitutor; +import net.minecraftforge.fml.loading.StringUtils; +import net.minecraftforge.forgespi.language.IConfigurable; +import net.minecraftforge.forgespi.language.IModInfo; +import net.minecraftforge.forgespi.language.MavenVersionAdapter; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; +import org.apache.maven.artifact.versioning.VersionRange; import java.net.URL; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -33,12 +38,7 @@ import java.util.Optional; import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.maven.artifact.versioning.ArtifactVersion; -import org.apache.maven.artifact.versioning.DefaultArtifactVersion; - -public class ModInfo implements IModInfo +public class ModInfo implements IModInfo, IConfigurable { private static final Logger LOGGER = LogManager.getLogger(); private static final DefaultArtifactVersion DEFAULT_VERSION = new DefaultArtifactVersion("1"); @@ -53,50 +53,51 @@ public class ModInfo implements IModInfo private final Optional logoFile; private final boolean logoBlur; private final URL updateJSONURL; - private final List dependencies; + private final List dependencies; private final Map properties; - private final UnmodifiableConfig modConfig; + private final IConfigurable config; - public ModInfo(final ModFileInfo owningFile, final UnmodifiableConfig modConfig) + public ModInfo(final ModFileInfo owningFile, final IConfigurable config) { + Optional ownFile = Optional.ofNullable(owningFile); this.owningFile = owningFile; - this.modConfig = modConfig; - this.modId = modConfig.getOptional("modId").orElseThrow(() -> new InvalidModFileException("Missing modId entry", owningFile)); + this.config = config; + this.modId = config.getConfigElement("modId") + .orElseThrow(() -> new InvalidModFileException("Missing modId", owningFile)); if (!VALID_LABEL.matcher(this.modId).matches()) { LOGGER.fatal("Invalid modId found in file {} - {} does not match the standard: {}", this.owningFile.getFile().getFilePath(), this.modId, VALID_LABEL.pattern()); - throw new InvalidModFileException("Invalid modId found : "+ this.modId, owningFile); + throw new InvalidModFileException("Invalid modId found : " + this.modId, owningFile); } - this.namespace = modConfig.getOptional("namespace").orElse(this.modId); + this.namespace = config.getConfigElement("namespace").orElse(this.modId); if (!VALID_LABEL.matcher(this.namespace).matches()) { LOGGER.fatal("Invalid override namespace found in file {} - {} does not match the standard: {}", this.owningFile.getFile().getFilePath(), this.namespace, VALID_LABEL.pattern()); - throw new InvalidModFileException("Invalid override namespace found : "+ this.namespace, owningFile); + throw new InvalidModFileException("Invalid override namespace found : " + this.namespace, owningFile); } - this.version = modConfig.getOptional("version"). - map(s->StringSubstitutor.replace(s, owningFile != null ? owningFile.getFile() : null )). - map(DefaultArtifactVersion::new).orElse(DEFAULT_VERSION); - this.displayName = modConfig.getOptional("displayName").orElse(this.modId); - this.description = modConfig.get("description"); + this.version = config.getConfigElement("version") + .map(s -> StringSubstitutor.replace(s, ownFile.map(ModFileInfo::getFile).orElse(null))) + .map(DefaultArtifactVersion::new).orElse(DEFAULT_VERSION); + this.displayName = config.getConfigElement("displayName").orElse(this.modId); + this.description = config.getConfigElement("description").orElse("MISSING DESCRIPTION"); - Optional tmp = modConfig.getOptional("logoFile"); - if (!tmp.isPresent() && this.owningFile != null) { - tmp = this.owningFile.getConfig().getOptional("logoFile"); - } - this.logoFile = tmp; - this.logoBlur = modConfig.getOptional("logoBlur"). - orElseGet(() -> Optional.ofNullable(this.owningFile). - flatMap(f -> f.getConfig().getOptional("logoBlur")). - orElse(true)); + this.logoFile = Optional.ofNullable(config.getConfigElement("logoFile") + .orElseGet(() -> ownFile.flatMap(mf -> mf.getConfigElement("logoFile")).orElse(null))); + this.logoBlur = config.getConfigElement("logoBlur") + .orElseGet(() -> ownFile.flatMap(f -> f.getConfigElement("logoBlur")) + .orElse(true)); - this.updateJSONURL = modConfig.getOptional("updateJSONURL").map(StringUtils::toURL).orElse(null); - if (owningFile != null) { - this.dependencies = owningFile.getConfig().>getOptional(Arrays.asList("dependencies", this.modId)). - orElse(Collections.emptyList()).stream().map(dep -> new ModVersion(this, dep)).collect(Collectors.toList()); - this.properties = owningFile.getConfig().getOptional(Arrays.asList("modproperties", this.modId)). - map(UnmodifiableConfig::valueMap).orElse(Collections.emptyMap()); - } else { - this.dependencies = Collections.emptyList(); - this.properties = Collections.emptyMap(); - } + this.updateJSONURL = config.getConfigElement("updateJSONURL") + .map(StringUtils::toURL) + .orElse(null); + + this.dependencies = ownFile.map(mfi -> mfi.getConfigList("dependencies", this.modId) + .stream() + .map(dep -> new ModVersion(this, dep)) + .collect(Collectors.toList())) + .orElse(Collections.emptyList()); + + this.properties = ownFile.map(mfi -> mfi.>getConfigElement("modproperties", this.modId) + .orElse(Collections.emptyMap())) + .orElse(Collections.emptyMap()); } @Override @@ -127,15 +128,10 @@ public class ModInfo implements IModInfo } @Override - public List getDependencies() { + public List getDependencies() { return this.dependencies; } - @Override - public UnmodifiableConfig getModConfig() { - return this.modConfig; - } - @Override public String getNamespace() { return this.namespace; @@ -169,4 +165,84 @@ public class ModInfo implements IModInfo { return false; } + + @Override + public Optional getConfigElement(final String... key) { + return this.config.getConfigElement(key); + } + + @Override + public List getConfigList(final String... key) { + return null; + } + + class ModVersion implements net.minecraftforge.forgespi.language.IModInfo.ModVersion { + private IModInfo owner; + private final String modId; + private final VersionRange versionRange; + private final boolean mandatory; + private final Ordering ordering; + private final DependencySide side; + + public ModVersion(final IModInfo owner, final IConfigurable config) { + this.owner = owner; + this.modId = config.getConfigElement("modId") + .orElseThrow(()->new InvalidModFileException("Missing required field modid in dependency", getOwningFile())); + this.mandatory = config.getConfigElement("mandatory") + .orElseThrow(()->new InvalidModFileException("Missing required field mandatory in dependency", getOwningFile())); + this.versionRange = config.getConfigElement("versionRange") + .map(MavenVersionAdapter::createFromVersionSpec) + .orElse(UNBOUNDED); + this.ordering = config.getConfigElement("ordering") + .map(Ordering::valueOf) + .orElse(Ordering.NONE); + this.side = config.getConfigElement("side") + .map(DependencySide::valueOf) + .orElse(DependencySide.BOTH); + } + + + @Override + public String getModId() + { + return modId; + } + + @Override + public VersionRange getVersionRange() + { + return versionRange; + } + + @Override + public boolean isMandatory() + { + return mandatory; + } + + @Override + public Ordering getOrdering() + { + return ordering; + } + + @Override + public DependencySide getSide() + { + return side; + } + + @Override + public void setOwner(final IModInfo owner) + { + this.owner = owner; + } + + @Override + public IModInfo getOwner() + { + return owner; + } + } + } 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 1e3257e2e..5ce28a84a 100644 --- a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModsFolderLocator.java +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/ModsFolderLocator.java @@ -65,7 +65,7 @@ public class ModsFolderLocator extends AbstractJarFileLocator { .filter(p->!excluded.contains(p)) .sorted(Comparator.comparing(path-> StringUtils.toLowerCase(path.getFileName().toString()))) .filter(p->StringUtils.toLowerCase(p.getFileName().toString()).endsWith(SUFFIX)) - .map(p->new ModFile(p, this)) + .map(p->ModFile.newFMLInstance(p, this)) .peek(f->modJars.compute(f, (mf, fs)->createFileSystem(mf))) .collect(Collectors.toList()); } diff --git a/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/NightConfigWrapper.java b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/NightConfigWrapper.java new file mode 100644 index 000000000..12bd134a6 --- /dev/null +++ b/src/fmllauncher/java/net/minecraftforge/fml/loading/moddiscovery/NightConfigWrapper.java @@ -0,0 +1,45 @@ +package net.minecraftforge.fml.loading.moddiscovery; + +import com.electronwill.nightconfig.core.UnmodifiableConfig; +import net.minecraftforge.forgespi.language.IConfigurable; +import net.minecraftforge.forgespi.language.IModFileInfo; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static java.util.Arrays.asList; + +public class NightConfigWrapper implements IConfigurable { + private final UnmodifiableConfig config; + private IModFileInfo file; + + public NightConfigWrapper(final UnmodifiableConfig config) { + this.config = config; + } + + NightConfigWrapper setFile(IModFileInfo file) { + this.file = file; + return this; + } + + @Override + public Optional getConfigElement(final String... key) { + return this.config.getOptional(asList(key)); + } + + @Override + public List getConfigList(final String... key) { + final List path = asList(key); + if (this.config.contains(path) && !(this.config.get(path) instanceof Collection)) { + throw new InvalidModFileException("The configuration path "+path+" is invalid. Expecting a collection!", file); + } + final ArrayList nestedConfigs = this.config.getOrElse(path, ArrayList::new); + return nestedConfigs.stream() + .map(NightConfigWrapper::new) + .map(cw->cw.setFile(file)) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/net/minecraftforge/fml/client/gui/screen/ModListScreen.java b/src/main/java/net/minecraftforge/fml/client/gui/screen/ModListScreen.java index 62ff42ecd..bac0083fd 100644 --- a/src/main/java/net/minecraftforge/fml/client/gui/screen/ModListScreen.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/screen/ModListScreen.java @@ -454,11 +454,11 @@ public class ModListScreen extends Screen lines.add(ForgeI18n.parseMessage("fml.menu.mods.info.idstate", selectedMod.getModId(), ModList.get().getModContainerById(selectedMod.getModId()). map(ModContainer::getCurrentState).map(Object::toString).orElse("NONE"))); - selectedMod.getModConfig().getOptional("credits").ifPresent(credits-> + selectedMod.getConfigElement("credits").ifPresent(credits-> lines.add(ForgeI18n.parseMessage("fml.menu.mods.info.credits", credits))); - selectedMod.getModConfig().getOptional("authors").ifPresent(authors -> + selectedMod.getConfigElement("authors").ifPresent(authors -> lines.add(ForgeI18n.parseMessage("fml.menu.mods.info.authors", authors))); - selectedMod.getModConfig().getOptional("displayURL").ifPresent(displayURL -> + selectedMod.getConfigElement("displayURL").ifPresent(displayURL -> lines.add(ForgeI18n.parseMessage("fml.menu.mods.info.displayurl", displayURL))); if (selectedMod.getOwningFile() == null || selectedMod.getOwningFile().getMods().size()==1) lines.add(ForgeI18n.parseMessage("fml.menu.mods.info.nochildmods")); diff --git a/src/userdev/java/net/minecraftforge/userdev/ClasspathLocator.java b/src/userdev/java/net/minecraftforge/userdev/ClasspathLocator.java index 824ab8a3c..d7d861321 100644 --- a/src/userdev/java/net/minecraftforge/userdev/ClasspathLocator.java +++ b/src/userdev/java/net/minecraftforge/userdev/ClasspathLocator.java @@ -52,7 +52,7 @@ public class ClasspathLocator extends AbstractJarFileLocator { @Override public List scanMods() { return modCoords.stream(). - map(mc -> new ModFile(mc, this)). + map(mc -> ModFile.newFMLInstance(mc, this)). peek(f->modJars.compute(f, (mf, fs)->createFileSystem(mf))). collect(Collectors.toList()); }