Add a simple ContainedDep mechanic- mods can contain other mods or libs, and can specify them using a manifest tag: "ContainedDeps".
This is a space separated (manifest standard) list of jar files that are to be extracted into the version specific directory. There's also a special system property "fml.skipContainedDeps" that will allow for runtime skipping of extraction of contained deps (a comma separated list, based on the file name).
This commit is contained in:
parent
1a31ff9f06
commit
dc4dc55dcd
1 changed files with 80 additions and 32 deletions
|
@ -14,6 +14,7 @@ package net.minecraftforge.fml.relauncher;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -29,8 +30,10 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import net.minecraft.launchwrapper.ITweaker;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import net.minecraft.launchwrapper.LaunchClassLoader;
|
||||
|
@ -59,6 +62,7 @@ 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 final Attributes.Name MODCONTAINSDEPS = new Attributes.Name("ContainedDeps");
|
||||
private static String[] rootPlugins = { "net.minecraftforge.fml.relauncher.FMLCorePlugin", "net.minecraftforge.classloading.FMLForgePlugin" };
|
||||
private static List<String> ignoredModFiles = Lists.newArrayList();
|
||||
private static Map<String, List<String>> transformers = Maps.newHashMap();
|
||||
|
@ -69,6 +73,7 @@ public class CoreModManager {
|
|||
private static List<String> candidateModFiles = Lists.newArrayList();
|
||||
private static List<String> accessTransformers = Lists.newArrayList();
|
||||
private static Set<String> rootNames = Sets.newHashSet();
|
||||
private static final List<String> skipContainedDeps = Arrays.asList(System.getProperty("fml.skipContainedDeps","").split(","));
|
||||
|
||||
static
|
||||
{
|
||||
|
@ -322,6 +327,7 @@ public class CoreModManager {
|
|||
FMLRelaunchLog.fine("Examining for coremod candidacy %s", coreMod.getName());
|
||||
JarFile jar = null;
|
||||
Attributes mfAttributes;
|
||||
String fmlCorePlugin;
|
||||
try
|
||||
{
|
||||
jar = new JarFile(coreMod);
|
||||
|
@ -332,6 +338,39 @@ public class CoreModManager {
|
|||
}
|
||||
ModAccessTransformer.addJar(jar);
|
||||
mfAttributes = jar.getManifest().getMainAttributes();
|
||||
String cascadedTweaker = mfAttributes.getValue("TweakClass");
|
||||
if (cascadedTweaker != null)
|
||||
{
|
||||
FMLRelaunchLog.info("Loading tweaker %s from %s", cascadedTweaker, coreMod.getName());
|
||||
Integer sortOrder = Ints.tryParse(Strings.nullToEmpty(mfAttributes.getValue("TweakOrder")));
|
||||
sortOrder = (sortOrder == null ? Integer.valueOf(0) : sortOrder);
|
||||
handleCascadingTweak(coreMod, jar, cascadedTweaker, classLoader, sortOrder);
|
||||
ignoredModFiles.add(coreMod.getName());
|
||||
continue;
|
||||
}
|
||||
List<String> modTypes = mfAttributes.containsKey(MODTYPE) ? Arrays.asList(mfAttributes.getValue(MODTYPE).split(",")) : ImmutableList.of("FML");
|
||||
|
||||
if (!modTypes.contains("FML"))
|
||||
{
|
||||
FMLRelaunchLog.fine("Adding %s to the list of things to skip. It is not an FML mod, it has types %s", coreMod.getName(), modTypes);
|
||||
ignoredModFiles.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());
|
||||
ignoredModFiles.add(coreMod.getName());
|
||||
continue;
|
||||
}
|
||||
ModListHelper.additionalMods.putAll(extractContainedDepJars(jar, versionedModDir));
|
||||
fmlCorePlugin = mfAttributes.getValue("FMLCorePlugin");
|
||||
if (fmlCorePlugin == null)
|
||||
{
|
||||
// Not a coremod
|
||||
FMLRelaunchLog.fine("Not found coremod data in %s", coreMod.getName());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
|
@ -352,38 +391,6 @@ public class CoreModManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
String cascadedTweaker = mfAttributes.getValue("TweakClass");
|
||||
if (cascadedTweaker != null)
|
||||
{
|
||||
FMLRelaunchLog.info("Loading tweaker %s from %s", cascadedTweaker, coreMod.getName());
|
||||
Integer sortOrder = Ints.tryParse(Strings.nullToEmpty(mfAttributes.getValue("TweakOrder")));
|
||||
sortOrder = (sortOrder == null ? Integer.valueOf(0) : sortOrder);
|
||||
handleCascadingTweak(coreMod, jar, cascadedTweaker, classLoader, sortOrder);
|
||||
ignoredModFiles.add(coreMod.getName());
|
||||
continue;
|
||||
}
|
||||
List<String> modTypes = mfAttributes.containsKey(MODTYPE) ? Arrays.asList(mfAttributes.getValue(MODTYPE).split(",")) : ImmutableList.of("FML");
|
||||
|
||||
if (!modTypes.contains("FML"))
|
||||
{
|
||||
FMLRelaunchLog.fine("Adding %s to the list of things to skip. It is not an FML mod, it has types %s", coreMod.getName(), modTypes);
|
||||
ignoredModFiles.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());
|
||||
ignoredModFiles.add(coreMod.getName());
|
||||
continue;
|
||||
}
|
||||
String fmlCorePlugin = mfAttributes.getValue("FMLCorePlugin");
|
||||
if (fmlCorePlugin == null)
|
||||
{
|
||||
// Not a coremod
|
||||
FMLRelaunchLog.fine("Not found coremod data in %s", coreMod.getName());
|
||||
continue;
|
||||
}
|
||||
// Support things that are mod jars, but not FML mod jars
|
||||
try
|
||||
{
|
||||
|
@ -409,6 +416,47 @@ public class CoreModManager {
|
|||
}
|
||||
}
|
||||
|
||||
private static Map<String,File> extractContainedDepJars(JarFile jar, File versionedModsDir) throws IOException
|
||||
{
|
||||
Map<String,File> result = Maps.newHashMap();
|
||||
if (!jar.getManifest().getMainAttributes().containsKey(MODCONTAINSDEPS)) return result;
|
||||
|
||||
String deps = jar.getManifest().getMainAttributes().getValue(MODCONTAINSDEPS);
|
||||
String[] depList = deps.split(" ");
|
||||
for (String dep : depList)
|
||||
{
|
||||
if (skipContainedDeps.contains(dep))
|
||||
{
|
||||
FMLRelaunchLog.log(Level.ERROR, "Skipping dep at request: %s", dep);
|
||||
continue;
|
||||
}
|
||||
final JarEntry jarEntry = jar.getJarEntry(dep);
|
||||
if (jarEntry == null)
|
||||
{
|
||||
FMLRelaunchLog.log(Level.ERROR, "Found invalid ContainsDeps declaration %s in %s", dep, jar.getName());
|
||||
continue;
|
||||
}
|
||||
File target = new File(versionedModsDir, dep);
|
||||
if (target.exists())
|
||||
{
|
||||
FMLRelaunchLog.log(Level.DEBUG, "Found existing ContainsDep extracted to %s, skipping extraction", target.getCanonicalPath());
|
||||
result.put(dep,target);
|
||||
continue;
|
||||
}
|
||||
FMLRelaunchLog.log(Level.DEBUG, "Extracted ContainedDep %s from %s to %s", dep, jar.getName(), target.getCanonicalPath());
|
||||
try
|
||||
{
|
||||
ByteStreams.copy(jar.getInputStream(jarEntry), new FileOutputStream(target));
|
||||
} catch (IOException e)
|
||||
{
|
||||
FMLRelaunchLog.log(Level.ERROR, e, "An error occurred extracting dependency");
|
||||
continue;
|
||||
}
|
||||
result.put(dep,target);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Method ADDURL;
|
||||
|
||||
private static void handleCascadingTweak(File coreMod, JarFile jar, String cascadedTweaker, LaunchClassLoader classLoader, Integer sortingOrder)
|
||||
|
|
Loading…
Reference in a new issue