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:
parent
ae79c79447
commit
e39092335a
|
@ -322,7 +322,6 @@ public class FMLClientHandler implements IFMLSidedHandler
|
|||
*/
|
||||
public void addSpecialModEntries(ArrayList<ModContainer> mods)
|
||||
{
|
||||
mods.add(new FMLDummyContainer());
|
||||
if (optifineContainer!=null) {
|
||||
mods.add(optifineContainer);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import net.minecraft.client.Minecraft;
|
|||
|
||||
public class EntityRendererProxy extends EntityRenderer
|
||||
{
|
||||
|
||||
public static final String fmlMarker = "This is an FML marker";
|
||||
private Minecraft game;
|
||||
|
||||
public EntityRendererProxy(Minecraft minecraft)
|
||||
|
|
|
@ -42,6 +42,7 @@ import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
|||
|
||||
public class ModLoader
|
||||
{
|
||||
public static final String fmlMarker = "This is an FML marker";
|
||||
// TODO dirty workaround for millinaire
|
||||
@Deprecated
|
||||
public static final Map<String,Map<String,String>> localizedStrings=Collections.emptyMap();
|
||||
|
|
|
@ -117,4 +117,9 @@ public class DummyModContainer implements ModContainer
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImmutable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ package cpw.mods.fml.common;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
|
@ -41,4 +43,10 @@ public class FMLDummyContainer extends DummyModContainer
|
|||
meta.screenshots=new String[0];
|
||||
meta.logoFile="";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerBus(EventBus bus, LoadController controller)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,4 +311,9 @@ public class FMLModContainer implements ModContainer
|
|||
}
|
||||
return processedVersion;
|
||||
}
|
||||
@Override
|
||||
public boolean isImmutable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ import com.google.common.eventbus.EventBus;
|
|||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.event.FMLLoadEvent;
|
||||
import cpw.mods.fml.common.event.FMLStateEvent;
|
||||
|
||||
public class LoadController
|
||||
|
@ -34,10 +35,16 @@ public class LoadController
|
|||
public LoadController(Loader loader)
|
||||
{
|
||||
this.loader = loader;
|
||||
this.modList = loader.getIndexedModList();
|
||||
this.masterChannel = new EventBus("FMLMainChannel");
|
||||
this.masterChannel.register(this);
|
||||
|
||||
state = LoaderState.NOINIT;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void buildModList(FMLLoadEvent event)
|
||||
{
|
||||
this.modList = loader.getIndexedModList();
|
||||
Builder<String, EventBus> eventBus = ImmutableMap.builder();
|
||||
|
||||
for (ModContainer mod : loader.getModList())
|
||||
|
@ -60,8 +67,6 @@ public class LoadController
|
|||
}
|
||||
|
||||
eventChannels = eventBus.build();
|
||||
|
||||
state = LoaderState.NOINIT;
|
||||
}
|
||||
|
||||
public void distributeStateMessage(LoaderState state, Object... eventData)
|
||||
|
@ -141,4 +146,17 @@ public class LoadController
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ import com.google.common.collect.Maps;
|
|||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.discovery.ContainerType;
|
||||
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.toposort.ModSorter;
|
||||
import cpw.mods.fml.common.toposort.ModSortingException;
|
||||
|
@ -131,6 +132,7 @@ public class Loader
|
|||
private LoadController modController;
|
||||
|
||||
private static File minecraftDir;
|
||||
private static List<String> injectedContainers;
|
||||
|
||||
public static Loader instance()
|
||||
{
|
||||
|
@ -151,6 +153,7 @@ public class Loader
|
|||
mccversion = (String) data[4];
|
||||
mcsversion = (String) data[5];
|
||||
minecraftDir = (File) data[6];
|
||||
injectedContainers = (List<String>)data[7];
|
||||
}
|
||||
|
||||
private Loader()
|
||||
|
@ -214,7 +217,10 @@ public class Loader
|
|||
FMLLog.fine("Mod sorting data:");
|
||||
for (ModContainer mod : mods)
|
||||
{
|
||||
FMLLog.fine("\t%s(%s): %s (%s)", mod.getModId(), mod.getName(), mod.getSource().getName(), mod.getSortingRules());
|
||||
if (!mod.isImmutable())
|
||||
{
|
||||
FMLLog.fine("\t%s(%s): %s (%s)", mod.getModId(), mod.getName(), mod.getSource().getName(), mod.getSortingRules());
|
||||
}
|
||||
}
|
||||
if (mods.size()==0)
|
||||
{
|
||||
|
@ -247,6 +253,21 @@ public class Loader
|
|||
*/
|
||||
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();
|
||||
FMLLog.fine("Attempting to load mods contained in the minecraft jar file and associated classes");
|
||||
discoverer.findClasspathMods(modClassLoader);
|
||||
|
@ -255,7 +276,7 @@ public class Loader
|
|||
FMLLog.info("Searching %s for mods", canonicalModsDir.getAbsolutePath());
|
||||
discoverer.findModDirMods(canonicalModsDir);
|
||||
|
||||
mods = discoverer.identifyMods();
|
||||
mods.addAll(discoverer.identifyMods());
|
||||
namedMods = Maps.uniqueIndex(mods, new ModIdFunction());
|
||||
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();
|
||||
sortModList();
|
||||
mods = ImmutableList.copyOf(mods);
|
||||
modController.distributeStateMessage(FMLLoadEvent.class);
|
||||
modController.transition(LoaderState.CONSTRUCTING);
|
||||
modController.distributeStateMessage(LoaderState.CONSTRUCTING, modClassLoader);
|
||||
modController.transition(LoaderState.PREINITIALIZATION);
|
||||
|
|
|
@ -148,4 +148,6 @@ public interface ModContainer
|
|||
ArtifactVersion getProcessedVersion();
|
||||
|
||||
ProxyInjector findSidedProxy();
|
||||
|
||||
boolean isImmutable();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package cpw.mods.fml.common.event;
|
||||
|
||||
public class FMLLoadEvent
|
||||
{
|
||||
|
||||
}
|
|
@ -558,4 +558,10 @@ public class ModLoaderModContainer implements ModContainer
|
|||
}
|
||||
return processedVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImmutable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cpw.mods.fml.common.DummyModContainer;
|
||||
import cpw.mods.fml.common.FMLModContainer;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
@ -35,6 +37,8 @@ public class ModSorter
|
|||
private ModContainer before = new DummyModContainer();
|
||||
private ModContainer after = new DummyModContainer();
|
||||
|
||||
private List<ModContainer> immutableMods;
|
||||
|
||||
public ModSorter(List<ModContainer> modList, Map<String, ModContainer> nameLookup)
|
||||
{
|
||||
buildGraph(modList, nameLookup);
|
||||
|
@ -43,6 +47,7 @@ public class ModSorter
|
|||
private void buildGraph(List<ModContainer> modList, Map<String, ModContainer> nameLookup)
|
||||
{
|
||||
modGraph = new DirectedGraph<ModContainer>();
|
||||
immutableMods = Lists.newArrayList();
|
||||
modGraph.addNode(beforeAll);
|
||||
modGraph.addNode(before);
|
||||
modGraph.addNode(afterAll);
|
||||
|
@ -53,11 +58,20 @@ public class ModSorter
|
|||
|
||||
for (ModContainer mod : modList)
|
||||
{
|
||||
modGraph.addNode(mod);
|
||||
if (!mod.isImmutable())
|
||||
{
|
||||
modGraph.addNode(mod);
|
||||
}
|
||||
else
|
||||
{
|
||||
immutableMods.add(mod);
|
||||
}
|
||||
}
|
||||
|
||||
for (ModContainer mod : modList)
|
||||
{
|
||||
if (mod.isImmutable())
|
||||
continue;
|
||||
boolean preDepAdded = false;
|
||||
boolean postDepAdded = false;
|
||||
|
||||
|
@ -117,6 +131,7 @@ public class ModSorter
|
|||
{
|
||||
List<ModContainer> sortedList = TopologicalSort.topologicalSort(modGraph);
|
||||
sortedList.removeAll(Arrays.asList(new ModContainer[] {beforeAll, before, after, afterAll}));
|
||||
return sortedList;
|
||||
immutableMods.addAll(sortedList);
|
||||
return immutableMods;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package cpw.mods.fml.relauncher;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class FMLCorePlugin implements IFMLLoadingPlugin
|
||||
{
|
||||
@Override
|
||||
|
@ -13,4 +15,22 @@ public class FMLCorePlugin implements IFMLLoadingPlugin
|
|||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,12 @@ package cpw.mods.fml.relauncher;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class FMLVersionData
|
||||
public class FMLInjectionData
|
||||
{
|
||||
static File minecraftHome;
|
||||
static String major;
|
||||
|
@ -15,6 +17,7 @@ public class FMLVersionData
|
|||
static String build;
|
||||
static String mccversion;
|
||||
static String mcsversion;
|
||||
public static List<String> containers = new ArrayList<String>();
|
||||
|
||||
static void build(File mcHome, RelaunchClassLoader classLoader)
|
||||
{
|
||||
|
@ -46,6 +49,6 @@ public class FMLVersionData
|
|||
|
||||
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 };
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ public class FMLRelauncher
|
|||
private Object newApplet;
|
||||
private Class<? super Object> appletClass;
|
||||
|
||||
private JDialog popupWindow;
|
||||
JDialog popupWindow;
|
||||
|
||||
public static void handleClientRelaunch(ArgsWrapper wrap)
|
||||
{
|
||||
|
@ -128,8 +128,8 @@ public class FMLRelauncher
|
|||
|
||||
private void setupHome(File minecraftHome)
|
||||
{
|
||||
FMLVersionData.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);
|
||||
FMLInjectionData.build(minecraftHome, classLoader);
|
||||
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
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package cpw.mods.fml.relauncher;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The base plugin that provides class name meta information to FML to
|
||||
* enhance the classloading lifecycle for mods in FML
|
||||
|
@ -20,4 +22,34 @@ public interface IFMLLoadingPlugin
|
|||
* @return
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package cpw.mods.fml.relauncher;
|
|||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
@ -79,7 +80,7 @@ public class RelaunchClassLoader extends URLClassLoader
|
|||
|
||||
try
|
||||
{
|
||||
byte[] basicClass = readFully(findResource(name.replace('.', '/').concat(".class")).openStream());
|
||||
byte[] basicClass = getClassBytes(name);
|
||||
byte[] transformedClass = runTransformers(name, basicClass);
|
||||
Class<?> cl = defineClass(name, transformedClass, 0, transformedClass.length);
|
||||
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)
|
||||
{
|
||||
for (IClassTransformer transformer : transformers)
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.net.MalformedURLException;
|
|||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
@ -23,7 +24,9 @@ import java.security.MessageDigest;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
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 final String HEXES = "0123456789abcdef";
|
||||
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)
|
||||
{
|
||||
List<IFMLLoadingPlugin> loadPlugins = new ArrayList<IFMLLoadingPlugin>();
|
||||
List<ILibrarySet> libraries = new ArrayList<ILibrarySet>();
|
||||
pluginLocations = new HashMap<IFMLLoadingPlugin, File>();
|
||||
loadPlugins = new ArrayList<IFMLLoadingPlugin>();
|
||||
libraries = new ArrayList<ILibrarySet>();
|
||||
for (String s : rootPlugins)
|
||||
{
|
||||
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
|
||||
{
|
||||
Class<?> loaderClazz = Class.forName("cpw.mods.fml.common.Loader", true, actualClassLoader);
|
||||
Method m = loaderClazz.getMethod("injectData", Object[].class);
|
||||
m.invoke(null, (Object)FMLVersionData.data());
|
||||
m.invoke(null, (Object)FMLInjectionData.data());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -270,6 +308,7 @@ public class RelaunchLibraryManager
|
|||
Class<?> coreModClass = Class.forName(fmlCorePlugin, true, classLoader);
|
||||
IFMLLoadingPlugin plugin = (IFMLLoadingPlugin) coreModClass.newInstance();
|
||||
loadPlugins.add(plugin);
|
||||
pluginLocations .put(plugin, coreMod);
|
||||
if (plugin.getLibraryRequestClass()!=null)
|
||||
{
|
||||
for (String libName : plugin.getLibraryRequestClass())
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="common"/>
|
||||
<classpathentry kind="src" path="src-common"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="src-common"/>
|
||||
<classpathentry kind="src" path="transformers"/>
|
||||
<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"/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src-common"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="src-common"/>
|
||||
<classpathentry kind="src" path="common"/>
|
||||
<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"/>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- ../src-base/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;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
|
@ -15,19 +15,23 @@
|
|||
|
||||
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[] 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_)
|
||||
{
|
||||
this(p_i3737_1_, p_i3737_2_, 0);
|
||||
@@ -23,6 +38,14 @@
|
||||
@@ -23,6 +39,14 @@
|
||||
this.field_77134_g = p_i3738_3_;
|
||||
this.field_77140_h = true;
|
||||
field_77139_a[p_i3738_1_] = this;
|
||||
|
@ -42,7 +46,7 @@
|
|||
}
|
||||
|
||||
public String func_77127_a()
|
||||
@@ -84,4 +107,63 @@
|
||||
@@ -84,4 +108,63 @@
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- ../src-base/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;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
|
@ -15,18 +15,21 @@
|
|||
|
||||
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[] 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_)
|
||||
{
|
||||
this(p_i3737_1_, p_i3737_2_, 0);
|
||||
@@ -23,6 +38,14 @@
|
||||
this.field_77134_g = p_i3738_3_;
|
||||
this.field_77140_h = true;
|
||||
|
|
Loading…
Reference in New Issue