From 6d5ed23a86f0a421c356ef48a69b318b5a30c8d8 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 3 May 2024 13:59:59 -0400 Subject: [PATCH] Fix mod detection --- .../helpers/CascadeDetectionHelper.java | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/embeddedt/archaicfix/helpers/CascadeDetectionHelper.java b/src/main/java/org/embeddedt/archaicfix/helpers/CascadeDetectionHelper.java index 43ced63..dc70d67 100644 --- a/src/main/java/org/embeddedt/archaicfix/helpers/CascadeDetectionHelper.java +++ b/src/main/java/org/embeddedt/archaicfix/helpers/CascadeDetectionHelper.java @@ -1,21 +1,64 @@ package org.embeddedt.archaicfix.helpers; +import com.google.common.collect.ListMultimap; +import cpw.mods.fml.common.LoadController; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ModContainer; +import cpw.mods.fml.relauncher.ReflectionHelper; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.IChunkProvider; import org.embeddedt.archaicfix.ArchaicLogger; import org.embeddedt.archaicfix.config.ArchaicConfig; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.util.LinkedList; +import java.util.List; public class CascadeDetectionHelper { private static final ThreadLocal> arch$populatingChunk = ThreadLocal.withInitial(LinkedList::new); + private static final LoadController controller = ReflectionHelper.getPrivateValue(Loader.class, Loader.instance(), "modController"); + private static final ListMultimap packageOwners = ReflectionHelper.getPrivateValue(LoadController.class, controller, "packageOwners"); + private static final MethodHandle callingStackGetter; + + static { + try { + callingStackGetter = MethodHandles.publicLookup().unreflect(ReflectionHelper.findMethod(LoadController.class, controller, new String[] { "getCallingStack" })); + } catch(ReflectiveOperationException e) { + throw new AssertionError(e); + } + } + + private static Class[] getCallingStack() { + try { + return (Class[])callingStackGetter.invokeExact(); + } catch(Throwable e) { + return new Class[0]; + } + } + + private static ModContainer findModContainer() { + for(Class clz : getCallingStack()) { + if(clz.getName().startsWith("net.minecraft") || clz.getName().startsWith("org.embeddedt.archaicfix")) { + continue; + } + int idx = clz.getName().lastIndexOf('.'); + if(idx == -1) { + continue; + } + String pkg = clz.getName().substring(0, idx); + List containers = packageOwners.get(pkg); + if(containers != null) { + return containers.get(0); + } + } + return null; + } + private static void logCascadingWorldGeneration(Chunk chunk, LinkedList stack) { - ModContainer activeModContainer = Loader.instance().activeModContainer(); + ModContainer activeModContainer = findModContainer(); String format = "{} loaded a new chunk {} in dimension {} ({}) while populating chunk {}, causing cascading worldgen lag."; ChunkCoordIntPair pos = new ChunkCoordIntPair(chunk.xPosition, chunk.zPosition);