From d1d12e4ebd31d4c7cf6daa1af6c2861cba6b49d0 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 30 Jul 2012 11:34:30 -0400 Subject: [PATCH] Fix up coremods with relaunch, add in a sample "coremod" --- .../relauncher/RelaunchLibraryManager.java | 141 +++++++++++++++++- fml/eclipse/coremodtest/.classpath | 7 + fml/eclipse/coremodtest/.project | 17 +++ .../.settings/org.eclipse.jdt.core.prefs | 11 ++ fml/eclipse/coremodtest/manifest.mf | 3 + .../cpw/mods/testcoremod/FMLLoadPlugin.java | 19 +++ 6 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 fml/eclipse/coremodtest/.classpath create mode 100644 fml/eclipse/coremodtest/.project create mode 100644 fml/eclipse/coremodtest/.settings/org.eclipse.jdt.core.prefs create mode 100644 fml/eclipse/coremodtest/manifest.mf create mode 100644 fml/eclipse/coremodtest/src/cpw/mods/testcoremod/FMLLoadPlugin.java diff --git a/fml/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java b/fml/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java index 3ed09f917..9ee3c5803 100644 --- a/fml/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java +++ b/fml/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java @@ -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 loadedLibraries = new ArrayList(); public static void handleLaunch(File mcDir, RelaunchClassLoader actualClassLoader) { List loadPlugins = new ArrayList(); List libraries = new ArrayList(); - 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 caughtErrors = new ArrayList(); 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 loadPlugins, List 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 diff --git a/fml/eclipse/coremodtest/.classpath b/fml/eclipse/coremodtest/.classpath new file mode 100644 index 000000000..294bff6e8 --- /dev/null +++ b/fml/eclipse/coremodtest/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/fml/eclipse/coremodtest/.project b/fml/eclipse/coremodtest/.project new file mode 100644 index 000000000..bda043346 --- /dev/null +++ b/fml/eclipse/coremodtest/.project @@ -0,0 +1,17 @@ + + + coremodtest + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/fml/eclipse/coremodtest/.settings/org.eclipse.jdt.core.prefs b/fml/eclipse/coremodtest/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..8000cd6ca --- /dev/null +++ b/fml/eclipse/coremodtest/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/fml/eclipse/coremodtest/manifest.mf b/fml/eclipse/coremodtest/manifest.mf new file mode 100644 index 000000000..eda1ba385 --- /dev/null +++ b/fml/eclipse/coremodtest/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +FMLCorePlugin: cpw.mods.testcoremod.FMLLoadPlugin + diff --git a/fml/eclipse/coremodtest/src/cpw/mods/testcoremod/FMLLoadPlugin.java b/fml/eclipse/coremodtest/src/cpw/mods/testcoremod/FMLLoadPlugin.java new file mode 100644 index 000000000..44094f000 --- /dev/null +++ b/fml/eclipse/coremodtest/src/cpw/mods/testcoremod/FMLLoadPlugin.java @@ -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; + } + +}