Fixed new ICrashReportDetail loader working with packaged mods by delaying it until the ModContainer's construct event. Closes #2924
This commit is contained in:
parent
d3e758fce6
commit
e65218b525
6 changed files with 100 additions and 38 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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){}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue