Fix up coremods with relaunch, add in a sample "coremod"

This commit is contained in:
Christian 2012-07-30 11:34:30 -04:00
parent b79ec382d7
commit d1d12e4ebd
6 changed files with 194 additions and 4 deletions

View File

@ -5,6 +5,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
@ -20,7 +21,11 @@ import java.nio.channels.FileChannel.MapMode;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -31,14 +36,14 @@ import cpw.mods.fml.common.discovery.ModCandidate;
public class RelaunchLibraryManager
{
private static String[] plugins = { "cpw.mods.fml.relauncher.FMLCorePlugin" , "net.minecraftforge.classloading.FMLForgePlugin" };
private static String[] rootPlugins = { "cpw.mods.fml.relauncher.FMLCorePlugin" , "net.minecraftforge.classloading.FMLForgePlugin" };
private static final String HEXES = "0123456789abcdef";
private static List<String> loadedLibraries = new ArrayList<String>();
public static void handleLaunch(File mcDir, RelaunchClassLoader actualClassLoader)
{
List<IFMLLoadingPlugin> loadPlugins = new ArrayList<IFMLLoadingPlugin>();
List<ILibrarySet> libraries = new ArrayList<ILibrarySet>();
for (String s : plugins)
for (String s : rootPlugins)
{
try
{
@ -60,6 +65,9 @@ public class RelaunchLibraryManager
throw new RuntimeException("A fatal error has occured - no valid fml load plugin was found - this is a completely corrupt FML installation.");
}
// Now that we have the root plugins loaded - lets see what else might be around
discoverCoreMods(mcDir, actualClassLoader, loadPlugins, libraries);
List<Throwable> caughtErrors = new ArrayList<Throwable>();
try
{
@ -172,9 +180,12 @@ public class RelaunchLibraryManager
for (IFMLLoadingPlugin plug : loadPlugins)
{
for (String xformClass : plug.getASMTransformerClass())
if (plug.getASMTransformerClass()!=null)
{
actualClassLoader.registerTransformer(xformClass);
for (String xformClass : plug.getASMTransformerClass())
{
actualClassLoader.registerTransformer(xformClass);
}
}
}
try
@ -188,6 +199,102 @@ public class RelaunchLibraryManager
}
}
private static void discoverCoreMods(File mcDir, RelaunchClassLoader classLoader, List<IFMLLoadingPlugin> loadPlugins, List<ILibrarySet> libraries)
{
File coreMods = setupCoreModDir(mcDir);
FilenameFilter ff = new FilenameFilter()
{
@Override
public boolean accept(File dir, String name)
{
return name.endsWith(".jar");
}
};
File[] coreModList = coreMods.listFiles(ff);
Arrays.sort(coreModList);
for (File coreMod : coreModList)
{
FMLLog.fine("Found a candidate coremod %s", coreMod.getName());
JarFile jar;
Attributes mfAttributes;
try
{
jar = new JarFile(coreMod);
mfAttributes = jar.getManifest().getMainAttributes();
}
catch (IOException ioe)
{
FMLLog.log(Level.SEVERE, ioe, "Unable to read the coremod jar file %s - ignoring", coreMod.getName());
continue;
}
String fmlCorePlugin = mfAttributes.getValue("FMLCorePlugin");
if (fmlCorePlugin == null)
{
FMLLog.severe("The coremod %s does not contain a valid jar manifest- it will be ignored", coreMod.getName());
continue;
}
// String className = fmlCorePlugin.replace('.', '/').concat(".class");
// JarEntry ent = jar.getJarEntry(className);
// if (ent ==null)
// {
// FMLLog.severe("The coremod %s specified %s as it's loading class but it does not include it - it will be ignored", coreMod.getName(), fmlCorePlugin);
// continue;
// }
// try
// {
// Class<?> coreModClass = Class.forName(fmlCorePlugin, false, classLoader);
// FMLLog.severe("The coremods %s specified a class %s that is already present in the classpath - it will be ignored", coreMod.getName(), fmlCorePlugin);
// continue;
// }
// catch (ClassNotFoundException cnfe)
// {
// // didn't find it, good
// }
try
{
classLoader.addURL(coreMod.toURI().toURL());
}
catch (MalformedURLException e)
{
FMLLog.log(Level.SEVERE, e, "Unable to convert file into a URL. weird");
continue;
}
try
{
Class<?> coreModClass = Class.forName(fmlCorePlugin, true, classLoader);
IFMLLoadingPlugin plugin = (IFMLLoadingPlugin) coreModClass.newInstance();
loadPlugins.add(plugin);
if (plugin.getLibraryRequestClass()!=null)
{
for (String libName : plugin.getLibraryRequestClass())
{
libraries.add((ILibrarySet) Class.forName(libName, true, classLoader).newInstance());
}
}
FMLLog.fine("Loaded coremod %s", coreMod.getName());
}
catch (ClassNotFoundException cnfe)
{
FMLLog.log(Level.SEVERE, cnfe, "Coremod %s: Unable to class load the plugin %s", coreMod.getName(), fmlCorePlugin);
}
catch (ClassCastException cce)
{
FMLLog.log(Level.SEVERE, cce, "Coremod %s: The plugin %s is not an implementor of IFMLLoadingPlugin", coreMod.getName(), fmlCorePlugin);
}
catch (InstantiationException ie)
{
FMLLog.log(Level.SEVERE, ie, "Coremod %s: The plugin class %s was not instantiable", coreMod.getName(), fmlCorePlugin);
}
catch (IllegalAccessException iae)
{
FMLLog.log(Level.SEVERE, iae, "Coremod %s: The plugin class %s was not accessible", coreMod.getName(), fmlCorePlugin);
}
}
}
/**
* @param mcDir
* @return
@ -214,6 +321,32 @@ public class RelaunchLibraryManager
return libDir;
}
/**
* @param mcDir
* @return
*/
private static File setupCoreModDir(File mcDir)
{
File coreModDir = new File(mcDir,"coremods");
try
{
coreModDir = coreModDir.getCanonicalFile();
}
catch (IOException e)
{
throw new RuntimeException(String.format("Unable to canonicalize the coremod dir at %s", mcDir.getName()),e);
}
if (!coreModDir.exists())
{
coreModDir.mkdir();
}
else if (coreModDir.exists() && !coreModDir.isDirectory())
{
throw new RuntimeException(String.format("Found a coremod file in %s that's not a directory", mcDir.getName()));
}
return coreModDir;
}
private static String generateChecksum(File file)
{
try

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry combineaccessrules="false" kind="src" path="/FML-Client"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>coremodtest</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
FMLCorePlugin: cpw.mods.testcoremod.FMLLoadPlugin

View File

@ -0,0 +1,19 @@
package cpw.mods.testcoremod;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
public class FMLLoadPlugin implements IFMLLoadingPlugin
{
@Override
public String[] getLibraryRequestClass()
{
return null;
}
@Override
public String[] getASMTransformerClass()
{
return null;
}
}