Allow coremods to inject a modcontainer and run code

this will mean that FML is deliberately and very obviously incompatible with a modloader installation.

Fix up worldtype so that the server can run.
This commit is contained in:
Christian 2012-08-04 11:26:51 -04:00
parent ae79c79447
commit e39092335a
25 changed files with 468 additions and 49 deletions

View file

@ -322,7 +322,6 @@ public class FMLClientHandler implements IFMLSidedHandler
*/ */
public void addSpecialModEntries(ArrayList<ModContainer> mods) public void addSpecialModEntries(ArrayList<ModContainer> mods)
{ {
mods.add(new FMLDummyContainer());
if (optifineContainer!=null) { if (optifineContainer!=null) {
mods.add(optifineContainer); mods.add(optifineContainer);
} }

View file

@ -18,7 +18,7 @@ import net.minecraft.client.Minecraft;
public class EntityRendererProxy extends EntityRenderer public class EntityRendererProxy extends EntityRenderer
{ {
public static final String fmlMarker = "This is an FML marker";
private Minecraft game; private Minecraft game;
public EntityRendererProxy(Minecraft minecraft) public EntityRendererProxy(Minecraft minecraft)

View file

@ -42,6 +42,7 @@ import cpw.mods.fml.common.ObfuscationReflectionHelper;
public class ModLoader public class ModLoader
{ {
public static final String fmlMarker = "This is an FML marker";
// TODO dirty workaround for millinaire // TODO dirty workaround for millinaire
@Deprecated @Deprecated
public static final Map<String,Map<String,String>> localizedStrings=Collections.emptyMap(); public static final Map<String,Map<String,String>> localizedStrings=Collections.emptyMap();

View file

@ -117,4 +117,9 @@ public class DummyModContainer implements ModContainer
return null; return null;
} }
@Override
public boolean isImmutable()
{
return false;
}
} }

View file

@ -16,6 +16,8 @@ package cpw.mods.fml.common;
import java.util.Arrays; import java.util.Arrays;
import com.google.common.eventbus.EventBus;
/** /**
* @author cpw * @author cpw
* *
@ -41,4 +43,10 @@ public class FMLDummyContainer extends DummyModContainer
meta.screenshots=new String[0]; meta.screenshots=new String[0];
meta.logoFile=""; meta.logoFile="";
} }
@Override
public boolean registerBus(EventBus bus, LoadController controller)
{
return true;
}
} }

View file

@ -311,4 +311,9 @@ public class FMLModContainer implements ModContainer
} }
return processedVersion; return processedVersion;
} }
@Override
public boolean isImmutable()
{
return false;
}
} }

View file

@ -0,0 +1,105 @@
package cpw.mods.fml.common;
import java.io.File;
import java.util.List;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.versioning.ArtifactVersion;
public class InjectedModContainer implements ModContainer
{
private ModContainer wrappedContainer;
public InjectedModContainer(ModContainer mc)
{
this.wrappedContainer = mc;
}
public String getModId()
{
return wrappedContainer.getModId();
}
public String getName()
{
return wrappedContainer.getName();
}
public String getVersion()
{
return wrappedContainer.getVersion();
}
public File getSource()
{
return wrappedContainer.getSource();
}
public ModMetadata getMetadata()
{
return wrappedContainer.getMetadata();
}
public void bindMetadata(MetadataCollection mc)
{
wrappedContainer.bindMetadata(mc);
}
public void setEnabledState(boolean enabled)
{
wrappedContainer.setEnabledState(enabled);
}
public List<ArtifactVersion> getRequirements()
{
return wrappedContainer.getRequirements();
}
public List<ArtifactVersion> getDependencies()
{
return wrappedContainer.getDependencies();
}
public List<ArtifactVersion> getDependants()
{
return wrappedContainer.getDependants();
}
public String getSortingRules()
{
return wrappedContainer.getSortingRules();
}
public boolean registerBus(EventBus bus, LoadController controller)
{
return wrappedContainer.registerBus(bus, controller);
}
public boolean matches(Object mod)
{
return wrappedContainer.matches(mod);
}
public Object getMod()
{
return wrappedContainer.getMod();
}
public ArtifactVersion getProcessedVersion()
{
return wrappedContainer.getProcessedVersion();
}
public ProxyInjector findSidedProxy()
{
return wrappedContainer.findSidedProxy();
}
@Override
public boolean isImmutable()
{
return true;
}
}

View file

@ -17,6 +17,7 @@ import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.LoaderState.ModState; import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.event.FMLLoadEvent;
import cpw.mods.fml.common.event.FMLStateEvent; import cpw.mods.fml.common.event.FMLStateEvent;
public class LoadController public class LoadController
@ -34,10 +35,16 @@ public class LoadController
public LoadController(Loader loader) public LoadController(Loader loader)
{ {
this.loader = loader; this.loader = loader;
this.modList = loader.getIndexedModList();
this.masterChannel = new EventBus("FMLMainChannel"); this.masterChannel = new EventBus("FMLMainChannel");
this.masterChannel.register(this); this.masterChannel.register(this);
state = LoaderState.NOINIT;
}
@Subscribe
public void buildModList(FMLLoadEvent event)
{
this.modList = loader.getIndexedModList();
Builder<String, EventBus> eventBus = ImmutableMap.builder(); Builder<String, EventBus> eventBus = ImmutableMap.builder();
for (ModContainer mod : loader.getModList()) for (ModContainer mod : loader.getModList())
@ -60,8 +67,6 @@ public class LoadController
} }
eventChannels = eventBus.build(); eventChannels = eventBus.build();
state = LoaderState.NOINIT;
} }
public void distributeStateMessage(LoaderState state, Object... eventData) public void distributeStateMessage(LoaderState state, Object... eventData)
@ -141,4 +146,17 @@ public class LoadController
{ {
return Iterables.getLast(modStates.get(selectedMod.getModId()), ModState.AVAILABLE); return Iterables.getLast(modStates.get(selectedMod.getModId()), ModState.AVAILABLE);
} }
public void distributeStateMessage(Class<?> customEvent)
{
try
{
masterChannel.post(customEvent.newInstance());
}
catch (Exception e)
{
FMLLog.log(Level.SEVERE, e, "An unexpected exception");
throw new LoaderException(e);
}
}
} }

View file

@ -47,6 +47,7 @@ import com.google.common.collect.Maps;
import cpw.mods.fml.common.LoaderState.ModState; import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.discovery.ContainerType; import cpw.mods.fml.common.discovery.ContainerType;
import cpw.mods.fml.common.discovery.ModDiscoverer; import cpw.mods.fml.common.discovery.ModDiscoverer;
import cpw.mods.fml.common.event.FMLLoadEvent;
import cpw.mods.fml.common.functions.ModIdFunction; import cpw.mods.fml.common.functions.ModIdFunction;
import cpw.mods.fml.common.toposort.ModSorter; import cpw.mods.fml.common.toposort.ModSorter;
import cpw.mods.fml.common.toposort.ModSortingException; import cpw.mods.fml.common.toposort.ModSortingException;
@ -131,6 +132,7 @@ public class Loader
private LoadController modController; private LoadController modController;
private static File minecraftDir; private static File minecraftDir;
private static List<String> injectedContainers;
public static Loader instance() public static Loader instance()
{ {
@ -151,6 +153,7 @@ public class Loader
mccversion = (String) data[4]; mccversion = (String) data[4];
mcsversion = (String) data[5]; mcsversion = (String) data[5];
minecraftDir = (File) data[6]; minecraftDir = (File) data[6];
injectedContainers = (List<String>)data[7];
} }
private Loader() private Loader()
@ -213,9 +216,12 @@ public class Loader
{ {
FMLLog.fine("Mod sorting data:"); FMLLog.fine("Mod sorting data:");
for (ModContainer mod : mods) for (ModContainer mod : mods)
{
if (!mod.isImmutable())
{ {
FMLLog.fine("\t%s(%s): %s (%s)", mod.getModId(), mod.getName(), mod.getSource().getName(), mod.getSortingRules()); FMLLog.fine("\t%s(%s): %s (%s)", mod.getModId(), mod.getName(), mod.getSource().getName(), mod.getSortingRules());
} }
}
if (mods.size()==0) if (mods.size()==0)
{ {
FMLLog.fine("No mods found to sort"); FMLLog.fine("No mods found to sort");
@ -247,6 +253,21 @@ public class Loader
*/ */
private void identifyMods() private void identifyMods()
{ {
FMLLog.fine("Building injected Mod Containers %s", injectedContainers);
for (String cont : injectedContainers)
{
ModContainer mc;
try
{
mc = (ModContainer) Class.forName(cont,true,modClassLoader).newInstance();
}
catch (Exception e)
{
FMLLog.log(Level.SEVERE, e, "A problem occured instantiating the injected mod container %s", cont);
throw new LoaderException(e);
}
mods.add(new InjectedModContainer(mc));
}
ModDiscoverer discoverer = new ModDiscoverer(); ModDiscoverer discoverer = new ModDiscoverer();
FMLLog.fine("Attempting to load mods contained in the minecraft jar file and associated classes"); FMLLog.fine("Attempting to load mods contained in the minecraft jar file and associated classes");
discoverer.findClasspathMods(modClassLoader); discoverer.findClasspathMods(modClassLoader);
@ -255,7 +276,7 @@ public class Loader
FMLLog.info("Searching %s for mods", canonicalModsDir.getAbsolutePath()); FMLLog.info("Searching %s for mods", canonicalModsDir.getAbsolutePath());
discoverer.findModDirMods(canonicalModsDir); discoverer.findModDirMods(canonicalModsDir);
mods = discoverer.identifyMods(); mods.addAll(discoverer.identifyMods());
namedMods = Maps.uniqueIndex(mods, new ModIdFunction()); namedMods = Maps.uniqueIndex(mods, new ModIdFunction());
FMLLog.info("Forge Mod Loader has identified %d mod%s to load", mods.size(), mods.size() != 1 ? "s" : ""); FMLLog.info("Forge Mod Loader has identified %d mod%s to load", mods.size(), mods.size() != 1 ? "s" : "");
} }
@ -343,6 +364,7 @@ public class Loader
disableRequestedMods(); disableRequestedMods();
sortModList(); sortModList();
mods = ImmutableList.copyOf(mods); mods = ImmutableList.copyOf(mods);
modController.distributeStateMessage(FMLLoadEvent.class);
modController.transition(LoaderState.CONSTRUCTING); modController.transition(LoaderState.CONSTRUCTING);
modController.distributeStateMessage(LoaderState.CONSTRUCTING, modClassLoader); modController.distributeStateMessage(LoaderState.CONSTRUCTING, modClassLoader);
modController.transition(LoaderState.PREINITIALIZATION); modController.transition(LoaderState.PREINITIALIZATION);

View file

@ -148,4 +148,6 @@ public interface ModContainer
ArtifactVersion getProcessedVersion(); ArtifactVersion getProcessedVersion();
ProxyInjector findSidedProxy(); ProxyInjector findSidedProxy();
boolean isImmutable();
} }

