Two new features. ModLists can have a "parent" mod list. Circularity will

result in a crash, so be careful. Mods specified in a child will override
ones from a parent (using the maven group:name:classifier triple to identify -
ignoring the version component)

Finally, ModSide is now doable in MANIFEST.MF. If you have this, it can tell
a mod to only load on a client, or on a dedicated server (though I'd watch out
before using the dediserver one, you'll never load in integrated servers then).
The default value is BOTH, which means you'll load both sides, other values are
CLIENT and SERVER, obviously. Perhaps, also, CAULDRON might be possible?
This commit is contained in:
cpw 2014-08-31 14:00:28 -04:00
parent c604a5e048
commit f5cf87304b
3 changed files with 43 additions and 15 deletions

View File

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

View File

@ -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<String> loadedCoremods = Lists.newArrayList();
private static List<FMLPluginWrapper> 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)
{

View File

@ -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<String> modRef;
public String parentList;
}
public static final ArrayList<File> additionalMods = Lists.newArrayList();
private static Set<File> visitedFiles = Sets.newHashSet();
public static final Map<String,File> 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);
}
}
}