Fixed new ICrashReportDetail loader working with packaged mods by delaying it until the ModContainer's construct event. Closes #2924

This commit is contained in:
LexManos 2016-05-29 02:37:37 -07:00
parent d3e758fce6
commit e65218b525
6 changed files with 100 additions and 38 deletions

View file

@ -14,10 +14,17 @@ import java.net.URL;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.logging.log4j.Level;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.ICrashReportDetail;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.stats.StatList;
@ -37,6 +44,7 @@ import net.minecraftforge.oredict.RecipeSorter;
import net.minecraftforge.server.command.ForgeCommand;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
@ -45,10 +53,13 @@ import net.minecraftforge.fml.client.FMLFolderResourcePack;
import net.minecraftforge.fml.client.event.ConfigChangedEvent.OnConfigChangedEvent;
import net.minecraftforge.fml.common.DummyModContainer;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.ICrashCallable;
import net.minecraftforge.fml.common.LoadController;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.ModMetadata;
import net.minecraftforge.fml.common.WorldAccessContainer;
import net.minecraftforge.fml.common.discovery.ASMDataTable;
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;
import net.minecraftforge.fml.common.event.FMLConstructionEvent;
import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent;
import net.minecraftforge.fml.common.event.FMLModIdMappingEvent;
@ -323,6 +334,36 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
@Subscribe
public void modConstruction(FMLConstructionEvent evt)
{
List<String> all = Lists.newArrayList();
for (ASMData asm : evt.getASMHarvestedData().getAll(ICrashReportDetail.class.getName().replace('.', '/')))
all.add(asm.getClassName());
for (ASMData asm : evt.getASMHarvestedData().getAll(ICrashCallable.class.getName().replace('.', '/')))
all.add(asm.getClassName());
Iterator<String> itr = all.iterator();
while (itr.hasNext())
{
String cls = itr.next();
if (!cls.startsWith("net/minecraft/") &&
!cls.startsWith("net/minecraftforge/"))
itr.remove();
}
FMLLog.log("Forge", Level.DEBUG, "Preloading CrashReport Classes");
Collections.sort(all); //Sort it because I like pretty output ;)
for (String name : all)
{
FMLLog.log("Forge", Level.DEBUG, "\t" + name);
try
{
Class.forName(name.replace('/', '.'), false, MinecraftForge.class.getClassLoader());
}
catch (Exception e)
{
e.printStackTrace();
}
}
NetworkRegistry.INSTANCE.register(this, this.getClass(), "*", evt.getASMHarvestedData());
ForgeNetworkHandler.registerChannel(this, evt.getSide());
}
@ -351,12 +392,6 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
}
}
@Subscribe
public void mappingChange(FMLModIdMappingEvent evt)
{
StatList.reinit();
}
@Subscribe
public void postInit(FMLPostInitializationEvent evt)
{
@ -400,6 +435,7 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
public void mappingChanged(FMLModIdMappingEvent evt)
{
OreDictionary.rebakeMap();
StatList.reinit();
}
@ -469,4 +505,5 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
{
return updateJSONUrl;
}
}

View file

@ -1,8 +1,22 @@
package net.minecraftforge.common;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.ICrashCallable;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.discovery.ASMDataTable;
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;
import net.minecraftforge.fml.common.eventhandler.EventBus;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.apache.logging.log4j.Level;
import com.google.common.collect.Lists;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.ICrashReportDetail;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.ForgeHooks.SeedEntry;
import net.minecraftforge.fluids.FluidRegistry;
@ -56,5 +70,41 @@ public class MinecraftForge
// Load before all the mods, so MC owns the MC fluids
FluidRegistry.validateFluidRegistry();
ForgeHooks.initTools();
//For all the normal CrashReport classes to be defined. We're in MC's classloader so this should all be fine
new CrashReport("ThisIsFake", new Exception("Not real"));
}
public static void preloadCrashClasses(ASMDataTable table, String modID, Set<String> classes)
{
//Find all ICrashReportDetail's handlers and preload them.
List<String> all = Lists.newArrayList();
for (ASMData asm : table.getAll(ICrashReportDetail.class.getName().replace('.', '/')))
all.add(asm.getClassName());
for (ASMData asm : table.getAll(ICrashCallable.class.getName().replace('.', '/')))
all.add(asm.getClassName());
all.retainAll(classes);
if (all.size() == 0)
return;
FMLLog.log(modID, Level.DEBUG, "Preloading CrashReport Classes");
Collections.sort(all); //Sort it because I like pretty output ;)
for (String name : all)
{
FMLLog.log(modID, Level.DEBUG, "\t" + name);
try
{
Class.forName(name.replace('/', '.'), false, MinecraftForge.class.getClassLoader());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}

View file

@ -27,6 +27,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.Mod.Metadata;
import net.minecraftforge.fml.common.asm.transformers.BlamingTransformer;
@ -466,6 +467,10 @@ public class FMLModContainer implements ModContainer
ModClassLoader modClassLoader = event.getModClassLoader();
modClassLoader.addFile(source);
modClassLoader.clearNegativeCacheFor(candidate.getClassList());
//Only place I could think to add this...
MinecraftForge.preloadCrashClasses(event.getASMHarvestedData(), getModId(), candidate.getClassList());
Class<?> clazz = Class.forName(className, true, modClassLoader);
Certificate[] certificates = clazz.getProtectionDomain().getCodeSource().getCertificates();

View file

@ -521,7 +521,6 @@ public class Loader
}
}
}
preloadCrashClasses();
modController.transition(LoaderState.CONSTRUCTING, false);
modController.distributeStateMessage(LoaderState.CONSTRUCTING, modClassLoader, discoverer.getASMTable(), reverseDependencies);
@ -1118,33 +1117,4 @@ public class Loader
{
return modController != null ? modController.getState() : LoaderState.NOINIT;
}
private void preloadCrashClasses()
{
//For all the normal CrashReport classes to be defined. We're in MC's classloader so this should all be fine
new CrashReport("ThisIsFake", new Exception("Not real"));
FMLLog.log(Level.DEBUG, "Preloading CrashReport Classes");
//Find all ICrashReportDetail's handlers and preload them.
List<String> classes = Lists.newArrayList();
for (ASMData asm : discoverer.getASMTable().getAll(ICrashReportDetail.class.getName().replace('.', '/')))
{
classes.add(asm.getClassName());
}
for (ASMData asm : discoverer.getASMTable().getAll(ICrashCallable.class.getName().replace('.', '/')))
{
classes.add(asm.getClassName());
}
Collections.sort(classes); //Sort it because I like pretty output ;)
for (String name : classes)
{
FMLLog.log(Level.DEBUG, "\t" + name);
try
{
Class<?> cls = Class.forName(name, false, getClass().getClassLoader());
}
catch (Exception e){}
}
}
}

View file

@ -86,7 +86,7 @@ public class DirectoryDiscoverer implements ITypeDiscoverer
if (file.isDirectory())
{
FMLLog.finer("Recursing into package %s", path + file.getName());
exploreFileSystem(path + file.getName() + ".", file, harvestedMods, candidate, mc);
exploreFileSystem(path + file.getName() + "/", file, harvestedMods, candidate, mc);
continue;
}
Matcher match = classFile.matcher(file.getName());

View file

@ -154,7 +154,7 @@ public class ASMModParser
for (String intf : interfaces)
{
table.addASMData(candidate, intf, this.asmType.getClassName(), null, null);
table.addASMData(candidate, intf, this.asmType.getInternalName(), null, null);
}
}