diff --git a/loader/build.gradle b/loader/build.gradle index 2a52ef74c..6bef80531 100644 --- a/loader/build.gradle +++ b/loader/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'net.neoforged.jarcompatibilitychecker' version '0.1.3' + id 'net.neoforged.jarcompatibilitychecker' version '0.1.13' } checkJarCompatibility { diff --git a/loader/src/main/java/net/neoforged/fml/loading/LoadingModList.java b/loader/src/main/java/net/neoforged/fml/loading/LoadingModList.java index 4df143958..f5b962253 100644 --- a/loader/src/main/java/net/neoforged/fml/loading/LoadingModList.java +++ b/loader/src/main/java/net/neoforged/fml/loading/LoadingModList.java @@ -5,6 +5,7 @@ package net.neoforged.fml.loading; +import com.mojang.logging.LogUtils; import cpw.mods.modlauncher.api.LambdaExceptionUtils; import java.net.URL; import java.nio.file.Files; @@ -24,16 +25,19 @@ import net.neoforged.fml.loading.mixin.DeferredMixinConfigRegistration; import net.neoforged.fml.loading.moddiscovery.ModFile; import net.neoforged.fml.loading.moddiscovery.ModFileInfo; +import net.neoforged.fml.loading.moddiscovery.ModFileParser; import net.neoforged.fml.loading.moddiscovery.ModInfo; import net.neoforged.fml.loading.modscan.BackgroundScanHandler; import net.neoforged.neoforgespi.language.IModFileInfo; import net.neoforged.neoforgespi.language.IModInfo; +import org.slf4j.Logger; /** * Master list of all mods in the loading context. This class cannot refer outside the * loading package */ public class LoadingModList { + private static final Logger LOGGER = LogUtils.getLogger(); private static LoadingModList INSTANCE; private final List plugins; private final List modFiles; @@ -77,7 +81,13 @@ public void addMixinConfigs() { .map(ModFileInfo::getFile) .forEach(file -> { final String modId = file.getModInfos().get(0).getModId(); - file.getMixinConfigs().forEach(cfg -> DeferredMixinConfigRegistration.addMixinConfig(cfg, modId)); + for (ModFileParser.MixinConfig potential : file.getMixinConfigs()) { + if (potential.requiredMods().stream().allMatch(id -> this.getModFileById(id) != null)) { + DeferredMixinConfigRegistration.addMixinConfig(potential.config(), modId); + } else { + LOGGER.debug("Mixin config {} for mod {} not applied as required mods are missing", potential.config(), modId); + } + } }); } diff --git a/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFile.java b/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFile.java index 388d0834b..114c1a968 100644 --- a/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFile.java +++ b/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFile.java @@ -56,7 +56,7 @@ public class ModFile implements IModFile { private ModFileScanData fileModFileScanData; private volatile CompletableFuture futureScanResult; private List coreMods; - private List mixinConfigs; + private List mixinConfigs; private List accessTransformers; public static final Attributes.Name TYPE = new Attributes.Name("FMLModType"); @@ -135,7 +135,7 @@ public List getCoreMods() { return coreMods; } - public List getMixinConfigs() { + public List getMixinConfigs() { return mixinConfigs; } diff --git a/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFileParser.java b/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFileParser.java index 2bfb74d1f..96e41f4b5 100644 --- a/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFileParser.java +++ b/loader/src/main/java/net/neoforged/fml/loading/moddiscovery/ModFileParser.java @@ -16,12 +16,14 @@ import java.lang.reflect.Type; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; import net.neoforged.fml.loading.LogMarkers; import net.neoforged.fml.loading.moddiscovery.readers.JarModsDotTomlModFileReader; +import net.neoforged.neoforgespi.language.IConfigurable; import net.neoforged.neoforgespi.language.IModFileInfo; import net.neoforged.neoforgespi.locating.IModFile; import net.neoforged.neoforgespi.locating.InvalidModFileException; @@ -85,17 +87,28 @@ protected static List getCoreMods(final ModFile modFile) { .toList(); } - protected static List getMixinConfigs(IModFileInfo modFileInfo) { + /** + * Represents a potential mixin configuration. + * + * @param config The name of the mixin configuration. + * @param requiredMods The mod ids that are required for this mixin configuration to be loaded. If empty, will be loaded regardless. + */ + public record MixinConfig(String config, List requiredMods) {} + + protected static List getMixinConfigs(IModFileInfo modFileInfo) { try { var config = modFileInfo.getConfig(); var mixinsEntries = config.getConfigList("mixins"); - return mixinsEntries - .stream() - .map(entry -> entry - .getConfigElement("config") - .orElseThrow( - () -> new InvalidModFileException("Missing \"config\" in [[mixins]] entry", modFileInfo))) - .toList(); + + var potentialMixins = new ArrayList(); + for (IConfigurable mixinsEntry : mixinsEntries) { + var name = mixinsEntry.getConfigElement("config") + .orElseThrow(() -> new InvalidModFileException("Missing \"config\" in [[mixins]] entry", modFileInfo)); + var requiredModIds = mixinsEntry.>getConfigElement("requiredMods").orElse(List.of()); + potentialMixins.add(new MixinConfig(name, requiredModIds)); + } + + return potentialMixins; } catch (Exception exception) { LOGGER.error("Failed to load mixin configs from mod file", exception); return List.of();