From e65218b525008e25b1b34f3eb8f20775d19c9b45 Mon Sep 17 00:00:00 2001 From: LexManos Date: Sun, 29 May 2016 02:37:37 -0700 Subject: [PATCH] Fixed new ICrashReportDetail loader working with packaged mods by delaying it until the ModContainer's construct event. Closes #2924 --- .../common/ForgeModContainer.java | 49 +++++++++++++++--- .../minecraftforge/common/MinecraftForge.java | 50 +++++++++++++++++++ .../fml/common/FMLModContainer.java | 5 ++ .../net/minecraftforge/fml/common/Loader.java | 30 ----------- .../common/discovery/DirectoryDiscoverer.java | 2 +- .../common/discovery/asm/ASMModParser.java | 2 +- 6 files changed, 100 insertions(+), 38 deletions(-) diff --git a/src/main/java/net/minecraftforge/common/ForgeModContainer.java b/src/main/java/net/minecraftforge/common/ForgeModContainer.java index 6ec37cd47..1c3aa8fed 100644 --- a/src/main/java/net/minecraftforge/common/ForgeModContainer.java +++ b/src/main/java/net/minecraftforge/common/ForgeModContainer.java @@ -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 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 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; } + } diff --git a/src/main/java/net/minecraftforge/common/MinecraftForge.java b/src/main/java/net/minecraftforge/common/MinecraftForge.java index a7cc2ccf9..edaa4fb37 100644 --- a/src/main/java/net/minecraftforge/common/MinecraftForge.java +++ b/src/main/java/net/minecraftforge/common/MinecraftForge.java @@ -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 classes) + { + //Find all ICrashReportDetail's handlers and preload them. + List 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(); + } + } } } diff --git a/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java b/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java index 8cc40bfe9..811b82d9d 100644 --- a/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java +++ b/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java @@ -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(); diff --git a/src/main/java/net/minecraftforge/fml/common/Loader.java b/src/main/java/net/minecraftforge/fml/common/Loader.java index 50f348ebf..a7be45d78 100644 --- a/src/main/java/net/minecraftforge/fml/common/Loader.java +++ b/src/main/java/net/minecraftforge/fml/common/Loader.java @@ -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 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){} - } - } } diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java b/src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java index 2ed403cbf..ef3bbcb44 100644 --- a/src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java +++ b/src/main/java/net/minecraftforge/fml/common/discovery/DirectoryDiscoverer.java @@ -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()); diff --git a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java b/src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java index 00a74f90f..f0bdd5e20 100644 --- a/src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java +++ b/src/main/java/net/minecraftforge/fml/common/discovery/asm/ASMModParser.java @@ -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); } }