diff --git a/src/main/java/net/fabricmc/api/FakeModProvider.java b/src/main/java/net/fabricmc/api/FakeModProvider.java
new file mode 100644
index 000000000..233e530c9
--- /dev/null
+++ b/src/main/java/net/fabricmc/api/FakeModProvider.java
@@ -0,0 +1,13 @@
+package net.fabricmc.api;
+
+import net.fabricmc.loader.api.ModContainer;
+
+import java.util.Collection;
+
+/**
+ * Hook for adding "fake" mod containers to Loader's list.
+ * Should run after {@link ModInitializer#onInitialize()}
+ */
+public interface FakeModProvider {
+ Collection getFakeMods();
+}
diff --git a/src/main/java/net/fabricmc/loader/FabricLoader.java b/src/main/java/net/fabricmc/loader/FabricLoader.java
index 82c157954..22334b1be 100644
--- a/src/main/java/net/fabricmc/loader/FabricLoader.java
+++ b/src/main/java/net/fabricmc/loader/FabricLoader.java
@@ -65,6 +65,8 @@ public class FabricLoader implements net.fabricmc.loader.api.FabricLoader {
protected final Map modMap = new HashMap<>();
protected List mods = new ArrayList<>();
+ protected final Map fakeModMap = new HashMap<>();
+ protected List fakeMods = new ArrayList<>();
private final Map adapterMap = new HashMap<>();
private final EntrypointStorage entrypointStorage = new EntrypointStorage();
@@ -242,9 +244,14 @@ public Collection getAllMods() {
return Collections.unmodifiableList(mods);
}
+ @Override
+ public Collection getFakeMods() {
+ return Collections.unmodifiableList(mods);
+ }
+
@Override
public boolean isModLoaded(String id) {
- return modMap.containsKey(id);
+ return modMap.containsKey(id) || fakeModMap.containsKey(id);
}
@Override
@@ -416,6 +423,13 @@ public void prepareModInit(File newRunDir, Object gameInstance) {
}
}
+ public void appendFakeMods(Collection mods) {
+ for (net.fabricmc.loader.api.ModContainer mod : mods) {
+ fakeModMap.put(mod.getMetadata().getId(), mod);
+ fakeMods.add(mod);
+ }
+ }
+
public Logger getLogger() {
return LOGGER;
}
diff --git a/src/main/java/net/fabricmc/loader/api/FabricLoader.java b/src/main/java/net/fabricmc/loader/api/FabricLoader.java
index b54264f8e..fcba42422 100644
--- a/src/main/java/net/fabricmc/loader/api/FabricLoader.java
+++ b/src/main/java/net/fabricmc/loader/api/FabricLoader.java
@@ -59,6 +59,12 @@ static FabricLoader getInstance() {
*/
Collection getAllMods();
+ /**
+ * Gets all mod containers added through {@link net.fabricmc.api.FakeModProvider}s.
+ * @return A collection of all added fake mod containers.
+ */
+ Collection getFakeMods();
+
/**
* Checks if a mod with a given ID is loaded.
* @param id The ID of the mod, as defined in fabric.mod.json.
diff --git a/src/main/java/net/fabricmc/loader/entrypoint/minecraft/hooks/EntrypointClient.java b/src/main/java/net/fabricmc/loader/entrypoint/minecraft/hooks/EntrypointClient.java
index 899c864a8..8a70b2f9b 100644
--- a/src/main/java/net/fabricmc/loader/entrypoint/minecraft/hooks/EntrypointClient.java
+++ b/src/main/java/net/fabricmc/loader/entrypoint/minecraft/hooks/EntrypointClient.java
@@ -17,6 +17,7 @@
package net.fabricmc.loader.entrypoint.minecraft.hooks;
import net.fabricmc.api.ClientModInitializer;
+import net.fabricmc.api.FakeModProvider;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.FabricLoader;
@@ -30,6 +31,7 @@ public static void start(File runDir, Object gameInstance) {
FabricLoader.INSTANCE.prepareModInit(runDir, gameInstance);
EntrypointUtils.invoke("main", ModInitializer.class, ModInitializer::onInitialize);
+ FabricLoader.INSTANCE.getEntrypoints("fake_mods", FakeModProvider.class).forEach(provider -> FabricLoader.INSTANCE.appendFakeMods(provider.getFakeMods()));
EntrypointUtils.invoke("client", ClientModInitializer.class, ClientModInitializer::onInitializeClient);
}
}
diff --git a/src/main/java/net/fabricmc/loader/entrypoint/minecraft/hooks/EntrypointServer.java b/src/main/java/net/fabricmc/loader/entrypoint/minecraft/hooks/EntrypointServer.java
index bd3ff323b..45a503d99 100644
--- a/src/main/java/net/fabricmc/loader/entrypoint/minecraft/hooks/EntrypointServer.java
+++ b/src/main/java/net/fabricmc/loader/entrypoint/minecraft/hooks/EntrypointServer.java
@@ -17,6 +17,7 @@
package net.fabricmc.loader.entrypoint.minecraft.hooks;
import net.fabricmc.api.DedicatedServerModInitializer;
+import net.fabricmc.api.FakeModProvider;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.FabricLoader;
@@ -30,6 +31,7 @@ public static void start(File runDir, Object gameInstance) {
FabricLoader.INSTANCE.prepareModInit(runDir, gameInstance);
EntrypointUtils.invoke("main", ModInitializer.class, ModInitializer::onInitialize);
+ FabricLoader.INSTANCE.getEntrypoints("fake_mods", FakeModProvider.class).forEach(provider -> FabricLoader.INSTANCE.appendFakeMods(provider.getFakeMods()));
EntrypointUtils.invoke("server", DedicatedServerModInitializer.class, DedicatedServerModInitializer::onInitializeServer);
}
}