diff --git a/patchwork-dispatcher/src/main/java/net/patchworkmc/impl/Patchwork.java b/patchwork-dispatcher/src/main/java/net/patchworkmc/impl/Patchwork.java index f6444d6b..b26bed8e 100644 --- a/patchwork-dispatcher/src/main/java/net/patchworkmc/impl/Patchwork.java +++ b/patchwork-dispatcher/src/main/java/net/patchworkmc/impl/Patchwork.java @@ -32,6 +32,7 @@ import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.ModContainer; +import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; @@ -112,6 +113,7 @@ public void onInitialize() { throw error; } + ModList.get().setLoadedMods(mods.values()); // Send initialization events RegistryEventDispatcher.dispatchRegistryEvents(event -> dispatch(mods, event)); diff --git a/patchwork-fml/src/main/java/net/minecraftforge/fml/ModContainer.java b/patchwork-fml/src/main/java/net/minecraftforge/fml/ModContainer.java index ee33a175..56a59a7a 100644 --- a/patchwork-fml/src/main/java/net/minecraftforge/fml/ModContainer.java +++ b/patchwork-fml/src/main/java/net/minecraftforge/fml/ModContainer.java @@ -21,13 +21,15 @@ import java.util.EnumMap; +import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.fml.config.ModConfig; // TODO: Stub -public class ModContainer { +public abstract class ModContainer { protected final String modId; protected final String namespace; protected final EnumMap configs; + private net.fabricmc.loader.api.ModContainer fabricModContainer; public ModContainer(String modId) { this.modId = modId; @@ -47,4 +49,17 @@ public final String getNamespace() { public void addConfig(final ModConfig modConfig) { configs.put(modConfig.getType(), modConfig); } + + public final void setParent(net.fabricmc.loader.api.ModContainer fabricModContainer) { + this.fabricModContainer = fabricModContainer; + } + + public final net.fabricmc.loader.api.ModContainer getParent() { + return this.fabricModContainer; + } + + public abstract Object getMod(); + + protected void acceptEvent(Event e) { + } } diff --git a/patchwork-fml/src/main/java/net/minecraftforge/fml/ModList.java b/patchwork-fml/src/main/java/net/minecraftforge/fml/ModList.java index e7e6d5c4..2028a3dc 100644 --- a/patchwork-fml/src/main/java/net/minecraftforge/fml/ModList.java +++ b/patchwork-fml/src/main/java/net/minecraftforge/fml/ModList.java @@ -19,16 +19,25 @@ package net.minecraftforge.fml; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; +import net.minecraftforge.fml.javafmlmod.FMLModContainer; +import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; import net.minecraftforge.forgespi.language.ModFileScanData; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.google.common.collect.ImmutableList; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; @@ -42,6 +51,7 @@ public class ModList { private static ModList INSTANCE = new ModList(); private Map modFileInfoMap = new HashMap<>(); + private Map fabricForgeModMap = new HashMap<>(); private List allScanDataCache; public static ModList get() { @@ -53,6 +63,10 @@ public boolean isLoaded(String modId) { return FabricLoader.getInstance().isModLoaded(modId); } + public List getModFiles() { + return ImmutableList.copyOf(modFileInfoMap.values()); + } + public ModFileInfo getModFileById(String modId) { ModContainer modContainer = FabricLoader.getInstance().getModContainer(modId).orElse(null); @@ -63,6 +77,39 @@ public ModFileInfo getModFileById(String modId) { return getModFileByContainer(modContainer); } + public void setLoadedMods(final Collection collection) { + fabricForgeModMap.clear(); + + for (net.minecraftforge.fml.ModContainer fmlContainer: collection) { + String modId = fmlContainer.modId; + ModContainer fabricModContainer = FabricLoader.getInstance().getModContainer(modId).orElse(null); + + if (fabricModContainer != null) { + fmlContainer.setParent(fabricModContainer); + fabricForgeModMap.put(fabricModContainer, fmlContainer); + } else { + throw new RuntimeException("Cannot find the Fabric ModContainer for Forge mod: " + modId); + } + } + } + + public net.minecraftforge.fml.ModContainer getModContainer(ModContainer fabricModContainer) { + return fabricForgeModMap.get(fabricModContainer); + } + + @SuppressWarnings("unchecked") + public Optional getModObjectById(String modId) { + return getModContainerById(modId).map(net.minecraftforge.fml.ModContainer::getMod).map(o -> (T) o); + } + + public Optional getModContainerById(String modId) { + return Optional.ofNullable(this.fabricForgeModMap.get(modId)); + } + + public Optional getModContainerByObject(Object obj) { + return this.fabricForgeModMap.values().stream().filter(mc -> mc.getMod() == obj).findFirst(); + } + private ModFileInfo getModFileByContainer(ModContainer modContainer) { return modFileInfoMap.computeIfAbsent(modContainer, this::createModFileInfo); } @@ -107,6 +154,10 @@ private ModFileInfo createModFileInfo(ModContainer modContainer) { return new ModFileInfo(); } + public int size() { + return modFileInfoMap.size(); + } + public List getAllScanData() { if (allScanDataCache == null) { // Even though ModFileScanData lacks an implementation of Object#equals, the default implementation tests @@ -124,4 +175,20 @@ public List getAllScanData() { return allScanDataCache; } + + public void forEachModFile(Consumer fileConsumer) { + modFileInfoMap.values().stream().map(ModFileInfo::getFile).forEach(fileConsumer); + } + + public Stream applyForEachModFile(Function function) { + return modFileInfoMap.values().stream().map(ModFileInfo::getFile).map(function); + } + + public void forEachModContainer(BiConsumer modContainerConsumer) { + fabricForgeModMap.forEach((fabric, fml) -> modContainerConsumer.accept(fabric.getMetadata().getId(), fml)); + } + + public Stream applyForEachModContainer(Function function) { + return fabricForgeModMap.values().stream().map(function); + } } diff --git a/patchwork-fml/src/main/java/net/minecraftforge/fml/ModLoader.java b/patchwork-fml/src/main/java/net/minecraftforge/fml/ModLoader.java new file mode 100644 index 00000000..0e9ea862 --- /dev/null +++ b/patchwork-fml/src/main/java/net/minecraftforge/fml/ModLoader.java @@ -0,0 +1,38 @@ +/* + * Minecraft Forge, Patchwork Project + * Copyright (c) 2016-2020, 2019-2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fml; + +import net.minecraftforge.eventbus.api.Event; + +public class ModLoader { + private static ModLoader INSTANCE; + + private ModLoader() { + INSTANCE = this; + } + + public static ModLoader get() { + return INSTANCE == null ? INSTANCE = new ModLoader() : INSTANCE; + } + + public void postEvent(Event e) { + ModList.get().forEachModContainer((id, mc) -> mc.acceptEvent(e)); + } +} diff --git a/patchwork-fml/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java b/patchwork-fml/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java index c203cd56..9761fcc1 100644 --- a/patchwork-fml/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java +++ b/patchwork-fml/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java @@ -27,6 +27,7 @@ public class FMLModContainer extends ModContainer { private final IEventBus eventBus; + private Object instance; public FMLModContainer(String id) { super(id); @@ -47,4 +48,18 @@ public IEventBus getEventBus() { private void onEventFailed(IEventBus iEventBus, Event event, IEventListener[] listeners, int i, Throwable throwable) { // TODO } + + @Override + protected void acceptEvent(final Event e) { + this.eventBus.post(e); + } + + @Override + public Object getMod() { + return this.instance; + } + + public void setMod(Object instance) { + this.instance = instance; + } }