package io.gitlab.jfronny.modsmod; import net.fabricmc.loader.FabricLoader; import net.fabricmc.loader.ModContainer; import net.fabricmc.loader.discovery.ModCandidate; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class FabricLoaderInterface { public static final Logger logger = LogManager.getLogger("modsmod"); private static final Method addModMethod; private static final Field modsField; //private static final Field abstractListModCount; static { try { addModMethod = FabricLoader.class.getDeclaredMethod("addMod", ModCandidate.class); addModMethod.setAccessible(true); modsField = FabricLoader.class.getDeclaredField("mods"); modsField.setAccessible(true); //abstractListModCount = AbstractList.class.getDeclaredField("modCount"); //abstractListModCount.setAccessible(true); } catch (NoSuchMethodException | NoSuchFieldException e) { logger.error("Failed to get reference to fabric-loader internals. The fabric-loader version may be incompatible with patchwork-runtime.", e); throw new IllegalStateException(e); } } public static void synchronize(FabricLoader fabricLoader) { try { modsField.set(fabricLoader, new IteratorCallbackList((List)modsField.get(fabricLoader), (s) -> { try { modsField.set(fabricLoader, s); } catch (IllegalAccessException e) { logger.error("Failed to reset mods field", e); e.printStackTrace(); } })); } catch (IllegalAccessException e) { logger.error("Failed to make mods list synchronized.", e); throw new IllegalStateException(e); } } public static void addMod(FabricLoader fabricLoader, ModCandidate modCandidate) { try { addModMethod.invoke(fabricLoader, modCandidate); } catch (IllegalAccessException | InvocationTargetException e) { logger.error("Failed to inject mod into fabric-loader.", e); throw new IllegalStateException(e); } } public static List getMods(FabricLoader fabricLoader) { try { return (List) modsField.get(fabricLoader); } catch (IllegalAccessException e) { logger.error("Failed to get mods from fabric-loader.", e); throw new IllegalStateException(e); } } }