diff --git a/fml/src/main/java/cpw/mods/fml/common/discovery/ModDiscoverer.java b/fml/src/main/java/cpw/mods/fml/common/discovery/ModDiscoverer.java index 5bc49e3c2..a1fb9812d 100644 --- a/fml/src/main/java/cpw/mods/fml/common/discovery/ModDiscoverer.java +++ b/fml/src/main/java/cpw/mods/fml/common/discovery/ModDiscoverer.java @@ -85,8 +85,8 @@ public class ModDiscoverer public void findModDirMods(File modsDir) { File[] modList = FileListHelper.sortFileList(modsDir, null); - modList = FileListHelper.sortFileList(ObjectArrays.concat(modList, ModListHelper.additionalMods.toArray(new File[0]), File.class)); - + modList = FileListHelper.sortFileList(ObjectArrays.concat(modList, ModListHelper.additionalMods.values().toArray(new File[0]), File.class)); + for (File modFile : modList) { // skip loaded coremods diff --git a/fml/src/main/java/cpw/mods/fml/relauncher/CoreModManager.java b/fml/src/main/java/cpw/mods/fml/relauncher/CoreModManager.java index fe8b48a30..d30f5fe3a 100644 --- a/fml/src/main/java/cpw/mods/fml/relauncher/CoreModManager.java +++ b/fml/src/main/java/cpw/mods/fml/relauncher/CoreModManager.java @@ -52,6 +52,7 @@ import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions; public class CoreModManager { private static final Attributes.Name COREMODCONTAINSFMLMOD = new Attributes.Name("FMLCorePluginContainsFMLMod"); private static final Attributes.Name MODTYPE = new Attributes.Name("ModType"); + private static final Attributes.Name MODSIDE = new Attributes.Name("ModSide"); private static String[] rootPlugins = { "cpw.mods.fml.relauncher.FMLCorePlugin", "net.minecraftforge.classloading.FMLForgePlugin" }; private static List loadedCoremods = Lists.newArrayList(); private static List loadPlugins; @@ -250,7 +251,7 @@ public class CoreModManager { coreModList = ObjectArrays.concat(coreModList, versionedCoreMods, File.class); } - ObjectArrays.concat(coreModList, ModListHelper.additionalMods.toArray(new File[0]), File.class); + ObjectArrays.concat(coreModList, ModListHelper.additionalMods.values().toArray(new File[0]), File.class); coreModList = FileListHelper.sortFileList(coreModList); @@ -307,6 +308,13 @@ public class CoreModManager { loadedCoremods.add(coreMod.getName()); continue; } + String modSide = mfAttributes.containsKey(MODSIDE) ? mfAttributes.getValue(MODSIDE) : "BOTH"; + if (! ("BOTH".equals(modSide) || FMLLaunchHandler.side.name().equals(modSide))) + { + FMLRelaunchLog.fine("Mod %s has ModSide meta-inf value %s, and we're %s. It will be ignored", coreMod.getName(), modSide, FMLLaunchHandler.side.name()); + loadedCoremods.add(coreMod.getName()); + continue; + } String fmlCorePlugin = mfAttributes.getValue("FMLCorePlugin"); if (fmlCorePlugin == null) { diff --git a/fml/src/main/java/cpw/mods/fml/relauncher/ModListHelper.java b/fml/src/main/java/cpw/mods/fml/relauncher/ModListHelper.java index 953b6faa4..1afb9d2b3 100644 --- a/fml/src/main/java/cpw/mods/fml/relauncher/ModListHelper.java +++ b/fml/src/main/java/cpw/mods/fml/relauncher/ModListHelper.java @@ -5,11 +5,14 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.logging.log4j.Level; import com.google.common.base.Charsets; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import com.google.common.io.Files; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; @@ -20,8 +23,10 @@ public class ModListHelper { public static class JsonModList { public String repositoryRoot; public List modRef; + public String parentList; } - public static final ArrayList additionalMods = Lists.newArrayList(); + private static Set visitedFiles = Sets.newHashSet(); + public static final Map additionalMods = Maps.newLinkedHashMap(); static void parseModList() { FMLRelaunchLog.fine("Attempting to load commandline specified mods"); @@ -49,6 +54,11 @@ public class ModListHelper { FMLRelaunchLog.info("Failed to find modList file %s", listFile); return; } + if (visitedFiles.contains(f)) + { + FMLRelaunchLog.severe("There appears to be a loop in the modListFile hierarchy. You shouldn't do this!"); + throw new RuntimeException("Loop detected, impossible to load modlistfile"); + } String json; try { json = Files.asCharSource(f, Charsets.UTF_8).read(); @@ -64,6 +74,12 @@ public class ModListHelper { FMLRelaunchLog.log(Level.INFO, e, "Failed to parse modList json file %s.", listFile); return; } + visitedFiles.add(f); + // We visit parents before children, so the additionalMods list is sorted from parent to child + if (modList.parentList != null) + { + parseListFile(modList.parentList); + } File repoRoot = new File(modList.repositoryRoot); if (!repoRoot.exists()) { @@ -73,19 +89,23 @@ public class ModListHelper { for (String s : modList.modRef) { - StringBuilder sb = new StringBuilder(); + StringBuilder fileName = new StringBuilder(); + StringBuilder genericName = new StringBuilder(); String[] parts = s.split(":"); - sb.append(parts[0].replace('.', File.separatorChar)); - sb.append(File.separatorChar); - sb.append(parts[1]).append(File.separatorChar); - sb.append(parts[2]).append(File.separatorChar); - sb.append(parts[1]).append('-').append(parts[2]); + fileName.append(parts[0].replace('.', File.separatorChar)); + genericName.append(parts[0]); + fileName.append(File.separatorChar); + fileName.append(parts[1]).append(File.separatorChar); + genericName.append(":").append(parts[1]); + fileName.append(parts[2]).append(File.separatorChar); + fileName.append(parts[1]).append('-').append(parts[2]); if (parts.length == 4) { - sb.append('-').append(parts[3]); + fileName.append('-').append(parts[3]); + genericName.append(":").append(parts[3]); } - sb.append(".jar"); - tryAddFile(sb.toString(), repoRoot, s); + fileName.append(".jar"); + tryAddFile(fileName.toString(), repoRoot, genericName.toString()); } } private static void tryAddFile(String modFileName, File repoRoot, String descriptor) { @@ -96,8 +116,8 @@ public class ModListHelper { } else { - FMLRelaunchLog.fine("Adding ;%s (%s) to the mod list", descriptor, modFile.getAbsolutePath()); - additionalMods.add(modFile); + FMLRelaunchLog.fine("Adding %s (%s) to the mod list", descriptor, modFile.getAbsolutePath()); + additionalMods.put(descriptor, modFile); } } }