View file

@ -0,0 +1,6 @@
package cpw.mods.fml.common.event;
public class FMLLoadEvent
{
}

View file

@ -558,4 +558,10 @@ public class ModLoaderModContainer implements ModContainer
} }
return processedVersion; return processedVersion;
} }
@Override
public boolean isImmutable()
{
return false;
}
} }

View file

@ -16,6 +16,8 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.google.common.collect.Lists;
import cpw.mods.fml.common.DummyModContainer; import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.FMLModContainer; import cpw.mods.fml.common.FMLModContainer;
import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.ModContainer;
@ -35,6 +37,8 @@ public class ModSorter
private ModContainer before = new DummyModContainer(); private ModContainer before = new DummyModContainer();
private ModContainer after = new DummyModContainer(); private ModContainer after = new DummyModContainer();
private List<ModContainer> immutableMods;
public ModSorter(List<ModContainer> modList, Map<String, ModContainer> nameLookup) public ModSorter(List<ModContainer> modList, Map<String, ModContainer> nameLookup)
{ {
buildGraph(modList, nameLookup); buildGraph(modList, nameLookup);
@ -43,6 +47,7 @@ public class ModSorter
private void buildGraph(List<ModContainer> modList, Map<String, ModContainer> nameLookup) private void buildGraph(List<ModContainer> modList, Map<String, ModContainer> nameLookup)
{ {
modGraph = new DirectedGraph<ModContainer>(); modGraph = new DirectedGraph<ModContainer>();
immutableMods = Lists.newArrayList();
modGraph.addNode(beforeAll); modGraph.addNode(beforeAll);
modGraph.addNode(before); modGraph.addNode(before);
modGraph.addNode(afterAll); modGraph.addNode(afterAll);
@ -52,12 +57,21 @@ public class ModSorter
modGraph.addEdge(after, afterAll); modGraph.addEdge(after, afterAll);
for (ModContainer mod : modList) for (ModContainer mod : modList)
{
if (!mod.isImmutable())
{ {
modGraph.addNode(mod); modGraph.addNode(mod);
} }
else
{
immutableMods.add(mod);
}
}
for (ModContainer mod : modList) for (ModContainer mod : modList)
{ {
if (mod.isImmutable())
continue;
boolean preDepAdded = false; boolean preDepAdded = false;
boolean postDepAdded = false; boolean postDepAdded = false;
@ -117,6 +131,7 @@ public class ModSorter
{ {
List<ModContainer> sortedList = TopologicalSort.topologicalSort(modGraph); List<ModContainer> sortedList = TopologicalSort.topologicalSort(modGraph);
sortedList.removeAll(Arrays.asList(new ModContainer[] {beforeAll, before, after, afterAll})); sortedList.removeAll(Arrays.asList(new ModContainer[] {beforeAll, before, after, afterAll}));
return sortedList; immutableMods.addAll(sortedList);
return immutableMods;
} }
} }

View file

@ -1,5 +1,7 @@
package cpw.mods.fml.relauncher; package cpw.mods.fml.relauncher;
import java.util.Map;
public class FMLCorePlugin implements IFMLLoadingPlugin public class FMLCorePlugin implements IFMLLoadingPlugin
{ {
@Override @Override
@ -13,4 +15,22 @@ public class FMLCorePlugin implements IFMLLoadingPlugin
{ {
return new String[] {"cpw.mods.fml.common.asm.ASMTransformer"}; return new String[] {"cpw.mods.fml.common.asm.ASMTransformer"};
} }
@Override
public String getModContainerClass()
{
return "cpw.mods.fml.common.FMLDummyContainer";
}
@Override
public String getSetupClass()
{
return "cpw.mods.fml.relauncher.FMLSanityChecker";
}
@Override
public void injectData(Map<String, Object> data)
{
// don't care about this data
}
} }

View file

@ -3,10 +3,12 @@ package cpw.mods.fml.relauncher;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.logging.Level; import java.util.logging.Level;
public class FMLVersionData public class FMLInjectionData
{ {
static File minecraftHome; static File minecraftHome;
static String major; static String major;
@ -15,6 +17,7 @@ public class FMLVersionData
static String build; static String build;
static String mccversion; static String mccversion;
static String mcsversion; static String mcsversion;
public static List<String> containers = new ArrayList<String>();
static void build(File mcHome, RelaunchClassLoader classLoader) static void build(File mcHome, RelaunchClassLoader classLoader)
{ {
@ -46,6 +49,6 @@ public class FMLVersionData
public static Object[] data() public static Object[] data()
{ {
return new Object[] { major, minor, rev, build, mccversion, mcsversion, minecraftHome }; return new Object[] { major, minor, rev, build, mccversion, mcsversion, minecraftHome, containers };
} }
} }

View file

@ -28,7 +28,7 @@ public class FMLRelauncher
private Object newApplet; private Object newApplet;
private Class<? super Object> appletClass; private Class<? super Object> appletClass;
private JDialog popupWindow; JDialog popupWindow;
public static void handleClientRelaunch(ArgsWrapper wrap) public static void handleClientRelaunch(ArgsWrapper wrap)
{ {
@ -128,8 +128,8 @@ public class FMLRelauncher
private void setupHome(File minecraftHome) private void setupHome(File minecraftHome)
{ {
FMLVersionData.build(minecraftHome, classLoader); FMLInjectionData.build(minecraftHome, classLoader);
FMLLog.info("Forge Mod Loader version %s.%s.%s.%s for Minecraft client:%s, server:%s loading", FMLVersionData.major, FMLVersionData.minor, FMLVersionData.rev, FMLVersionData.build, FMLVersionData.mccversion, FMLVersionData.mcsversion); FMLLog.info("Forge Mod Loader version %s.%s.%s.%s for Minecraft client:%s, server:%s loading", FMLInjectionData.major, FMLInjectionData.minor, FMLInjectionData.rev, FMLInjectionData.build, FMLInjectionData.mccversion, FMLInjectionData.mcsversion);
try try
{ {

View file

@ -0,0 +1,69 @@
package cpw.mods.fml.relauncher;
import java.util.Map;
import javax.swing.JOptionPane;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
public class FMLSanityChecker implements IFMLCallHook
{
static class MLDetectorClassVisitor extends ClassVisitor
{
private boolean foundMarker = false;
private MLDetectorClassVisitor()
{
super(Opcodes.ASM4);
}
@Override
public FieldVisitor visitField(int arg0, String arg1, String arg2, String arg3, Object arg4)
{
if (arg1 == "fmlMarker")
{
foundMarker = true;
}
return null;
}
}
private RelaunchClassLoader cl;
@Override
public Void call() throws Exception
{
byte[] mlClass = cl.getClassBytes("ModLoader");
// Only care in obfuscated env
if (mlClass == null)
{
return null;
}
MLDetectorClassVisitor mlTester = new MLDetectorClassVisitor();
ClassReader cr = new ClassReader(mlClass);
cr.accept(mlTester, ClassReader.SKIP_CODE);
if (!mlTester.foundMarker)
{
JOptionPane.showMessageDialog(FMLRelauncher.instance().popupWindow, "<html>CRITICAL ERROR<br/>" +
"ModLoader was detected in this environment<br/>" +
"ForgeModLoader cannot be installed alongside ModLoader<br/>" +
"All mods should work without ModLoader being installed<br/>" +
"Because ForgeModLoader is 100% compatible with ModLoader<br/>" +
"Re-install Minecraft Forge or Forge ModLoader into a clean<br/>" +
"jar and try again.",
"ForgeModLoader critical error",
JOptionPane.ERROR_MESSAGE);
throw new RuntimeException("Invalid ModLoader class detected");
}
return null;
}
@Override
public void injectData(Map<String, Object> data)
{
cl = (RelaunchClassLoader) data.get("classLoader");
}
}

View file

@ -0,0 +1,22 @@
package cpw.mods.fml.relauncher;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* This call hook allows for code to execute at the very early stages of
* minecraft initialization. FML uses it to validate that there is a
* safe environment for further loading of FML.
*
* @author cpw
*
*/
public interface IFMLCallHook extends Callable<Void>
{
/**
* Injected with data from the FML environment:
* "classLoader" : The FML Class Loader
* @param data
*/
void injectData(Map<String,Object> data);
}

View file

@ -1,5 +1,7 @@
package cpw.mods.fml.relauncher; package cpw.mods.fml.relauncher;
import java.util.Map;
/** /**
* The base plugin that provides class name meta information to FML to * The base plugin that provides class name meta information to FML to
* enhance the classloading lifecycle for mods in FML * enhance the classloading lifecycle for mods in FML
@ -20,4 +22,34 @@ public interface IFMLLoadingPlugin
* @return * @return
*/ */
String[] getASMTransformerClass(); String[] getASMTransformerClass();
/**
* Return a class name that implements "ModContainer" for injection into the mod list
* The "getName" function should return a name that other mods can, if need be,
* depend on.
* Trivially, this modcontainer will be loaded before all regular mod containers,
* which means it will be forced to be "immutable" - not susceptible to normal
* sorting behaviour.
* All other mod behaviours are available however- this container can receive and handle
* normal loading events
*/
String getModContainerClass();
/**
* Return the class name of an implementor of "IFMLCallHook", that will be run, in the
* main thread, to perform any additional setup this coremod may require. It will be
* run <strong>prior</strong> to Minecraft starting, so it CANNOT operate on minecraft
* itself. The game will deliberately crash if this code is detected to trigger a
* minecraft class loading (TODO: implement crash ;) )
*/
String getSetupClass();
/**
* Inject coremod data into this coremod
* This data includes:
* "mcLocation" : the location of the minecraft directory,
* "coremodList" : the list of coremods
* "coremodLocation" : the file this coremod loaded from,
*/
void injectData(Map<String, Object> data);
} }

View file

@ -2,6 +2,7 @@ package cpw.mods.fml.relauncher;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
@ -79,7 +80,7 @@ public class RelaunchClassLoader extends URLClassLoader
try try
{ {
byte[] basicClass = readFully(findResource(name.replace('.', '/').concat(".class")).openStream()); byte[] basicClass = getClassBytes(name);
byte[] transformedClass = runTransformers(name, basicClass); byte[] transformedClass = runTransformers(name, basicClass);
Class<?> cl = defineClass(name, transformedClass, 0, transformedClass.length); Class<?> cl = defineClass(name, transformedClass, 0, transformedClass.length);
cachedClasses.put(name, cl); cachedClasses.put(name, cl);
@ -91,6 +92,40 @@ public class RelaunchClassLoader extends URLClassLoader
} }
} }
/**
* @param name
* @return
* @throws IOException
*/
public byte[] getClassBytes(String name) throws IOException
{
InputStream classStream = null;
try
{
URL classResource = findResource(name.replace('.', '/').concat(".class"));
if (classResource == null)
{
return null;
}
classStream = classResource.openStream();
return readFully(classStream);
}
finally
{
if (classStream != null)
{
try
{
classStream.close();
}
catch (IOException e)
{
// Swallow the close exception
}
}
}
}
private byte[] runTransformers(String name, byte[] basicClass) private byte[] runTransformers(String name, byte[] basicClass)
{ {
for (IClassTransformer transformer : transformers) for (IClassTransformer transformer : transformers)

View file

@ -14,6 +14,7 @@ import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer; import java.nio.MappedByteBuffer;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
@ -23,7 +24,9 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.jar.Attributes; import java.util.jar.Attributes;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
@ -40,10 +43,14 @@ public class RelaunchLibraryManager
private static String[] rootPlugins = { "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 final String HEXES = "0123456789abcdef";
private static List<String> loadedLibraries = new ArrayList<String>(); private static List<String> loadedLibraries = new ArrayList<String>();
private static Map<IFMLLoadingPlugin, File> pluginLocations;
private static List<IFMLLoadingPlugin> loadPlugins;
private static List<ILibrarySet> libraries;
public static void handleLaunch(File mcDir, RelaunchClassLoader actualClassLoader) public static void handleLaunch(File mcDir, RelaunchClassLoader actualClassLoader)
{ {
List<IFMLLoadingPlugin> loadPlugins = new ArrayList<IFMLLoadingPlugin>(); pluginLocations = new HashMap<IFMLLoadingPlugin, File>();
List<ILibrarySet> libraries = new ArrayList<ILibrarySet>(); loadPlugins = new ArrayList<IFMLLoadingPlugin>();
libraries = new ArrayList<ILibrarySet>();
for (String s : rootPlugins) for (String s : rootPlugins)
{ {
try try
@ -189,11 +196,42 @@ public class RelaunchLibraryManager
} }
} }
} }
Map<String,Object> data = new HashMap<String,Object>();
data.put("mcLocation", mcDir);
data.put("coremodList", loadPlugins);
for (IFMLLoadingPlugin plugin : loadPlugins)
{
data.put("coremodLocation", pluginLocations.get(plugin));
plugin.injectData(data);
String setupClass = plugin.getSetupClass();
if (setupClass != null)
{
try
{
IFMLCallHook call = (IFMLCallHook) Class.forName(setupClass, true, actualClassLoader).newInstance();
Map<String,Object> callData = new HashMap<String, Object>();
callData.put("classLoader", actualClassLoader);
call.injectData(callData);
call.call();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
String modContainer = plugin.getModContainerClass();
if (modContainer != null)
{
FMLInjectionData.containers.add(modContainer);
}
}
try try
{ {
Class<?> loaderClazz = Class.forName("cpw.mods.fml.common.Loader", true, actualClassLoader); Class<?> loaderClazz = Class.forName("cpw.mods.fml.common.Loader", true, actualClassLoader);
Method m = loaderClazz.getMethod("injectData", Object[].class); Method m = loaderClazz.getMethod("injectData", Object[].class);
m.invoke(null, (Object)FMLVersionData.data()); m.invoke(null, (Object)FMLInjectionData.data());
} }
catch (Exception e) catch (Exception e)
{ {
@ -270,6 +308,7 @@ public class RelaunchLibraryManager
Class<?> coreModClass = Class.forName(fmlCorePlugin, true, classLoader); Class<?> coreModClass = Class.forName(fmlCorePlugin, true, classLoader);
IFMLLoadingPlugin plugin = (IFMLLoadingPlugin) coreModClass.newInstance(); IFMLLoadingPlugin plugin = (IFMLLoadingPlugin) coreModClass.newInstance();
loadPlugins.add(plugin); loadPlugins.add(plugin);
pluginLocations .put(plugin, coreMod);
if (plugin.getLibraryRequestClass()!=null) if (plugin.getLibraryRequestClass()!=null)
{ {
for (String libName : plugin.getLibraryRequestClass()) for (String libName : plugin.getLibraryRequestClass())

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path="common"/> <classpathentry kind="src" path="common"/>
<classpathentry kind="src" path="src-common"/>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="src-common"/>
<classpathentry kind="src" path="transformers"/> <classpathentry kind="src" path="transformers"/>
<classpathentry kind="src" path="client"/> <classpathentry kind="src" path="client"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>

View file

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

View file

@ -1,6 +1,6 @@
--- ../src-base/minecraft/net/minecraft/src/WorldType.java --- ../src-base/minecraft/net/minecraft/src/WorldType.java
+++ ../src-work/minecraft/net/minecraft/src/WorldType.java +++ ../src-work/minecraft/net/minecraft/src/WorldType.java
@@ -1,4 +1,14 @@ @@ -1,7 +1,20 @@
package net.minecraft.src; package net.minecraft.src;
+ +
+import java.util.Arrays; +import java.util.Arrays;
@ -15,19 +15,23 @@
public class WorldType public class WorldType
{ {
@@ -12,6 +22,11 @@
private boolean field_77140_h;
private boolean field_77141_i;
+ protected BiomeGenBase[] biomesForWorldType;
+
+ public static final BiomeGenBase[] base11Biomes = new BiomeGenBase[] {BiomeGenBase.field_76769_d, BiomeGenBase.field_76767_f, BiomeGenBase.field_76770_e, BiomeGenBase.field_76780_h, BiomeGenBase.field_76772_c, BiomeGenBase.field_76768_g}; + public static final BiomeGenBase[] base11Biomes = new BiomeGenBase[] {BiomeGenBase.field_76769_d, BiomeGenBase.field_76767_f, BiomeGenBase.field_76770_e, BiomeGenBase.field_76780_h, BiomeGenBase.field_76772_c, BiomeGenBase.field_76768_g};
+ public static final BiomeGenBase[] base12Biomes = ObjectArrays.concat(base11Biomes, BiomeGenBase.field_76782_w); + public static final BiomeGenBase[] base12Biomes = ObjectArrays.concat(base11Biomes, BiomeGenBase.field_76782_w);
+ +
public static final WorldType[] field_77139_a = new WorldType[16];
public static final WorldType field_77137_b = (new WorldType(0, "default", 1)).func_77129_f();
public static final WorldType field_77138_c = new WorldType(1, "flat");
@@ -11,6 +24,9 @@
private final int field_77134_g;
private boolean field_77140_h;
private boolean field_77141_i;
+
+ protected BiomeGenBase[] biomesForWorldType;
+
private WorldType(int p_i3737_1_, String p_i3737_2_) private WorldType(int p_i3737_1_, String p_i3737_2_)
{ {
this(p_i3737_1_, p_i3737_2_, 0); @@ -23,6 +39,14 @@
@@ -23,6 +38,14 @@
this.field_77134_g = p_i3738_3_; this.field_77134_g = p_i3738_3_;
this.field_77140_h = true; this.field_77140_h = true;
field_77139_a[p_i3738_1_] = this; field_77139_a[p_i3738_1_] = this;
@ -42,7 +46,7 @@
} }
public String func_77127_a() public String func_77127_a()
@@ -84,4 +107,63 @@ @@ -84,4 +108,63 @@
return null; return null;
} }

View file

@ -1,6 +1,6 @@
--- ../src-base/minecraft_server/net/minecraft/src/WorldType.java --- ../src-base/minecraft_server/net/minecraft/src/WorldType.java
+++ ../src-work/minecraft_server/net/minecraft/src/WorldType.java +++ ../src-work/minecraft_server/net/minecraft/src/WorldType.java
@@ -1,4 +1,14 @@ @@ -1,7 +1,19 @@
package net.minecraft.src; package net.minecraft.src;
+ +
+import java.util.Arrays; +import java.util.Arrays;
@ -15,18 +15,21 @@
public class WorldType public class WorldType
{ {
@@ -12,6 +22,11 @@
private boolean field_77140_h;
private boolean field_77141_i;
+ protected BiomeGenBase[] biomesForWorldType;
+
+ public static final BiomeGenBase[] base11Biomes = new BiomeGenBase[] {BiomeGenBase.field_76769_d, BiomeGenBase.field_76767_f, BiomeGenBase.field_76770_e, BiomeGenBase.field_76780_h, BiomeGenBase.field_76772_c, BiomeGenBase.field_76768_g}; + public static final BiomeGenBase[] base11Biomes = new BiomeGenBase[] {BiomeGenBase.field_76769_d, BiomeGenBase.field_76767_f, BiomeGenBase.field_76770_e, BiomeGenBase.field_76780_h, BiomeGenBase.field_76772_c, BiomeGenBase.field_76768_g};
+ public static final BiomeGenBase[] base12Biomes = ObjectArrays.concat(base11Biomes, BiomeGenBase.field_76782_w); + public static final BiomeGenBase[] base12Biomes = ObjectArrays.concat(base11Biomes, BiomeGenBase.field_76782_w);
public static final WorldType[] field_77139_a = new WorldType[16];
public static final WorldType field_77137_b = (new WorldType(0, "default", 1)).func_77129_f();
public static final WorldType field_77138_c = new WorldType(1, "flat");
@@ -11,6 +23,9 @@
private final int field_77134_g;
private boolean field_77140_h;
private boolean field_77141_i;
+ +
+ protected BiomeGenBase[] biomesForWorldType;
+
private WorldType(int p_i3737_1_, String p_i3737_2_) private WorldType(int p_i3737_1_, String p_i3737_2_)
{ {
this(p_i3737_1_, p_i3737_2_, 0);
@@ -23,6 +38,14 @@ @@ -23,6 +38,14 @@
this.field_77134_g = p_i3738_3_; this.field_77134_g = p_i3738_3_;
this.field_77140_h = true; this.field_77140_h = true;