ModsMod/src/main/java/io/gitlab/jfronny/modsmod/FabricLoaderInterface.java

60 lines
2.2 KiB
Java

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.List;
public class FabricLoaderInterface {
public static final Logger logger = LogManager.getLogger(ModsMod.MOD_ID);
private static final Method addModMethod;
private static final Field modsField;
static {
try {
addModMethod = FabricLoader.class.getDeclaredMethod("addMod", ModCandidate.class);
addModMethod.setAccessible(true);
modsField = FabricLoader.class.getDeclaredField("mods");
modsField.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<ModContainer>)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);
}
}
}