Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -112,6 +113,7 @@ public void onInitialize() {
throw error;
}

ModList.get().setLoadedMods(mods.values());
// Send initialization events

RegistryEventDispatcher.dispatchRegistryEvents(event -> dispatch(mods, event));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ModConfig.Type, ModConfig> configs;
private net.fabricmc.loader.api.ModContainer fabricModContainer;

public ModContainer(String modId) {
this.modId = modId;
Expand All @@ -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) {
}
}
67 changes: 67 additions & 0 deletions patchwork-fml/src/main/java/net/minecraftforge/fml/ModList.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -42,6 +51,7 @@ public class ModList {
private static ModList INSTANCE = new ModList();

private Map<ModContainer, ModFileInfo> modFileInfoMap = new HashMap<>();
private Map<ModContainer, net.minecraftforge.fml.ModContainer> fabricForgeModMap = new HashMap<>();
private List<ModFileScanData> allScanDataCache;

public static ModList get() {
Expand All @@ -53,6 +63,10 @@ public boolean isLoaded(String modId) {
return FabricLoader.getInstance().isModLoaded(modId);
}

public List<ModFileInfo> getModFiles() {
return ImmutableList.copyOf(modFileInfoMap.values());
}

public ModFileInfo getModFileById(String modId) {
ModContainer modContainer = FabricLoader.getInstance().getModContainer(modId).orElse(null);

Expand All @@ -63,6 +77,39 @@ public ModFileInfo getModFileById(String modId) {
return getModFileByContainer(modContainer);
}

public void setLoadedMods(final Collection<FMLModContainer> 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 <T> Optional<T> getModObjectById(String modId) {
return getModContainerById(modId).map(net.minecraftforge.fml.ModContainer::getMod).map(o -> (T) o);
}

public Optional<? extends net.minecraftforge.fml.ModContainer> getModContainerById(String modId) {
return Optional.ofNullable(this.fabricForgeModMap.get(modId));
}

public Optional<? extends net.minecraftforge.fml.ModContainer> 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);
}
Expand Down Expand Up @@ -107,6 +154,10 @@ private ModFileInfo createModFileInfo(ModContainer modContainer) {
return new ModFileInfo();
}

public int size() {
return modFileInfoMap.size();
}

public List<ModFileScanData> getAllScanData() {
if (allScanDataCache == null) {
// Even though ModFileScanData lacks an implementation of Object#equals, the default implementation tests
Expand All @@ -124,4 +175,20 @@ public List<ModFileScanData> getAllScanData() {

return allScanDataCache;
}

public void forEachModFile(Consumer<ModFile> fileConsumer) {
modFileInfoMap.values().stream().map(ModFileInfo::getFile).forEach(fileConsumer);
}

public <T> Stream<T> applyForEachModFile(Function<ModFile, T> function) {
return modFileInfoMap.values().stream().map(ModFileInfo::getFile).map(function);
}

public void forEachModContainer(BiConsumer<String, net.minecraftforge.fml.ModContainer> modContainerConsumer) {
fabricForgeModMap.forEach((fabric, fml) -> modContainerConsumer.accept(fabric.getMetadata().getId(), fml));
}

public <T> Stream<T> applyForEachModContainer(Function<net.minecraftforge.fml.ModContainer, T> function) {
return fabricForgeModMap.values().stream().map(function);
}
}
38 changes: 38 additions & 0 deletions patchwork-fml/src/main/java/net/minecraftforge/fml/ModLoader.java
Original file line number Diff line number Diff line change
@@ -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));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

public class FMLModContainer extends ModContainer {
private final IEventBus eventBus;
private Object instance;

public FMLModContainer(String id) {
super(id);
Expand All @@ -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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to always be null, it might actually be better to drop them until the setter is actually called

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just comment getMod() and setMod() for now? Impl setMod needs some changes in the patcher as well, the ForgeInitializer.onForgeInitialize should return the instance of the Forge mod class, so that we can record it in its ModContainer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, just comment them out for now and the change that needs Patcher can be a separate PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we leave getMod() and setMod() here? Just add TODOs to both of them and throw a warning when they are called? Other methods in this pr require getMod(), simply remove getMod() needs more work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright. Make sure you open an issue on Patcher about it

}

public void setMod(Object instance) {
this.instance = instance;
}
}