mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 00:07:45 +00:00
Things. they work. Obviously still WAY more to do.
This commit is contained in:
1 parent
1b1ee6f0b8
commit
baa9dfe55a
95 files changed
+852
-786
No files matched your search
@@ -49,7 +49,7 @@ import net.minecraftforge.fml.client.config.GuiConfigEntries.SelectValueEntry;
|
||||
import net.minecraftforge.fml.client.config.GuiConfigEntries.BooleanEntry;
|
||||
import net.minecraftforge.fml.client.config.IConfigElement;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import static net.minecraftforge.common.ForgeModContainer.VERSION_CHECK_CAT;
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,7 +52,7 @@ import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
@@ -145,7 +145,7 @@ import net.minecraftforge.fluids.IFluidBlock;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.LoaderState;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher;
|
||||
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.ConnectionType;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
|
||||
@@ -71,7 +71,7 @@ import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
import net.minecraftforge.oredict.OreIngredient;
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.apache.commons.lang3.Validate;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.eventbus.api.GenericEvent;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
@@ -46,7 +46,7 @@ import com.google.common.collect.Sets;
|
||||
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.registries.IRegistryDelegate;
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2018.
|
||||
*
|
||||
* 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.api.Side;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.language.ModFileScanData;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.minecraftforge.fml.Logging.LOADING;
|
||||
|
||||
/**
|
||||
* Automatic eventbus subscriber - reads {@link net.minecraftforge.fml.common.Mod.EventBusSubscriber}
|
||||
* annotations and passes the class instances to the {@link net.minecraftforge.common.MinecraftForge.EVENT_BUS}
|
||||
*/
|
||||
public class AutomaticEventSubscriber
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger("FML");
|
||||
public static void inject(final ModContainer mod, final ModFileScanData scanData, final ClassLoader loader)
|
||||
{
|
||||
LOGGER.debug(LOADING,"Attempting to inject @EventBusSubscriber classes into the eventbus for {}", mod.getModId());
|
||||
List<ModFileScanData.AnnotationData> ebsTargets = scanData.getAnnotations().stream().
|
||||
filter(annotationData -> Objects.equals(annotationData.getAnnotationType(), Type.getType(Mod.EventBusSubscriber.class))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
ebsTargets.forEach(ad -> {
|
||||
final List<ModAnnotation.EnumHolder> sidesValue = (List<ModAnnotation.EnumHolder>)ad.getAnnotationData().get("value");
|
||||
final EnumSet<Side> sides = sidesValue.stream().map(eh -> Side.valueOf(eh.getValue())).
|
||||
collect(Collectors.toCollection(() -> EnumSet.noneOf(Side.class)));
|
||||
final String modId = (String)ad.getAnnotationData().getOrDefault("modId", mod.getModId());
|
||||
if (Objects.equals(mod.getModId(), modId) && sides.contains(FMLEnvironment.side)) {
|
||||
try
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.register(Class.forName(ad.getClassType().getClassName(), true, loader));
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
LOGGER.error(LOADING, "Failed to load mod class {} for @EventBusSubscriber annotation", ad.getClassType(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,53 +19,14 @@
|
||||
|
||||
package net.minecraftforge.fml;
|
||||
|
||||
import com.electronwill.nightconfig.core.path.PathConfig;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.language.IModInfo;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import net.minecraftforge.fml.loading.DefaultModInfos;
|
||||
|
||||
public class DefaultModContainers
|
||||
{
|
||||
static {
|
||||
PathConfig minecraftmod;
|
||||
PathConfig forgemod;
|
||||
try
|
||||
{
|
||||
minecraftmod = PathConfig.of(Paths.get(DefaultModContainers.class.getClassLoader().getResource("minecraftmod.toml").toURI()));
|
||||
forgemod = PathConfig.of(Paths.get(DefaultModContainers.class.getClassLoader().getResource("forgemod.toml").toURI()));
|
||||
minecraftmod.load();
|
||||
forgemod.load();
|
||||
}
|
||||
catch (URISyntaxException | NullPointerException e)
|
||||
{
|
||||
throw new RuntimeException("Missing toml configs for minecraft and forge!", e);
|
||||
}
|
||||
minecraftModInfo = new ModInfo(null, minecraftmod);
|
||||
forgeModInfo = new ModInfo(null, forgemod);
|
||||
|
||||
}
|
||||
|
||||
private static final IModInfo minecraftModInfo;
|
||||
private static final IModInfo forgeModInfo;
|
||||
|
||||
// no construction
|
||||
private DefaultModContainers() {}
|
||||
|
||||
public static List<IModInfo> getModInfos()
|
||||
{
|
||||
return Arrays.asList(minecraftModInfo, forgeModInfo);
|
||||
}
|
||||
|
||||
|
||||
public static final ModContainer MINECRAFT = new ModContainer(minecraftModInfo)
|
||||
public static final ModContainer MINECRAFT = new ModContainer(DefaultModInfos.minecraftModInfo)
|
||||
{
|
||||
@Override
|
||||
public boolean matches(Object mod)
|
||||
public boolean matches(final Object mod)
|
||||
{
|
||||
return mod == this;
|
||||
}
|
||||
@@ -76,4 +37,4 @@ public class DefaultModContainers
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,7 @@ public class LaunchTesting
|
||||
logcontext.getConfiguration().addFilter(axformFilter);
|
||||
logcontext.getConfiguration().addFilter(eventbusFilter);
|
||||
logcontext.updateLoggers();
|
||||
System.setProperty("fml.explodedDir", "/home/cpw/projects/mods/inventorysorter/classes");
|
||||
hackNatives();
|
||||
Launcher.main("--launchTarget", "devfmlclient","--gameDir", "projects/run",
|
||||
"--accessToken", "blah", "--version", "FMLDev", "--assetIndex", "1.12",
|
||||
|
||||
@@ -20,18 +20,18 @@
|
||||
package net.minecraftforge.fml;
|
||||
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.loading.ModList;
|
||||
import net.minecraftforge.fml.loading.ModLoadingStage;
|
||||
import net.minecraftforge.fml.common.event.ModLifecycleEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLModContainer;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public enum LifecycleEventProvider
|
||||
{
|
||||
LOAD(()->new LifecycleEvent(ModLoadingStage.BEGIN)),
|
||||
PREINIT(()->new LifecycleEvent(ModLoadingStage.PREINIT));
|
||||
CONSTRUCT(()->new LifecycleEvent(ModLoadingStage.CONSTRUCT));
|
||||
|
||||
public void dispatch(final ModList target) {
|
||||
target.dispatchLifeCycleEvent(this.event.get());
|
||||
public void dispatch() {
|
||||
ModList.get().dispatchLifeCycleEvent(this.event.get());
|
||||
}
|
||||
private final Supplier<? extends LifecycleEvent> event;
|
||||
|
||||
@@ -41,7 +41,7 @@ public enum LifecycleEventProvider
|
||||
}
|
||||
|
||||
|
||||
public static class LifecycleEvent extends Event {
|
||||
public static class LifecycleEvent {
|
||||
private final ModLoadingStage stage;
|
||||
|
||||
public LifecycleEvent(ModLoadingStage stage)
|
||||
@@ -59,5 +59,9 @@ public enum LifecycleEventProvider
|
||||
return ModLoadingStage.values()[this.stage.ordinal()+1];
|
||||
}
|
||||
|
||||
public ModLifecycleEvent buildModEvent(FMLModContainer fmlModContainer)
|
||||
{
|
||||
return stage.getModEvent(fmlModContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
-6
@@ -17,14 +17,19 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.language;
|
||||
package net.minecraftforge.fml;
|
||||
|
||||
import net.minecraftforge.fml.LifecycleEventProvider;
|
||||
import net.minecraftforge.fml.loading.ModLoadingStage;
|
||||
import net.minecraftforge.fml.language.ExtensionPoint;
|
||||
import net.minecraftforge.fml.language.IModInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* The container that wraps around mods in the system.
|
||||
@@ -45,11 +50,15 @@ public abstract class ModContainer
|
||||
protected final IModInfo modInfo;
|
||||
protected ModLoadingStage modLoadingStage;
|
||||
protected final Map<ModLoadingStage, Consumer<LifecycleEventProvider.LifecycleEvent>> triggerMap;
|
||||
protected final Map<ExtensionPoint, Supplier<?>> extensionPoints = new IdentityHashMap<>();
|
||||
protected final List<Throwable> modLoadingError;
|
||||
|
||||
public ModContainer(IModInfo info)
|
||||
{
|
||||
this.modId = info.getModId();
|
||||
this.modInfo = info;
|
||||
this.triggerMap = new HashMap<>();
|
||||
this.modLoadingError = new ArrayList<>();
|
||||
this.modLoadingStage = ModLoadingStage.BEGIN;
|
||||
}
|
||||
|
||||
@@ -83,7 +92,7 @@ public abstract class ModContainer
|
||||
*/
|
||||
public final void transitionState(LifecycleEventProvider.LifecycleEvent event)
|
||||
{
|
||||
if (modLoadingStage != event.fromStage())
|
||||
if (modLoadingStage == event.fromStage())
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -105,6 +114,16 @@ public abstract class ModContainer
|
||||
return modInfo;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Optional<T> getCustomExtension(ExtensionPoint point) {
|
||||
return Optional.ofNullable((T)extensionPoints.getOrDefault(point,()-> null).get());
|
||||
}
|
||||
|
||||
public <T> void registerExtensionPoint(ExtensionPoint point, Supplier<T> extension)
|
||||
{
|
||||
extensionPoints.put(point, extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this mod match the supplied mod?
|
||||
*
|
||||
@@ -117,6 +136,4 @@ public abstract class ModContainer
|
||||
* @return the mod object instance
|
||||
*/
|
||||
public abstract Object getMod();
|
||||
|
||||
public abstract <T> T getCustomExtension(final String name);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2018.
|
||||
*
|
||||
* 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 com.google.common.collect.Streams;
|
||||
import net.minecraftforge.fml.loading.DefaultModInfos;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Master list of all mods
|
||||
*/
|
||||
public class ModList
|
||||
{
|
||||
private static ModList INSTANCE;
|
||||
private final List<ModFileInfo> modFiles;
|
||||
private final List<ModInfo> sortedList;
|
||||
private final Map<String, ModFileInfo> fileById;
|
||||
private BackgroundScanHandler scanner;
|
||||
private List<ModContainer> mods;
|
||||
private Map<String, ModContainer> indexedMods;
|
||||
|
||||
private ModList(final List<ModFile> modFiles, final List<ModInfo> sortedList)
|
||||
{
|
||||
this.modFiles = modFiles.stream().map(ModFile::getModFileInfo).map(ModFileInfo.class::cast).collect(Collectors.toList());
|
||||
this.sortedList = Streams.concat(DefaultModInfos.getModInfos().stream(), sortedList.stream()).
|
||||
map(ModInfo.class::cast).
|
||||
collect(Collectors.toList());
|
||||
this.fileById = this.modFiles.stream().map(ModFileInfo::getMods).flatMap(Collection::stream).
|
||||
map(ModInfo.class::cast).
|
||||
collect(Collectors.toMap(ModInfo::getModId, ModInfo::getOwningFile));
|
||||
}
|
||||
|
||||
public static ModList of(List<ModFile> modFiles, List<ModInfo> sortedList)
|
||||
{
|
||||
INSTANCE = new ModList(modFiles, sortedList);
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static ModList get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public List<ModFileInfo> getModFiles()
|
||||
{
|
||||
return modFiles;
|
||||
}
|
||||
|
||||
|
||||
public ModFileInfo getModFileById(String modid)
|
||||
{
|
||||
return this.fileById.get(modid);
|
||||
}
|
||||
|
||||
public void dispatchLifeCycleEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) {
|
||||
this.mods.parallelStream().forEach(m->m.transitionState(lifecycleEvent));
|
||||
final List<ModContainer> erroredContainers = this.mods.stream().filter(m -> m.getCurrentState() == ModLoadingStage.ERROR).collect(Collectors.toList());
|
||||
if (!erroredContainers.isEmpty()) {
|
||||
throw new RuntimeException("Errored containers found!");
|
||||
}
|
||||
}
|
||||
|
||||
public void setLoadedMods(final List<ModContainer> modContainers)
|
||||
{
|
||||
this.mods = modContainers;
|
||||
this.indexedMods = modContainers.stream().collect(Collectors.toMap(ModContainer::getModId, Function.identity()));
|
||||
}
|
||||
|
||||
public Optional<Object> getModObjectById(String modId)
|
||||
{
|
||||
return getModContainerById(modId).map(ModContainer::getMod);
|
||||
}
|
||||
|
||||
public Optional<? extends ModContainer> getModContainerById(String modId)
|
||||
{
|
||||
return Optional.ofNullable(this.indexedMods.get(modId));
|
||||
}
|
||||
|
||||
public List<ModInfo> getMods()
|
||||
{
|
||||
return this.sortedList;
|
||||
}
|
||||
|
||||
public boolean isLoaded(String modTarget)
|
||||
{
|
||||
return this.indexedMods.containsKey(modTarget);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2018.
|
||||
*
|
||||
* 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.fml.language.IModInfo;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.loading.LoadingModList;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ModLoader
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger("FML");
|
||||
private static ModLoader INSTANCE;
|
||||
private final ClassLoader launchClassLoader;
|
||||
private final LoadingModList loadingModList;
|
||||
private final ModLoadingClassLoader modClassLoader;
|
||||
|
||||
private ModLoader()
|
||||
{
|
||||
INSTANCE = this;
|
||||
this.launchClassLoader = FMLLoader.getLaunchClassLoader();
|
||||
this.loadingModList = FMLLoader.getLoadingModList();
|
||||
this.modClassLoader = new ModLoadingClassLoader(this.launchClassLoader);
|
||||
Thread.currentThread().setContextClassLoader(this.modClassLoader);
|
||||
}
|
||||
|
||||
public static ModLoader get()
|
||||
{
|
||||
return INSTANCE == null ? INSTANCE = new ModLoader() : INSTANCE;
|
||||
}
|
||||
|
||||
public void loadMods() {
|
||||
final ModList modList = ModList.of(loadingModList.getModFiles().stream().map(ModFileInfo::getFile).collect(Collectors.toList()), loadingModList.getMods());
|
||||
modList.setLoadedMods(loadingModList.getModFiles().stream().
|
||||
map(ModFileInfo::getFile).
|
||||
map(mf -> buildMods(mf, modClassLoader)).
|
||||
flatMap(Collection::stream).collect(Collectors.toList()));
|
||||
|
||||
LifecycleEventProvider.LOAD.dispatch();
|
||||
LifecycleEventProvider.CONSTRUCT.dispatch();
|
||||
}
|
||||
|
||||
private List<ModContainer> buildMods(final ModFile modFile, final ModLoadingClassLoader modClassLoader)
|
||||
{
|
||||
final Map<String, IModInfo> modInfoMap = modFile.getModFileInfo().getMods().stream().collect(Collectors.toMap(IModInfo::getModId, Function.identity()));
|
||||
|
||||
return modFile.getScanResult().getTargets().entrySet().stream().
|
||||
map(e->e.getValue().<ModContainer>loadMod(modInfoMap.get(e.getKey()), modClassLoader, modFile.getScanResult())).
|
||||
collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+6
-9
@@ -17,15 +17,13 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.loading;
|
||||
package net.minecraftforge.fml;
|
||||
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.SecureClassLoader;
|
||||
@@ -38,11 +36,8 @@ public class ModLoadingClassLoader extends SecureClassLoader
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
|
||||
private ModLoader modLoader;
|
||||
|
||||
protected ModLoadingClassLoader(ModLoader modLoader, ClassLoader parent) {
|
||||
protected ModLoadingClassLoader(final ClassLoader parent) {
|
||||
super(parent);
|
||||
this.modLoader = modLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,7 +51,7 @@ public class ModLoadingClassLoader extends SecureClassLoader
|
||||
{
|
||||
LogManager.getLogger("FML").debug(LOADING, "Loading class {}", name);
|
||||
final String className = name.replace('.','/').concat(".class");
|
||||
final Path classResource = modLoader.getModList().findResource(className);
|
||||
final Path classResource = FMLLoader.getLoadingModList().findResource(className);
|
||||
if (classResource != null) {
|
||||
try {
|
||||
final byte[] bytes = Files.readAllBytes(classResource);
|
||||
@@ -66,6 +61,8 @@ public class ModLoadingClassLoader extends SecureClassLoader
|
||||
{
|
||||
throw new ClassNotFoundException("Failed to load class file " + classResource + " for "+ className, e);
|
||||
}
|
||||
} else {
|
||||
getParent().loadClass(name);
|
||||
}
|
||||
throw new ClassNotFoundException("Failed to find class file "+ className);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2018.
|
||||
*
|
||||
* 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.fml.common.event.FMLInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.ModLifecycleEvent;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public enum ModLoadingStage
|
||||
{
|
||||
ERROR(null),
|
||||
BEGIN(null),
|
||||
CONSTRUCT(()->FMLPreInitializationEvent::new),
|
||||
PREINIT(()->FMLInitializationEvent::new),
|
||||
INIT(()->FMLPostInitializationEvent::new),
|
||||
POSTINIT(()->FMLLoadCompleteEvent::new),
|
||||
COMPLETE(null);
|
||||
|
||||
private final Supplier<Function<ModContainer, ModLifecycleEvent>> modLifecycleEventFunction;
|
||||
|
||||
ModLoadingStage(Supplier<Function<ModContainer, ModLifecycleEvent>> modLifecycleEventFunction)
|
||||
{
|
||||
this.modLifecycleEventFunction = modLifecycleEventFunction;
|
||||
}
|
||||
|
||||
public ModLifecycleEvent getModEvent(ModContainer fmlModContainer)
|
||||
{
|
||||
return modLifecycleEventFunction.get().apply(fmlModContainer);
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
package net.minecraftforge.fml;
|
||||
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
|
||||
public class ModThreadContext
|
||||
{
|
||||
private static ThreadLocal<ModThreadContext> context = ThreadLocal.withInitial(ModThreadContext::new);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
package net.minecraftforge.fml;
|
||||
|
||||
import net.minecraftforge.api.Side;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Supplier;
|
||||
@@ -37,7 +38,7 @@ public final class SidedExecutor
|
||||
* @return The callable's result
|
||||
*/
|
||||
public static <T> T runOn(Side side, Supplier<Callable<T>> toRun) {
|
||||
if (side == Side.CLIENT) {
|
||||
if (side == FMLEnvironment.side) {
|
||||
try
|
||||
{
|
||||
return toRun.get().call();
|
||||
@@ -49,4 +50,16 @@ public final class SidedExecutor
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T runSided(Supplier<Supplier<T>> clientTarget, Supplier<Supplier<T>> serverTarget) {
|
||||
switch (FMLEnvironment.side)
|
||||
{
|
||||
case CLIENT:
|
||||
return clientTarget.get().get();
|
||||
case SERVER:
|
||||
return serverTarget.get().get();
|
||||
default:
|
||||
throw new IllegalArgumentException("UNSIDED?");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
package net.minecraftforge.fml;
|
||||
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.common.versioning.ComparableVersion;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import net.minecraft.client.resources.IResourcePack;
|
||||
import net.minecraft.client.resources.data.MetadataSerializer;
|
||||
import net.minecraftforge.fml.SidedProvider;
|
||||
import net.minecraftforge.fml.VersionChecker;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.ModLoader;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -46,7 +46,7 @@ public class ClientModLoader
|
||||
{
|
||||
SidedProvider.setClient(()->minecraft);
|
||||
SplashProgress.start();
|
||||
FMLLoader.getModLoader().loadMods();
|
||||
ModLoader.get().loadMods();
|
||||
minecraft.refreshResources();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ package net.minecraftforge.fml.client;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraftforge.fml.loading.ModList;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.language.ExtensionPoint;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -31,6 +32,7 @@ public class ConfigGuiHandler
|
||||
{
|
||||
public static Optional<BiFunction<Minecraft, GuiScreen, GuiScreen>> getGuiFactoryFor(ModInfo selectedMod)
|
||||
{
|
||||
return ModList.get().getModContainerById(selectedMod.getModId()).map(mc->mc.getCustomExtension("customGuiFactory"));
|
||||
return ModList.get().getModContainerById(selectedMod.getModId()).
|
||||
flatMap(mc -> mc.getCustomExtension(ExtensionPoint.GUIFACTORY));
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import java.util.Set;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraftforge.fml.client.config.GuiConfig;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
public class DefaultGuiFactory implements IModGuiFactory
|
||||
{
|
||||
|
||||
@@ -101,7 +101,7 @@ import net.minecraftforge.fml.common.LoaderException;
|
||||
import net.minecraftforge.fml.common.MetadataCollection;
|
||||
import net.minecraftforge.fml.common.MissingModsException;
|
||||
import net.minecraftforge.fml.common.MultipleModsErrored;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.ModMetadata;
|
||||
import net.minecraftforge.fml.common.StartupQuery;
|
||||
import net.minecraftforge.fml.common.WrongMinecraftVersionException;
|
||||
|
||||
@@ -32,7 +32,7 @@ import javax.imageio.ImageIO;
|
||||
|
||||
import net.minecraft.client.resources.FileResourcePack;
|
||||
import net.minecraftforge.fml.common.FMLContainerHolder;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
public class FMLFileResourcePack extends FileResourcePack implements FMLContainerHolder {
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import javax.imageio.ImageIO;
|
||||
|
||||
import net.minecraft.client.resources.FolderResourcePack;
|
||||
import net.minecraftforge.fml.common.FMLContainerHolder;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
public class FMLFolderResourcePack extends FolderResourcePack implements FMLContainerHolder {
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
package net.minecraftforge.fml.client;
|
||||
|
||||
import net.minecraftforge.fml.common.DuplicateModsFoundException;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
package net.minecraftforge.fml.client;
|
||||
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.toposort.ModSortingException;
|
||||
import net.minecraftforge.fml.common.toposort.ModSortingException.SortingExceptionData;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import net.minecraft.client.resources.IResourcePack;
|
||||
import net.minecraft.client.resources.SimpleReloadableResourceManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.FMLContainerHolder;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -37,7 +37,7 @@ import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
|
||||
@@ -52,16 +52,16 @@ import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.VersionChecker;
|
||||
import net.minecraftforge.fml.client.ConfigGuiHandler;
|
||||
import net.minecraftforge.fml.client.ResourcePackLoader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.versioning.ComparableVersion;
|
||||
|
||||
import static net.minecraft.util.StringUtils.stripControlCodes;
|
||||
|
||||
import net.minecraftforge.fml.language.IModInfo;
|
||||
import net.minecraftforge.fml.loading.ModList;
|
||||
import net.minecraftforge.fml.loading.StringUtils;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2018.
|
||||
*
|
||||
* 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.common;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Automatic eventbus subscriber - reads {@link net.minecraftforge.fml.common.Mod.EventBusSubscriber}
|
||||
* annotations and passes the class instances to the {@link net.minecraftforge.common.MinecraftForge.EVENT_BUS}
|
||||
*/
|
||||
public class AutomaticEventSubscriber
|
||||
{
|
||||
private static final EnumSet<Side> DEFAULT = EnumSet.allOf(Side.class);
|
||||
public static void inject(ModContainer mod, ASMDataTable data, Side side)
|
||||
{
|
||||
FMLLog.log.debug("Attempting to inject @EventBusSubscriber classes into the eventbus for {}", mod.getModId());
|
||||
SetMultimap<String, ASMData> modData = data.getAnnotationsFor(mod);
|
||||
Set<ASMDataTable.ASMData> mods = modData.get(Mod.class.getName());
|
||||
Set<ASMDataTable.ASMData> targets = modData.get(Mod.EventBusSubscriber.class.getName());
|
||||
ClassLoader mcl = Loader.instance().getModClassLoader();
|
||||
|
||||
for (ASMDataTable.ASMData targ : targets)
|
||||
{
|
||||
try
|
||||
{
|
||||
//noinspection unchecked
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ModAnnotation.EnumHolder> sidesEnum = (List<ModAnnotation.EnumHolder>)targ.getAnnotationInfo().get("value");
|
||||
EnumSet<Side> sides = DEFAULT;
|
||||
if (sidesEnum != null) {
|
||||
sides = EnumSet.noneOf(Side.class);
|
||||
for (ModAnnotation.EnumHolder h: sidesEnum) {
|
||||
sides.add(Side.valueOf(h.getValue()));
|
||||
}
|
||||
}
|
||||
if (sides == DEFAULT || sides.contains(side)) {
|
||||
//FMLLog.log.debug("Found @EventBusSubscriber class {}", targ.getClassName());
|
||||
String amodid = (String)targ.getAnnotationInfo().get("modid");
|
||||
if (Strings.isNullOrEmpty(amodid)) {
|
||||
amodid = ASMDataTable.getOwnerModID(mods, targ);
|
||||
if (Strings.isNullOrEmpty(amodid)) {
|
||||
FMLLog.bigWarning("Could not determine owning mod for @EventBusSubscriber on {} for mod {}", targ.getClassName(), mod.getModId());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!mod.getModId().equals(amodid))
|
||||
{
|
||||
FMLLog.log.debug("Skipping @EventBusSubscriber injection for {} since it is not for mod {}", targ.getClassName(), mod.getModId());
|
||||
continue; //We're not injecting this guy
|
||||
}
|
||||
FMLLog.log.debug("Registering @EventBusSubscriber for {} for mod {}", targ.getClassName(), mod.getModId());
|
||||
Class<?> subscriptionTarget = Class.forName(targ.getClassName(), false, mcl);
|
||||
MinecraftForge.EVENT_BUS.register(subscriptionTarget);
|
||||
FMLLog.log.debug("Injected @EventBusSubscriber class {}", targ.getClassName());
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
FMLLog.log.error("An error occurred trying to load an EventBusSubscriber {} for modid {}", targ.getClassName(), mod.getModId(), e);
|
||||
throw new LoaderException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -62,7 +62,7 @@ import net.minecraftforge.fml.common.gameevent.TickEvent.Phase;
|
||||
import net.minecraftforge.fml.common.network.FMLNetworkEvent;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.common.thread.SidedThreadGroup;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.server.FMLServerHandler;
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ import net.minecraftforge.fml.common.network.NetworkCheckHandler;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.registries.ForgeRegistry;
|
||||
import net.minecraftforge.registries.GameData;
|
||||
@@ -119,7 +119,7 @@ public final class FMLContainer extends DummyModContainer implements WorldAccess
|
||||
mod.setString("ModVersion", mc.getVersion());
|
||||
modList.appendTag(mod);
|
||||
}
|
||||
fmlData.setTag("ModList", modList);
|
||||
fmlData.setTag("LoadingModList", modList);
|
||||
|
||||
NBTTagCompound registries = new NBTTagCompound();
|
||||
fmlData.setTag("Registries", registries);
|
||||
@@ -135,9 +135,9 @@ public final class FMLContainer extends DummyModContainer implements WorldAccess
|
||||
@Override
|
||||
public void readData(SaveHandler handler, WorldInfo info, Map<String, NBTBase> propertyMap, NBTTagCompound tag)
|
||||
{
|
||||
if (tag.hasKey("ModList"))
|
||||
if (tag.hasKey("LoadingModList"))
|
||||
{
|
||||
NBTTagList modList = tag.getTagList("ModList", (byte)10);
|
||||
NBTTagList modList = tag.getTagList("LoadingModList", (byte)10);
|
||||
for (int i = 0; i < modList.tagCount(); i++)
|
||||
{
|
||||
NBTTagCompound mod = modList.getCompoundTagAt(i);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
package net.minecraftforge.fml.common;
|
||||
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
public interface FMLContainerHolder
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.IThreadListener;
|
||||
import net.minecraftforge.common.util.CompoundDataFixer;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
public interface IFMLSidedHandler
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import net.minecraftforge.fml.javafmlmod.FMLModContainer;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
public interface ILanguageAdapter {
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.stream.Stream;
|
||||
import net.minecraftforge.common.util.TextTable;
|
||||
import net.minecraftforge.fml.common.LoaderState.ModState;
|
||||
import net.minecraftforge.fml.common.ProgressManager.ProgressBar;
|
||||
import net.minecraftforge.fml.common.event.FMLEvent;
|
||||
import net.minecraftforge.fml.common.event.ModLifecycleEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLLoadEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLModDisabledEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
@@ -39,7 +39,7 @@ import net.minecraftforge.fml.common.event.FMLStateEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.FMLThrowingEventBus;
|
||||
import net.minecraftforge.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.ThreadContext;
|
||||
import org.apache.logging.log4j.message.FormattedMessage;
|
||||
@@ -175,7 +175,7 @@ public class LoadController
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void propogateStateMessage(FMLEvent stateEvent)
|
||||
public void propogateStateMessage(ModLifecycleEvent stateEvent)
|
||||
{
|
||||
if (stateEvent instanceof FMLPreInitializationEvent)
|
||||
{
|
||||
@@ -190,7 +190,7 @@ public class LoadController
|
||||
ProgressManager.pop(bar);
|
||||
}
|
||||
|
||||
private void sendEventToModContainer(FMLEvent stateEvent, ModContainer mc)
|
||||
private void sendEventToModContainer(ModLifecycleEvent stateEvent, ModContainer mc)
|
||||
{
|
||||
String modId = mc.getModId();
|
||||
Collection<String> requirements = mc.getRequirements().stream().map(ArtifactVersion::getLabel).collect(Collectors.toCollection(HashSet::new));
|
||||
|
||||
@@ -42,8 +42,8 @@ import net.minecraftforge.common.capabilities.CapabilityManager;
|
||||
import net.minecraftforge.common.config.ConfigManager;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.fml.common.LoaderState.ModState;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.language.ModContainer.Disableable;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer.Disableable;
|
||||
import net.minecraftforge.fml.common.ProgressManager.ProgressBar;
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||
import net.minecraftforge.fml.common.discovery.ContainerType;
|
||||
|
||||
@@ -24,8 +24,8 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import net.minecraftforge.fml.client.IModGuiFactory;
|
||||
import net.minecraftforge.fml.common.event.FMLEvent;
|
||||
import net.minecraftforge.api.Side;
|
||||
import net.minecraftforge.fml.common.event.ModLifecycleEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLFingerprintViolationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLInterModComms;
|
||||
@@ -37,15 +37,12 @@ import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLServerStoppedEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLInterModComms.IMCEvent;
|
||||
import net.minecraftforge.fml.common.network.NetworkCheckHandler;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.fml.common.versioning.VersionRange;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
/**
|
||||
* This defines a Mod to FML.
|
||||
* Any class found with this annotation applied will be loaded as a Mod. The instance that is loaded will
|
||||
* represent the mod to other Mods in the system. It will be sent various subclasses of {@link FMLEvent}
|
||||
* represent the mod to other Mods in the system. It will be sent various subclasses of {@link ModLifecycleEvent}
|
||||
* at pre-defined times during the loading of the game, based on where you have applied the {@link EventHandler}
|
||||
* annotation.
|
||||
*/
|
||||
@@ -60,7 +57,7 @@ public @interface Mod
|
||||
* This will be used to identify your mod for third parties (other mods), it will be used to identify your mod for registries such as block and item registries.
|
||||
* By default, you will have a resource domain that matches the modid. All these uses require that constraints are imposed on the format of the modid.
|
||||
*/
|
||||
String modid();
|
||||
String value();
|
||||
/**
|
||||
* Marks the associated method as handling an FML lifecycle event.
|
||||
* The method must have a single parameter, one of the following types. This annotation
|
||||
@@ -105,20 +102,6 @@ public @interface Mod
|
||||
@Target(ElementType.METHOD)
|
||||
@interface EventHandler{}
|
||||
|
||||
/**
|
||||
* Populate the annotated field with the mod instance based on the specified ModId. This can be used
|
||||
* to retrieve instances of other mods.
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@interface Instance {
|
||||
/**
|
||||
* The mod object to inject into this field
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
||||
/**
|
||||
* A class which will be subscribed to {@link net.minecraftforge.common.MinecraftForge.EVENT_BUS} at mod construction time.
|
||||
*/
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.Map;
|
||||
import net.minecraftforge.fml.common.discovery.ModCandidate;
|
||||
import net.minecraftforge.fml.common.discovery.asm.ASMModParser;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLModContainer;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
@@ -28,7 +28,7 @@ import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.Set;
|
||||
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
@@ -24,6 +24,7 @@ import net.minecraftforge.fml.client.GuiWrongMinecraft;
|
||||
import net.minecraftforge.fml.client.IDisplayableError;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
public class WrongMinecraftVersionException extends EnhancedRuntimeException implements IDisplayableError
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
public class ASMDataTable
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ package net.minecraftforge.fml.common.discovery;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
public enum ContainerType
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.regex.Matcher;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.LoaderException;
|
||||
import net.minecraftforge.fml.common.MetadataCollection;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.ModContainerFactory;
|
||||
import net.minecraftforge.fml.common.discovery.asm.ASMModParser;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ package net.minecraftforge.fml.common.discovery;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
public interface ITypeDiscoverer
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.jar.JarFile;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.LoaderException;
|
||||
import net.minecraftforge.fml.common.MetadataCollection;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.ModContainerFactory;
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import net.minecraftforge.fml.common.discovery.asm.ASMModParser;
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.List;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.LoaderException;
|
||||
import net.minecraftforge.fml.common.ModClassLoader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.relauncher.CoreModManager;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2018.
|
||||
*
|
||||
* 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.common.event;
|
||||
|
||||
import net.minecraftforge.fml.common.ModClassLoader;
|
||||
import net.minecraftforge.fml.common.LoaderState.ModState;
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||
|
||||
import com.google.common.collect.ListMultimap;
|
||||
|
||||
/**
|
||||
* An internal FML event used to signal the construction of mods. Should not be used by mods.
|
||||
*/
|
||||
public class FMLConstructionEvent extends FMLStateEvent
|
||||
{
|
||||
private ModClassLoader modClassLoader;
|
||||
private ASMDataTable asmData;
|
||||
private ListMultimap<String,String> reverseDependencies;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public FMLConstructionEvent(Object... eventData)
|
||||
{
|
||||
this.modClassLoader = (ModClassLoader)eventData[0];
|
||||
this.asmData = (ASMDataTable) eventData[1];
|
||||
this.reverseDependencies = (ListMultimap<String, String>) eventData[2];
|
||||
}
|
||||
|
||||
public ModClassLoader getModClassLoader()
|
||||
{
|
||||
return modClassLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModState getModState()
|
||||
{
|
||||
return ModState.CONSTRUCTED;
|
||||
}
|
||||
|
||||
public ASMDataTable getASMHarvestedData()
|
||||
{
|
||||
return asmData;
|
||||
}
|
||||
|
||||
public ListMultimap<String, String> getReverseDependencies()
|
||||
{
|
||||
return reverseDependencies;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,8 @@ import net.minecraftforge.fml.common.Mod;
|
||||
* A special event used when the {@link Mod#certificateFingerprint()} doesn't match the certificate loaded from the JAR
|
||||
* file. You could use this to log a warning that the code that is running might not be yours, for example.
|
||||
*/
|
||||
public class FMLFingerprintViolationEvent extends FMLEvent {
|
||||
public class FMLFingerprintViolationEvent extends ModLifecycleEvent
|
||||
{
|
||||
|
||||
private final boolean isDirectory;
|
||||
private final Set<String> fingerprints;
|
||||
@@ -39,7 +40,7 @@ public class FMLFingerprintViolationEvent extends FMLEvent {
|
||||
|
||||
public FMLFingerprintViolationEvent(boolean isDirectory, File source, ImmutableSet<String> fingerprints, String expectedFingerprint)
|
||||
{
|
||||
super();
|
||||
super(null);
|
||||
this.isDirectory = isDirectory;
|
||||
this.source = source;
|
||||
this.fingerprints = fingerprints;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
package net.minecraftforge.fml.common.event;
|
||||
|
||||
import net.minecraftforge.fml.common.LoaderState.ModState;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
/**
|
||||
* Called after {@link FMLPreInitializationEvent} and before {@link FMLPostInitializationEvent} during mod
|
||||
@@ -34,18 +34,11 @@ import net.minecraftforge.fml.common.LoaderState.ModState;
|
||||
* @see net.minecraftforge.fml.common.Mod.EventHandler for how to subscribe to this event
|
||||
* @author cpw
|
||||
*/
|
||||
public class FMLInitializationEvent extends FMLStateEvent
|
||||
public class FMLInitializationEvent extends ModLifecycleEvent
|
||||
{
|
||||
|
||||
public FMLInitializationEvent(Object... data)
|
||||
public FMLInitializationEvent(final ModContainer container)
|
||||
{
|
||||
super(data);
|
||||
super(container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModState getModState()
|
||||
{
|
||||
return ModState.INITIALIZED;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,11 +24,13 @@ import java.util.Optional;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.ModThreadContext;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.LoaderState;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.Mod.Instance;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
@@ -54,9 +56,15 @@ public class FMLInterModComms {
|
||||
* @see net.minecraftforge.fml.common.Mod.EventHandler for how to subscribe to this event
|
||||
* @author cpw
|
||||
*/
|
||||
public static class IMCEvent extends FMLEvent {
|
||||
public static class IMCEvent extends ModLifecycleEvent
|
||||
{
|
||||
private ModContainer activeContainer;
|
||||
|
||||
public IMCEvent()
|
||||
{
|
||||
super(activeContainer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyModContainer(ModContainer activeContainer)
|
||||
{
|
||||
@@ -371,27 +379,19 @@ public class FMLInterModComms {
|
||||
|
||||
private static boolean enqueueStartupMessage(String modTarget, IMCMessage message)
|
||||
{
|
||||
if (Loader.instance().activeModContainer() == null)
|
||||
if (ModThreadContext.get().getCurrentContainer() == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
enqueueMessage(Loader.instance().activeModContainer(), modTarget, message);
|
||||
return Loader.isModLoaded(modTarget) && !Loader.instance().hasReachedState(LoaderState.POSTINITIALIZATION);
|
||||
enqueueMessage(ModThreadContext.get().getCurrentContainer(), modTarget, message);
|
||||
return ModList.get().isLoaded(modTarget);
|
||||
|
||||
}
|
||||
private static void enqueueMessage(Object sourceMod, String modTarget, IMCMessage message)
|
||||
private static void enqueueMessage(ModContainer sourceMod, String modTarget, IMCMessage message)
|
||||
{
|
||||
ModContainer mc;
|
||||
if (sourceMod instanceof ModContainer) {
|
||||
mc = (ModContainer) sourceMod;
|
||||
}
|
||||
else
|
||||
if (ModList.get().isLoaded(modTarget))
|
||||
{
|
||||
mc = FMLCommonHandler.instance().findContainerFor(sourceMod);
|
||||
}
|
||||
if (mc != null && Loader.isModLoaded(modTarget))
|
||||
{
|
||||
message.setSender(mc);
|
||||
message.setSender(sourceMod);
|
||||
modMessages.put(modTarget, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
package net.minecraftforge.fml.common.event;
|
||||
|
||||
import net.minecraftforge.fml.common.LoaderState.ModState;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
/**
|
||||
* This is a mostly internal event fired to mod containers that indicates that loading is complete. Mods should not
|
||||
@@ -27,18 +27,10 @@ import net.minecraftforge.fml.common.LoaderState.ModState;
|
||||
*
|
||||
* @author cpw
|
||||
*/
|
||||
public class FMLLoadCompleteEvent extends FMLStateEvent
|
||||
public class FMLLoadCompleteEvent extends ModLifecycleEvent
|
||||
{
|
||||
|
||||
public FMLLoadCompleteEvent(Object... data)
|
||||
public FMLLoadCompleteEvent(final ModContainer container)
|
||||
{
|
||||
super(data);
|
||||
super(container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModState getModState()
|
||||
{
|
||||
return ModState.AVAILABLE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2018.
|
||||
*
|
||||
* 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.common.event;
|
||||
|
||||
public class FMLModDisabledEvent extends FMLEvent {
|
||||
}
|
||||
@@ -42,7 +42,7 @@ import net.minecraft.util.ResourceLocation;
|
||||
* @see net.minecraftforge.fml.common.Mod.EventHandler for how to subscribe to this event
|
||||
* @author cpw
|
||||
*/
|
||||
public class FMLModIdMappingEvent extends FMLEvent
|
||||
public class FMLModIdMappingEvent extends ModLifecycleEvent
|
||||
{
|
||||
public class ModRemapping
|
||||
{
|
||||
@@ -66,6 +66,7 @@ public class FMLModIdMappingEvent extends FMLEvent
|
||||
public final boolean isFrozen;
|
||||
public FMLModIdMappingEvent(Map<ResourceLocation, Map<ResourceLocation, Integer[]>> remaps, boolean isFrozen)
|
||||
{
|
||||
super(null);
|
||||
this.isFrozen = isFrozen;
|
||||
this.remaps = Maps.newHashMap();
|
||||
remaps.forEach((name, rm) ->
|
||||
|
||||
@@ -19,15 +19,7 @@
|
||||
|
||||
package net.minecraftforge.fml.common.event;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.LoaderState.ModState;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
/**
|
||||
* Called after {@link FMLInitializationEvent} has been dispatched on every mod. This is the third and last
|
||||
@@ -38,45 +30,10 @@ import java.lang.reflect.Constructor;
|
||||
* @see net.minecraftforge.fml.common.Mod.EventHandler for how to subscribe to this event
|
||||
* @author cpw
|
||||
*/
|
||||
public class FMLPostInitializationEvent extends FMLStateEvent
|
||||
public class FMLPostInitializationEvent extends ModLifecycleEvent
|
||||
{
|
||||
public FMLPostInitializationEvent(Object... data)
|
||||
public FMLPostInitializationEvent(final ModContainer container)
|
||||
{
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModState getModState()
|
||||
{
|
||||
return ModState.POSTINITIALIZED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an object depending on if a specific target mod is loaded or not.
|
||||
*
|
||||
* Usually would be used to access an object from the other mod.
|
||||
*
|
||||
* @param modId The modId I conditionally want to build an object for
|
||||
* @param className The name of the class I wish to instantiate
|
||||
* @return An optional containing the object if possible, or null if not
|
||||
*/
|
||||
public Optional<?> buildSoftDependProxy(String modId, String className, Object... arguments)
|
||||
{
|
||||
if (Loader.isModLoaded(modId))
|
||||
{
|
||||
Class<?>[] args = Arrays.stream(arguments).filter(Objects::nonNull).map(Object::getClass).toArray(Class<?>[]::new);
|
||||
try
|
||||
{
|
||||
Class<?> clz = Class.forName(className,true,Loader.instance().getModClassLoader());
|
||||
Constructor<?> ct = clz.getConstructor(args);
|
||||
return Optional.of(ct.newInstance(arguments));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log.info("An error occurred trying to build a soft depend proxy", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
super(container);
|
||||
}
|
||||
}
|
||||
@@ -19,21 +19,8 @@
|
||||
|
||||
package net.minecraftforge.fml.common.event;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.CodeSource;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.minecraftforge.fml.javafmlmod.FMLModContainer;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.ModMetadata;
|
||||
import net.minecraftforge.fml.common.LoaderState.ModState;
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Called before {@link FMLInitializationEvent} during mod startup.
|
||||
@@ -50,131 +37,10 @@ import javax.annotation.Nullable;
|
||||
* @see net.minecraftforge.fml.common.Mod.EventHandler for how to subscribe to this event
|
||||
* @author cpw
|
||||
*/
|
||||
public class FMLPreInitializationEvent extends FMLStateEvent
|
||||
public class FMLPreInitializationEvent extends ModLifecycleEvent
|
||||
{
|
||||
private ModMetadata modMetadata;
|
||||
private File sourceFile;
|
||||
private File configurationDir;
|
||||
private File suggestedConfigFile;
|
||||
private ASMDataTable asmData;
|
||||
private ModContainer modContainer;
|
||||
|
||||
public FMLPreInitializationEvent(Object... data)
|
||||
public FMLPreInitializationEvent(final ModContainer container)
|
||||
{
|
||||
super(data);
|
||||
this.asmData = (ASMDataTable)data[0];
|
||||
this.configurationDir = (File)data[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModState getModState()
|
||||
{
|
||||
return ModState.PREINITIALIZED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyModContainer(ModContainer activeContainer)
|
||||
{
|
||||
this.modContainer = activeContainer;
|
||||
this.modMetadata = activeContainer.getMetadata();
|
||||
this.sourceFile = activeContainer.getSource();
|
||||
this.suggestedConfigFile = new File(configurationDir, activeContainer.getModId()+".cfg");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link File} the mod was loaded from
|
||||
* @return The file the mod was loaded from
|
||||
*/
|
||||
public File getSourceFile()
|
||||
{
|
||||
return sourceFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link ModMetadata} for this mod
|
||||
* @return the mod metadata for the mod
|
||||
*/
|
||||
public ModMetadata getModMetadata()
|
||||
{
|
||||
return modMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the main configuration directory for this minecraft instance
|
||||
* @return the main configuration directory
|
||||
*/
|
||||
public File getModConfigurationDirectory()
|
||||
{
|
||||
return configurationDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a suggested configuration file for this mod. It will be of the form <modid>.cfg
|
||||
* @return A suggested configuration file name for this mod
|
||||
*/
|
||||
public File getSuggestedConfigurationFile()
|
||||
{
|
||||
return suggestedConfigFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link ASMDataTable} for this instance of Minecraft. This is a special structure containing
|
||||
* parsing information from FML. It can be searched for annotations parsed out by FML.
|
||||
* @return
|
||||
*/
|
||||
public ASMDataTable getAsmData()
|
||||
{
|
||||
return asmData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a version.properties file as a {@link Properties} object from the mod file.
|
||||
* This can be used to load build-type information
|
||||
* such as a unique version number from a properties file shipped as part of the distributable.
|
||||
* @return A properties object if one exists, else null
|
||||
*/
|
||||
@Nullable
|
||||
public Properties getVersionProperties()
|
||||
{
|
||||
if (this.modContainer instanceof FMLModContainer)
|
||||
{
|
||||
return ((FMLModContainer)this.modContainer).searchForVersionProperties();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a logger instance configured to write to the FML Log as a parent, identified by modid. Handy for mod logging!
|
||||
*
|
||||
* @return A logger
|
||||
*/
|
||||
public Logger getModLog()
|
||||
{
|
||||
return LogManager.getLogger(modContainer.getModId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the FML signing certificates, if any. Validate these against the
|
||||
* published FML certificates in your mod, if you wish.
|
||||
*
|
||||
* Deprecated because mods should <b>NOT</b> trust this code. Rather
|
||||
* they should copy this, or something like this, into their own mods.
|
||||
*
|
||||
* @return Certificates used to sign FML and Forge
|
||||
*/
|
||||
@Deprecated
|
||||
public Certificate[] getFMLSigningCertificates()
|
||||
{
|
||||
CodeSource codeSource = getClass().getClassLoader().getParent().getClass().getProtectionDomain().getCodeSource();
|
||||
Certificate[] certs = codeSource.getCertificates();
|
||||
if (certs == null)
|
||||
{
|
||||
return new Certificate[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return certs;
|
||||
}
|
||||
super(container);
|
||||
}
|
||||
}
|
||||
@@ -20,25 +20,19 @@
|
||||
package net.minecraftforge.fml.common.event;
|
||||
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.LoaderState.ModState;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
/**
|
||||
* The parent of all mod-state changing events
|
||||
*/
|
||||
public abstract class FMLStateEvent extends FMLEvent
|
||||
public abstract class FMLStateEvent extends ModLifecycleEvent
|
||||
{
|
||||
public FMLStateEvent(Object... data)
|
||||
|
||||
public FMLStateEvent()
|
||||
{
|
||||
|
||||
super(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* The current state of the mod
|
||||
* @return The current state of the mod
|
||||
*/
|
||||
public abstract ModState getModState();
|
||||
|
||||
/**
|
||||
* The side we're loading on. {@link Side#CLIENT} means we're loading in the client, {@link Side#SERVER} means
|
||||
* we're loading in the dedicated server.
|
||||
|
||||
+10
-9
@@ -19,24 +19,25 @@
|
||||
|
||||
package net.minecraftforge.fml.common.event;
|
||||
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
/**
|
||||
* Parent type to all FML events. This is based on Guava EventBus. Event Subscription isn't using the Guava annotation
|
||||
* however, it's using a custom annotation specific to FML {@link net.minecraftforge.fml.common.Mod.EventHandler}
|
||||
* Parent type to all ModLifecycle events. This is based on Forge EventBus. They fire through the
|
||||
* ModContainer's eventbus instance.
|
||||
*/
|
||||
public class FMLEvent
|
||||
public class ModLifecycleEvent extends Event
|
||||
{
|
||||
public final String getEventType()
|
||||
private final ModContainer container;
|
||||
|
||||
public ModLifecycleEvent(ModContainer container)
|
||||
{
|
||||
return getClass().getSimpleName();
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
public final String description()
|
||||
{
|
||||
String cn = getClass().getName();
|
||||
return cn.substring(cn.lastIndexOf('.')+4,cn.length()-5);
|
||||
}
|
||||
public void applyModContainer(ModContainer activeContainer) {
|
||||
// NO OP
|
||||
}
|
||||
}
|
||||
@@ -25,12 +25,14 @@ import io.netty.channel.embedded.EmbeddedChannel;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraftforge.api.Side;
|
||||
import net.minecraftforge.fml.ModThreadContext;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.network.FMLOutboundHandler.OutboundTarget;
|
||||
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher;
|
||||
import net.minecraftforge.fml.common.network.internal.FMLProxyPacket;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.javafmlmod.ModLoadingContext;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -44,7 +46,7 @@ import javax.annotation.Nullable;
|
||||
public class FMLEmbeddedChannel extends EmbeddedChannel {
|
||||
public FMLEmbeddedChannel(String channelName, Side source, ChannelHandler... handlers)
|
||||
{
|
||||
this(Loader.instance().activeModContainer(), channelName, source, handlers);
|
||||
this(ModThreadContext.get().getCurrentContainer(), channelName, source, handlers);
|
||||
}
|
||||
public FMLEmbeddedChannel(ModContainer container, String channelName, Side source, ChannelHandler... handlers)
|
||||
{
|
||||
|
||||
@@ -35,16 +35,16 @@ import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.network.INetHandler;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.Side;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||
import net.minecraftforge.fml.common.network.FMLOutboundHandler.OutboundTarget;
|
||||
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher;
|
||||
import net.minecraftforge.fml.common.network.internal.FMLProxyPacket;
|
||||
import net.minecraftforge.fml.common.network.internal.NetworkModHolder;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
@@ -311,7 +311,7 @@ public enum NetworkRegistry
|
||||
{
|
||||
return registry.values().stream()
|
||||
.filter(mod -> !mod.acceptsVanilla(from))
|
||||
.map(mod -> mod.getContainer().getName())
|
||||
.map(mod -> mod.getContainer().getModId())
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
@@ -338,6 +338,7 @@ public enum NetworkRegistry
|
||||
*/
|
||||
public void fireNetworkHandshake(NetworkDispatcher networkDispatcher, Side origin)
|
||||
{
|
||||
/*
|
||||
NetworkHandshakeEstablished handshake = new NetworkHandshakeEstablished(networkDispatcher, networkDispatcher.getNetHandler(), origin);
|
||||
for (FMLEmbeddedChannel channel : channels.get(origin).values())
|
||||
{
|
||||
@@ -345,6 +346,7 @@ public enum NetworkRegistry
|
||||
channel.attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(networkDispatcher);
|
||||
channel.pipeline().fireUserEventTriggered(handshake);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void cleanAttributes()
|
||||
|
||||
+19
@@ -17,6 +17,25 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
// This method is called every tick (20 times per second normally)
|
||||
|
||||
if (world.isRemote) {
|
||||
// We only do something on the client so we don't have to bother about client-server communication.
|
||||
// The effect that we want to have (blinking the block) is client-side as well.
|
||||
updateCounter();
|
||||
counter -= lastCount * 3;
|
||||
if (counter <= 0) {
|
||||
lit = !lit;
|
||||
counter = 400; // This is 20 seconds. Rate increases if more mods are near
|
||||
world.markBlockRangeForRenderUpdate(getPos(), getPos());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCounter() {
|
||||
|
||||
package net.minecraftforge.fml.common.network.handshake;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ import java.util.Set;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.network.ByteBufUtils;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.common.network.internal.FMLProxyPacket;
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import net.minecraftforge.fml.client.FMLClientHandler;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.common.network.internal.FMLMessage.EntityMessage;
|
||||
import net.minecraftforge.fml.common.registry.EntityRegistry;
|
||||
|
||||
@@ -31,7 +31,7 @@ import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.network.ByteBufUtils;
|
||||
import net.minecraftforge.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
|
||||
@@ -42,7 +42,7 @@ import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.FMLContainer;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.network.FMLEmbeddedChannel;
|
||||
import net.minecraftforge.fml.common.network.FMLOutboundHandler;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
|
||||
@@ -23,15 +23,15 @@ import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraftforge.api.Side;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import net.minecraftforge.fml.common.network.NetworkCheckHandler;
|
||||
import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion;
|
||||
import net.minecraftforge.fml.common.versioning.InvalidVersionSpecificationException;
|
||||
import net.minecraftforge.fml.common.versioning.VersionRange;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
@@ -22,7 +22,7 @@ package net.minecraftforge.fml.common.network.simpleimpl;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.network.INetHandler;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.api.Side;
|
||||
|
||||
/**
|
||||
* Context for the {@link IMessageHandler}
|
||||
|
||||
+1
-1
@@ -19,13 +19,13 @@
|
||||
|
||||
package net.minecraftforge.fml.common.network.simpleimpl;
|
||||
|
||||
import net.minecraftforge.api.Side;
|
||||
import org.apache.logging.log4j.Level;
|
||||
|
||||
import net.minecraft.network.INetHandler;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.network.FMLOutboundHandler;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
|
||||
+1
-1
@@ -33,13 +33,13 @@ import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.network.INetHandler;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.api.Side;
|
||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
import net.minecraftforge.fml.common.network.FMLEmbeddedChannel;
|
||||
import net.minecraftforge.fml.common.network.FMLOutboundHandler;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry.TargetPoint;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
/**
|
||||
* This class is a simplified netty wrapper for those not wishing to deal with the full power of netty.
|
||||
|
||||
@@ -30,7 +30,7 @@ import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.relauncher.ReflectionHelper;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
@@ -32,7 +32,7 @@ import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.Biome.SpawnListEntry;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.network.internal.FMLMessage.EntitySpawnMessage;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -29,7 +29,7 @@ import net.minecraftforge.fml.common.DummyModContainer;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.ModAPIManager;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.toposort.TopologicalSort.DirectedGraph;
|
||||
import net.minecraftforge.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraftforge.fml.client.GuiSortingProblem;
|
||||
import net.minecraftforge.fml.client.IDisplayableError;
|
||||
import net.minecraftforge.fml.common.EnhancedRuntimeException;
|
||||
import net.minecraftforge.fml.common.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
package net.minecraftforge.fml.common.toposort;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import org.apache.logging.log4j.message.Message;
|
||||
import org.apache.logging.log4j.util.StringBuilderFormattable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -176,7 +180,7 @@ public class TopologicalSort
|
||||
return;
|
||||
}
|
||||
|
||||
throw new TopoSortException(node, sortedResult, visitedNodes, expandedNodes);
|
||||
throw new TopoSortException(new TopoSortException.TopoSortExceptionData<>(node, sortedResult, visitedNodes, expandedNodes));
|
||||
}
|
||||
|
||||
// Visit this node
|
||||
@@ -194,38 +198,68 @@ public class TopologicalSort
|
||||
expandedNodes.add(node);
|
||||
}
|
||||
|
||||
static class TopoSortException extends RuntimeException {
|
||||
private final Object node;
|
||||
private final List<?> sortedResult;
|
||||
private final Set<?> visitedNodes;
|
||||
private final Set<?> expandedNodes;
|
||||
public static class TopoSortException extends RuntimeException {
|
||||
private final TopoSortExceptionData<?> topoSortData;
|
||||
|
||||
public TopoSortException(Object node, List<?> sortedResult, Set<?> visitedNodes, Set<?> expandedNodes)
|
||||
public static class TopoSortExceptionData<T> implements Message, StringBuilderFormattable
|
||||
{
|
||||
this.node = node;
|
||||
this.sortedResult = sortedResult;
|
||||
this.visitedNodes = visitedNodes;
|
||||
this.expandedNodes = expandedNodes;
|
||||
private final List<T> sortedResult;
|
||||
private final Set<T> visitedNodes;
|
||||
private final Set<T> expandedNodes;
|
||||
private final T node;
|
||||
|
||||
TopoSortExceptionData(T node, List<T> sortedResult, Set<T> visitedNodes, Set<T> expandedNodes)
|
||||
{
|
||||
this.node = node;
|
||||
this.sortedResult = sortedResult;
|
||||
this.visitedNodes = visitedNodes;
|
||||
this.expandedNodes = expandedNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedMessage()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getParameters()
|
||||
{
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable getThrowable()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void formatTo(StringBuilder buffer)
|
||||
{
|
||||
buffer.append("Mod Sorting failed.\n");
|
||||
buffer.append("Visiting node {}\n").append(String.valueOf(node));
|
||||
buffer.append("Current sorted list : {}\n").append(String.valueOf(sortedResult));
|
||||
buffer.append("Visited set for this node : {}\n").append(String.valueOf(visitedNodes));
|
||||
buffer.append("Explored node set : {}\n").append(expandedNodes);
|
||||
buffer.append("Likely cycle is in : {}\n").append(Sets.difference(visitedNodes, expandedNodes));
|
||||
}
|
||||
}
|
||||
|
||||
public Object getNode()
|
||||
public <T> TopoSortException(TopoSortExceptionData<T> data)
|
||||
{
|
||||
return node;
|
||||
this.topoSortData = data;
|
||||
}
|
||||
|
||||
public List<?> getSortedResult()
|
||||
{
|
||||
return sortedResult;
|
||||
}
|
||||
|
||||
public Set<?> getVisitedNodes()
|
||||
{
|
||||
return visitedNodes;
|
||||
}
|
||||
|
||||
public Set<?> getExpandedNodes()
|
||||
{
|
||||
return expandedNodes;
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> TopoSortExceptionData<T> getData() {
|
||||
return (TopoSortExceptionData<T>)this.topoSortData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,23 +19,28 @@
|
||||
|
||||
package net.minecraftforge.fml.javafmlmod;
|
||||
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.language.IModLanguageProvider;
|
||||
import net.minecraftforge.fml.language.IModInfo;
|
||||
import net.minecraftforge.fml.language.ModFileScanData;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.minecraftforge.fml.Logging.LOADING;
|
||||
import static net.minecraftforge.fml.Logging.SCAN;
|
||||
import static net.minecraftforge.fml.Logging.fmlLog;
|
||||
|
||||
public class FMLJavaModLanguageProvider implements IModLanguageProvider
|
||||
{
|
||||
private static class FMLModTarget implements IModLanguageProvider.IModLanguageLoader {
|
||||
private static final Logger LOGGER = LogManager.getLogger("FML");
|
||||
private final String className;
|
||||
private final String modId;
|
||||
|
||||
@@ -50,10 +55,21 @@ public class FMLJavaModLanguageProvider implements IModLanguageProvider
|
||||
return modId;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ModContainer loadMod(final IModInfo info, final ClassLoader modClassLoader, final ModFileScanData modFileScanResults)
|
||||
public <T> T loadMod(final IModInfo info, final ClassLoader modClassLoader, final ModFileScanData modFileScanResults)
|
||||
{
|
||||
return new FMLModContainer(info, className, modClassLoader, modFileScanResults);
|
||||
try
|
||||
{
|
||||
final Constructor<?> constructor = Class.forName("net.minecraftforge.fml.javafmlmod.FMLModContainer", true, Thread.currentThread().getContextClassLoader()).
|
||||
getConstructor(IModInfo.class, String.class, ClassLoader.class, ModFileScanData.class);
|
||||
return (T)constructor.newInstance(info, className, modClassLoader, modFileScanResults);
|
||||
}
|
||||
catch (NoSuchMethodException | ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException e)
|
||||
{
|
||||
LOGGER.error(LOADING,"Unable to load FMLModContainer, wut?", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +87,7 @@ public class FMLJavaModLanguageProvider implements IModLanguageProvider
|
||||
final Map<String, FMLModTarget> modTargetMap = scanResult.getAnnotations().stream()
|
||||
.filter(ad -> ad.getAnnotationType().equals(MODANNOTATION))
|
||||
.peek(ad -> fmlLog.debug(SCAN, "Found @Mod class {} with id {}", ad.getClassType().getClassName(), ad.getAnnotationData().get("modid")))
|
||||
.map(ad -> new FMLModTarget(ad.getClassType().getClassName(), (String)ad.getAnnotationData().get("modid")))
|
||||
.map(ad -> new FMLModTarget(ad.getClassType().getClassName(), (String)ad.getAnnotationData().get("value")))
|
||||
.collect(Collectors.toMap(FMLModTarget::getModId, Function.identity()));
|
||||
scanResult.addLanguageLoader(modTargetMap);
|
||||
};
|
||||
|
||||
@@ -18,26 +18,22 @@
|
||||
*/
|
||||
package net.minecraftforge.fml.javafmlmod;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.minecraftforge.eventbus.EventBusErrorMessage;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.eventbus.api.IEventListener;
|
||||
import net.minecraftforge.fml.LifecycleEventProvider;
|
||||
import net.minecraftforge.fml.loading.ModLoadingStage;
|
||||
import net.minecraftforge.fml.common.Mod.Instance;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.common.event.ModLifecycleEvent;
|
||||
import net.minecraftforge.fml.AutomaticEventSubscriber;
|
||||
import net.minecraftforge.fml.ModLoadingStage;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.language.IModInfo;
|
||||
import net.minecraftforge.fml.language.ModFileScanData;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static net.minecraftforge.fml.Logging.LOADING;
|
||||
|
||||
@@ -45,6 +41,7 @@ public class FMLModContainer extends ModContainer
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger("FML");
|
||||
private final ModFileScanData scanResults;
|
||||
private final IEventBus eventBus;
|
||||
private Object modInstance;
|
||||
private final Class<?> modClass;
|
||||
|
||||
@@ -52,43 +49,65 @@ public class FMLModContainer extends ModContainer
|
||||
{
|
||||
super(info);
|
||||
this.scanResults = modFileScanResults;
|
||||
triggerMap.put(ModLoadingStage.BEGIN, this::constructMod);
|
||||
triggerMap.put(ModLoadingStage.PREINIT, this::preinitMod);
|
||||
triggerMap.put(ModLoadingStage.BEGIN, dummy().andThen(this::beforeEvent).andThen(this::constructMod).andThen(this::afterEvent));
|
||||
triggerMap.put(ModLoadingStage.CONSTRUCT, dummy().andThen(this::beforeEvent).andThen(this::preinitMod).andThen(this::fireEvent).andThen(this::afterEvent));
|
||||
triggerMap.put(ModLoadingStage.PREINIT, dummy().andThen(this::beforeEvent).andThen(this::initMod).andThen(this::fireEvent).andThen(this::afterEvent));
|
||||
this.eventBus = IEventBus.create(this::onEventFailed);
|
||||
|
||||
try
|
||||
{
|
||||
modClass = Class.forName(className, true, modClassLoader);
|
||||
LOGGER.error(LOADING,"Loaded modclass {} with {}", modClass.getName(), modClass.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
LOGGER.error(LOADING, "Failed to load class {}", className, e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void preinitMod(LifecycleEventProvider.LifecycleEvent lifecycleEvent)
|
||||
private void initMod(LifecycleEventProvider.LifecycleEvent lifecycleEvent)
|
||||
{
|
||||
|
||||
List<Pair<String, String>> instanceFields = scanResults.getAnnotations().stream().
|
||||
filter(a -> Objects.equals(a.getAnnotationType(), Type.getType(Instance.class)) &&
|
||||
Objects.equals(a.getClassType(), Type.getType(modClass))).
|
||||
map(a->Pair.of(a.getMemberName(), (String)a.getAnnotationData().get("value"))).
|
||||
collect(Collectors.toList());
|
||||
}
|
||||
|
||||
instanceFields.forEach(p->{
|
||||
try
|
||||
{
|
||||
final Field field = modClass.getDeclaredField(p.getLeft());
|
||||
field.setAccessible(true);
|
||||
field.set(modInstance, FMLLoader.getModLoader().getModList().getModObjectById(p.getRight()).get());
|
||||
}
|
||||
catch (NoSuchFieldException | IllegalAccessException e)
|
||||
{
|
||||
LOGGER.error(LOADING, "Unable to set field {} to mod with ID {}", p.getLeft(), p.getRight(), e);
|
||||
}
|
||||
});
|
||||
private Consumer<LifecycleEventProvider.LifecycleEvent> dummy() { return (s) -> {}; }
|
||||
|
||||
private void onEventFailed(IEventBus iEventBus, Event event, IEventListener[] iEventListeners, int i, Throwable throwable)
|
||||
{
|
||||
LOGGER.error(new EventBusErrorMessage(event, i, iEventListeners, throwable));
|
||||
}
|
||||
|
||||
private void beforeEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) {
|
||||
ModLoadingContext.get().activeContainer = this;
|
||||
}
|
||||
|
||||
private void fireEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) {
|
||||
final ModLifecycleEvent event = lifecycleEvent.buildModEvent(this);
|
||||
LOGGER.debug(LOADING, "Firing event {} for modid {}", event, this.getModId());
|
||||
try
|
||||
{
|
||||
eventBus.post(event);
|
||||
LOGGER.debug(LOADING, "Fired event {} for modid {}", event, this.getModId());
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
LOGGER.error(LOADING,"Caught exception during event {} dispatch for modid {}", event, this.getModId(), e);
|
||||
modLoadingStage = ModLoadingStage.ERROR;
|
||||
modLoadingError.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void afterEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) {
|
||||
ModLoadingContext.get().activeContainer = null;
|
||||
if (getCurrentState() == ModLoadingStage.ERROR) {
|
||||
LOGGER.error(LOADING,"An error occurred while dispatching event {} to {}", lifecycleEvent.fromStage(), getModId());
|
||||
}
|
||||
}
|
||||
|
||||
private void preinitMod(LifecycleEventProvider.LifecycleEvent lifecycleEvent)
|
||||
{
|
||||
AutomaticEventSubscriber.inject(this, this.scanResults, this.modClass.getClassLoader());
|
||||
}
|
||||
|
||||
private void constructMod(LifecycleEventProvider.LifecycleEvent event)
|
||||
@@ -99,10 +118,11 @@ public class FMLModContainer extends ModContainer
|
||||
this.modInstance = modClass.newInstance();
|
||||
LOGGER.debug(LOADING, "Loaded mod instance {} of type {}", getModId(), modClass.getName());
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
LOGGER.error("Failed to create mod instance. ModID: {}, class {}", getModId(), modClass.getName(), e);
|
||||
throw new RuntimeException("Failed to create mod instance", e);
|
||||
LOGGER.error(LOADING,"Failed to create mod instance. ModID: {}, class {}", getModId(), modClass.getName(), e);
|
||||
modLoadingStage = ModLoadingStage.ERROR;
|
||||
modLoadingError.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,9 +138,8 @@ public class FMLModContainer extends ModContainer
|
||||
return modInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getCustomExtension(final String name)
|
||||
public IEventBus getEventBus()
|
||||
{
|
||||
return ((Function<String,T>)modInstance).apply(name);
|
||||
return this.eventBus;
|
||||
}
|
||||
}
|
||||
+21
-3
@@ -17,9 +17,27 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.loading;
|
||||
package net.minecraftforge.fml.javafmlmod;
|
||||
|
||||
public enum ModLoadingStage
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.language.ExtensionPoint;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ModLoadingContext
|
||||
{
|
||||
ERROR, BEGIN, CONSTRUCT, PREINIT, INIT, POSTINIT, COMPLETE
|
||||
private static ThreadLocal<ModLoadingContext> context = ThreadLocal.withInitial(ModLoadingContext::new);
|
||||
FMLModContainer activeContainer;
|
||||
public static ModLoadingContext get() {
|
||||
return context.get();
|
||||
}
|
||||
|
||||
public <T> void registerExtensionPoint(ExtensionPoint<T> point, Supplier<T> extension) {
|
||||
activeContainer.registerExtensionPoint(point, extension);
|
||||
}
|
||||
|
||||
public IEventBus getModEventBus()
|
||||
{
|
||||
return activeContainer.getEventBus();
|
||||
}
|
||||
}
|
||||
+11
-8
@@ -17,14 +17,17 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.common.event;
|
||||
package net.minecraftforge.fml.language;
|
||||
|
||||
/**
|
||||
* Internal only event, used to begin the lifecycle of loading mods.
|
||||
*
|
||||
* @author cpw
|
||||
*/
|
||||
public class FMLLoadEvent
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.resources.IResourcePack;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ExtensionPoint<T>
|
||||
{
|
||||
|
||||
public static final ExtensionPoint<BiFunction<Minecraft, GuiScreen, GuiScreen>> GUIFACTORY = new ExtensionPoint<>();
|
||||
public static final ExtensionPoint<Function<Minecraft, IResourcePack>> RESOURCEPACK = new ExtensionPoint<>();
|
||||
}
|
||||
@@ -107,5 +107,10 @@ public interface IModInfo
|
||||
{
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public IModInfo getOwner()
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ package net.minecraftforge.fml.language;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Loaded as a ServiceLoader, from the classpath. Extensions are loaded from
|
||||
* Loaded as a ServiceLoader, from the classpath. ExtensionPoint are loaded from
|
||||
* the mods directory, with the FMLType META-INF of LANGPROVIDER.
|
||||
*
|
||||
* Version data is read from the manifest's implementation version.
|
||||
@@ -34,6 +34,6 @@ public interface IModLanguageProvider
|
||||
Consumer<ModFileScanData> getFileVisitor();
|
||||
|
||||
interface IModLanguageLoader {
|
||||
ModContainer loadMod(IModInfo info, ClassLoader modClassLoader, ModFileScanData modFileScanResults);
|
||||
<T> T loadMod(IModInfo info, ClassLoader modClassLoader, ModFileScanData modFileScanResults);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2018.
|
||||
*
|
||||
* 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.loading;
|
||||
|
||||
import com.electronwill.nightconfig.core.path.PathConfig;
|
||||
import net.minecraftforge.fml.language.IModInfo;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultModInfos
|
||||
{
|
||||
static {
|
||||
PathConfig minecraftmod;
|
||||
PathConfig forgemod;
|
||||
try
|
||||
{
|
||||
minecraftmod = PathConfig.of(Paths.get(DefaultModInfos.class.getClassLoader().getResource("minecraftmod.toml").toURI()));
|
||||
forgemod = PathConfig.of(Paths.get(DefaultModInfos.class.getClassLoader().getResource("forgemod.toml").toURI()));
|
||||
minecraftmod.load();
|
||||
forgemod.load();
|
||||
}
|
||||
catch (URISyntaxException | NullPointerException e)
|
||||
{
|
||||
throw new RuntimeException("Missing toml configs for minecraft and forge!", e);
|
||||
}
|
||||
minecraftModInfo = new ModInfo(null, minecraftmod);
|
||||
forgeModInfo = new ModInfo(null, forgemod);
|
||||
|
||||
}
|
||||
|
||||
public static final IModInfo minecraftModInfo;
|
||||
private static final IModInfo forgeModInfo;
|
||||
|
||||
// no construction
|
||||
private DefaultModInfos() {}
|
||||
|
||||
public static List<IModInfo> getModInfos()
|
||||
{
|
||||
return Arrays.asList(minecraftModInfo, forgeModInfo);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import cpw.mods.modlauncher.api.ILaunchHandlerService;
|
||||
import cpw.mods.modlauncher.api.ITransformingClassLoader;
|
||||
import net.minecraftforge.api.Side;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -72,6 +73,10 @@ public class FMLDevClientLaunchProvider extends FMLCommonLaunchHandler implement
|
||||
fmlLog.debug(CORE, "Launching minecraft in {} with arguments {}", launchClassLoader, arguments);
|
||||
super.beforeStart(launchClassLoader);
|
||||
launchClassLoader.addTargetPackageFilter(cn -> SKIPPACKAGES.stream().noneMatch(cn::startsWith));
|
||||
Field scl = ClassLoader.class.getDeclaredField("scl"); // Get system class loader
|
||||
scl.setAccessible(true); // Set accessible
|
||||
scl.set(null, launchClassLoader.getInstance()); // Update it to your class loader
|
||||
Thread.currentThread().setContextClassLoader(launchClassLoader.getInstance());
|
||||
Class.forName("net.minecraft.client.main.Main", true, launchClassLoader.getInstance()).getMethod("main", String[].class).invoke(null, (Object)arguments);
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -27,14 +27,11 @@ import cpw.mods.modlauncher.api.IncompatibleEnvironmentException;
|
||||
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
|
||||
import net.minecraftforge.api.Side;
|
||||
import net.minecraftforge.common.ForgeVersion;
|
||||
import net.minecraftforge.fml.common.FMLPaths;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModDiscoverer;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import net.minecraftforge.forgespi.ICoreModProvider;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
@@ -57,9 +54,8 @@ public class FMLLoader
|
||||
private static ILaunchPluginService eventBus;
|
||||
private static LanguageLoadingProvider languageLoadingProvider;
|
||||
private static Side side;
|
||||
private static ModList modList;
|
||||
private static LoadingModList loadingModList;
|
||||
private static ClassLoader launchClassLoader;
|
||||
private static ModLoader modLoader;
|
||||
|
||||
static void onInitialLoad(IEnvironment environment, Set<String> otherServices) throws IncompatibleEnvironmentException
|
||||
{
|
||||
@@ -134,7 +130,7 @@ public class FMLLoader
|
||||
fmlLog.debug(SCAN,"Scanning for Mod Locators");
|
||||
modDiscoverer = new ModDiscoverer();
|
||||
final BackgroundScanHandler backgroundScanHandler = modDiscoverer.discoverMods();
|
||||
modList = backgroundScanHandler.getModList();
|
||||
loadingModList = backgroundScanHandler.getLoadingModList();
|
||||
}
|
||||
|
||||
public static ICoreModProvider getCoreModProvider() {
|
||||
@@ -177,12 +173,18 @@ public class FMLLoader
|
||||
|
||||
public static void beforeStart(ITransformingClassLoader launchClassLoader)
|
||||
{
|
||||
modLoader = new ModLoader(launchClassLoader.getInstance(), modList);
|
||||
modLoader.classloadModFiles();
|
||||
FMLLoader.launchClassLoader = launchClassLoader.getInstance();
|
||||
}
|
||||
|
||||
public static ModLoader getModLoader()
|
||||
|
||||
public static LoadingModList getLoadingModList()
|
||||
{
|
||||
return modLoader;
|
||||
return loadingModList;
|
||||
|
||||
}
|
||||
|
||||
public static ClassLoader getLaunchClassLoader()
|
||||
{
|
||||
return launchClassLoader;
|
||||
}
|
||||
}
|
||||
+16
-11
@@ -19,13 +19,16 @@
|
||||
|
||||
package net.minecraftforge.fml.loading;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
import net.minecraftforge.fml.LifecycleEventProvider;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.ModLoadingStage;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -37,9 +40,9 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* Master list of all mods
|
||||
*/
|
||||
public class ModList
|
||||
public class LoadingModList
|
||||
{
|
||||
private static ModList INSTANCE;
|
||||
private static LoadingModList INSTANCE;
|
||||
private final List<ModFileInfo> modFiles;
|
||||
private final List<ModInfo> sortedList;
|
||||
private final Map<String, ModFileInfo> fileById;
|
||||
@@ -47,22 +50,24 @@ public class ModList
|
||||
private List<ModContainer> mods;
|
||||
private Map<String, ModContainer> indexedMods;
|
||||
|
||||
private ModList(final List<ModFile> modFiles, final List<ModInfo> sortedList)
|
||||
private LoadingModList(final List<ModFile> modFiles, final List<ModInfo> sortedList)
|
||||
{
|
||||
this.modFiles = modFiles.stream().map(ModFile::getModFileInfo).map(ModFileInfo.class::cast).collect(Collectors.toList());
|
||||
this.sortedList = sortedList;
|
||||
this.sortedList = Streams.concat(DefaultModInfos.getModInfos().stream(), sortedList.stream()).
|
||||
map(ModInfo.class::cast).
|
||||
collect(Collectors.toList());
|
||||
this.fileById = this.modFiles.stream().map(ModFileInfo::getMods).flatMap(Collection::stream).
|
||||
map(ModInfo.class::cast).
|
||||
collect(Collectors.toMap(ModInfo::getModId, ModInfo::getOwningFile));
|
||||
}
|
||||
|
||||
public static ModList of(List<ModFile> modFiles, List<ModInfo> sortedList)
|
||||
public static LoadingModList of(List<ModFile> modFiles, List<ModInfo> sortedList)
|
||||
{
|
||||
INSTANCE = new ModList(modFiles, sortedList);
|
||||
INSTANCE = new LoadingModList(modFiles, sortedList);
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static ModList get() {
|
||||
public static LoadingModList get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
public void addCoreMods()
|
||||
@@ -78,7 +83,7 @@ public class ModList
|
||||
public void addForScanning(BackgroundScanHandler backgroundScanHandler)
|
||||
{
|
||||
this.scanner = backgroundScanHandler;
|
||||
backgroundScanHandler.setModList(this);
|
||||
backgroundScanHandler.setLoadingModList(this);
|
||||
modFiles.stream().map(ModFileInfo::getFile).forEach(backgroundScanHandler::submitForScanning);
|
||||
}
|
||||
|
||||
@@ -91,7 +96,7 @@ public class ModList
|
||||
{
|
||||
for (ModFileInfo mf : modFiles) {
|
||||
final Path resource = mf.getFile().findResource(className);
|
||||
if (resource != null) return resource;
|
||||
if (Files.exists(resource)) return resource;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -109,7 +114,7 @@ public class ModList
|
||||
}
|
||||
}
|
||||
|
||||
public void setLoadedMods(List<ModContainer> modContainers)
|
||||
public void setLoadedMods(final List<ModContainer> modContainers)
|
||||
{
|
||||
this.mods = modContainers;
|
||||
this.indexedMods = modContainers.stream().collect(Collectors.toMap(ModContainer::getModId, Function.identity()));
|
||||
@@ -47,7 +47,7 @@ public class ModJarURLHandler extends URLStreamHandler
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException
|
||||
{
|
||||
return Files.newInputStream(FMLLoader.getModLoader().getModList().getModFileById(modid).getFile().findResource(modpath));
|
||||
return Files.newInputStream(FMLLoader.getLoadingModList().getModFileById(modid).getFile().findResource(modpath));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2018.
|
||||
*
|
||||
* 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.loading;
|
||||
|
||||
import net.minecraftforge.fml.LifecycleEventProvider;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ModLoader
|
||||
{
|
||||
private final ClassLoader launchClassLoader;
|
||||
private final ModList modList;
|
||||
private final ModLoadingClassLoader modClassLoader;
|
||||
|
||||
public ModLoader(final ClassLoader launchClassLoader, final ModList modList)
|
||||
{
|
||||
this.launchClassLoader = launchClassLoader;
|
||||
this.modList = modList;
|
||||
this.modClassLoader = new ModLoadingClassLoader(this, this.launchClassLoader);
|
||||
}
|
||||
|
||||
public void classloadModFiles()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ModList getModList()
|
||||
{
|
||||
return modList;
|
||||
}
|
||||
|
||||
public void loadMods() {
|
||||
modList.setLoadedMods(modList.getModFiles().stream().
|
||||
map(ModFileInfo::getFile).
|
||||
map(mf -> mf.buildMods(this.modClassLoader)).
|
||||
flatMap(Collection::stream).collect(Collectors.toList()));
|
||||
|
||||
LifecycleEventProvider.LOAD.dispatch(modList);
|
||||
LifecycleEventProvider.PREINIT.dispatch(modList);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
package net.minecraftforge.fml.loading;
|
||||
|
||||
import net.minecraftforge.fml.DefaultModContainers;
|
||||
import net.minecraftforge.fml.Java9BackportUtils;
|
||||
import net.minecraftforge.fml.common.DuplicateModsFoundException;
|
||||
import net.minecraftforge.fml.common.MissingModsException;
|
||||
@@ -27,14 +26,17 @@ import net.minecraftforge.fml.common.toposort.TopologicalSort;
|
||||
import net.minecraftforge.fml.common.versioning.ArtifactVersion;
|
||||
import net.minecraftforge.fml.language.IModInfo;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -42,34 +44,59 @@ import static net.minecraftforge.fml.Logging.LOADING;
|
||||
|
||||
public class ModSorter
|
||||
{
|
||||
private final List<ModFile> modFiles;
|
||||
private static final Logger LOGGER = LogManager.getLogger("FML");
|
||||
private List<ModFile> modFiles;
|
||||
private List<ModInfo> sortedList;
|
||||
private Map<String, ModInfo> modIdNameLookup;
|
||||
|
||||
public ModSorter(final List<ModFile> modFiles)
|
||||
private ModSorter(final List<ModFile> modFiles)
|
||||
{
|
||||
this.modFiles = modFiles;
|
||||
}
|
||||
|
||||
public static ModList sort(List<ModFile> mods)
|
||||
public static LoadingModList sort(List<ModFile> mods)
|
||||
{
|
||||
final ModSorter ms = new ModSorter(mods);
|
||||
ms.buildUniqueList();
|
||||
ms.verifyDependencyVersions();
|
||||
ms.sort();
|
||||
return ModList.of(ms.modFiles, ms.sortedList);
|
||||
return LoadingModList.of(ms.modFiles, ms.sortedList);
|
||||
}
|
||||
|
||||
private void sort() {
|
||||
final TopologicalSort.DirectedGraph<IModInfo> topoGraph = new TopologicalSort.DirectedGraph<>();
|
||||
modFiles.stream().map(ModFile::getModInfos).
|
||||
flatMap(Collection::stream).forEach(topoGraph::addNode);
|
||||
modFiles.stream().map(ModFile::getModInfos).
|
||||
flatMap(Collection::stream).map(IModInfo::getDependencies).flatMap(Collection::stream).forEach(dep->addDependency(topoGraph, dep));
|
||||
}
|
||||
|
||||
private void addDependency(TopologicalSort.DirectedGraph<IModInfo> topoGraph, IModInfo.ModVersion dep)
|
||||
private void sort()
|
||||
{
|
||||
final TopologicalSort.DirectedGraph<Supplier<ModFileInfo>> topoGraph = new TopologicalSort.DirectedGraph<>();
|
||||
modFiles.stream().map(ModFile::getModFileInfo).map(ModFileInfo.class::cast).forEach(mi -> topoGraph.addNode(() -> mi));
|
||||
modFiles.stream().map(ModFile::getModInfos).flatMap(Collection::stream).map(IModInfo::getDependencies).flatMap(Collection::stream).
|
||||
forEach(dep -> addDependency(topoGraph, dep));
|
||||
final List<Supplier<ModFileInfo>> sorted;
|
||||
try
|
||||
{
|
||||
sorted = TopologicalSort.topologicalSort(topoGraph);
|
||||
}
|
||||
catch (TopologicalSort.TopoSortException e)
|
||||
{
|
||||
TopologicalSort.TopoSortException.TopoSortExceptionData<Supplier<ModInfo>> data = e.getData();
|
||||
LOGGER.error(LOADING, ()-> data);
|
||||
throw e;
|
||||
}
|
||||
this.sortedList = sorted.stream().map(Supplier::get).map(ModFileInfo::getMods).
|
||||
flatMap(Collection::stream).map(ModInfo.class::cast).collect(Collectors.toList());
|
||||
this.modFiles = sorted.stream().map(Supplier::get).map(ModFileInfo::getFile).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void addDependency(TopologicalSort.DirectedGraph<Supplier<ModFileInfo>> topoGraph,IModInfo.ModVersion dep)
|
||||
{
|
||||
switch (dep.getOrdering()) {
|
||||
case BEFORE:
|
||||
topoGraph.addEdge(()->(ModFileInfo)dep.getOwner().getOwningFile(), ()->modIdNameLookup.get(dep.getModId()).getOwningFile());
|
||||
break;
|
||||
case AFTER:
|
||||
topoGraph.addEdge(()->modIdNameLookup.get(dep.getModId()).getOwningFile(), ()->(ModFileInfo)dep.getOwner().getOwningFile());
|
||||
break;
|
||||
case NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void buildUniqueList()
|
||||
@@ -90,7 +117,7 @@ public class ModSorter
|
||||
private void verifyDependencyVersions()
|
||||
{
|
||||
final Map<String, ArtifactVersion> modVersions = Stream.concat(modFiles.stream().map(ModFile::getModInfos).
|
||||
flatMap(Collection::stream), DefaultModContainers.getModInfos().stream()).collect(Collectors.toMap(IModInfo::getModId, IModInfo::getVersion));
|
||||
flatMap(Collection::stream), DefaultModInfos.getModInfos().stream()).collect(Collectors.toMap(IModInfo::getModId, IModInfo::getVersion));
|
||||
final Map<IModInfo, List<IModInfo.ModVersion>> modVersionDependencies = modFiles.stream().
|
||||
map(ModFile::getModInfos).flatMap(Collection::stream).
|
||||
collect(Collectors.groupingBy(Function.identity(), Java9BackportUtils.flatMapping(e -> e.getDependencies().stream(), Collectors.toList())));
|
||||
|
||||
+6
-6
@@ -20,7 +20,7 @@
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import net.minecraftforge.fml.language.ModFileScanData;
|
||||
import net.minecraftforge.fml.loading.ModList;
|
||||
import net.minecraftforge.fml.loading.LoadingModList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -38,7 +38,7 @@ public class BackgroundScanHandler
|
||||
private final List<ModFile> pendingFiles;
|
||||
private final List<ModFile> scannedFiles;
|
||||
private final List<ModFile> allFiles;
|
||||
private ModList modList;
|
||||
private LoadingModList loadingModList;
|
||||
|
||||
public BackgroundScanHandler() {
|
||||
modContentScanner = Executors.newSingleThreadExecutor(r -> {
|
||||
@@ -86,13 +86,13 @@ public class BackgroundScanHandler
|
||||
return allFiles;
|
||||
}
|
||||
|
||||
public void setModList(ModList modList)
|
||||
public void setLoadingModList(LoadingModList loadingModList)
|
||||
{
|
||||
this.modList = modList;
|
||||
this.loadingModList = loadingModList;
|
||||
}
|
||||
|
||||
public ModList getModList()
|
||||
public LoadingModList getLoadingModList()
|
||||
{
|
||||
return modList;
|
||||
return loadingModList;
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import cpw.mods.modlauncher.ServiceLoaderStreamUtils;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.loading.ModList;
|
||||
import net.minecraftforge.fml.loading.LoadingModList;
|
||||
import net.minecraftforge.fml.loading.ModSorter;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -70,10 +70,10 @@ public class ModDiscoverer {
|
||||
}
|
||||
}
|
||||
fmlLog.debug(SCAN,"Found {} mod files with {} mods", mods::size, ()->mods.stream().mapToInt(mf -> mf.getModInfos().size()).sum());
|
||||
final ModList modList = ModSorter.sort(mods);
|
||||
modList.addCoreMods();
|
||||
modList.addAccessTransformers();
|
||||
modList.addForScanning(backgroundScanHandler);
|
||||
final LoadingModList loadingModList = ModSorter.sort(mods);
|
||||
loadingModList.addCoreMods();
|
||||
loadingModList.addAccessTransformers();
|
||||
loadingModList.addForScanning(backgroundScanHandler);
|
||||
return backgroundScanHandler;
|
||||
}
|
||||
}
|
||||
@@ -20,13 +20,11 @@
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.language.IModFileInfo;
|
||||
import net.minecraftforge.fml.language.IModInfo;
|
||||
import net.minecraftforge.fml.language.ModFileScanData;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.language.IModLanguageProvider;
|
||||
import net.minecraftforge.fml.loading.ModLoadingClassLoader;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -37,11 +35,9 @@ import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.minecraftforge.fml.Logging.LOADING;
|
||||
import static net.minecraftforge.fml.Logging.SCAN;
|
||||
@@ -74,12 +70,6 @@ public class ModFile
|
||||
return locator.findPath(this, className);
|
||||
}
|
||||
|
||||
public List<ModContainer> buildMods(ModLoadingClassLoader modClassLoader)
|
||||
{
|
||||
return getScanResult().getTargets().entrySet().stream().
|
||||
map(e->e.getValue().loadMod(this.modInfoMap.get(e.getKey()), modClassLoader, getScanResult())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
MOD, LIBRARY, LANGPROVIDER
|
||||
}
|
||||
@@ -88,7 +78,6 @@ public class ModFile
|
||||
private final Manifest manifest;
|
||||
private final IModLocator locator;
|
||||
private IModFileInfo modFileInfo;
|
||||
private Map<String, IModInfo> modInfoMap;
|
||||
private ModFileScanData fileModFileScanData;
|
||||
private CompletableFuture<ModFileScanData> futureScanResult;
|
||||
private List<CoreModFile> coreMods;
|
||||
@@ -129,7 +118,6 @@ public class ModFile
|
||||
this.modFileInfo = ModFileParser.readModList(this);
|
||||
if (this.modFileInfo == null) return false;
|
||||
fmlLog.debug(LOADING,"Loading mod file {} with language {}", this.getFilePath(), this.modFileInfo.getModLoader());
|
||||
this.modInfoMap = this.getModInfos().stream().collect(Collectors.toMap(IModInfo::getModId, Function.identity()));
|
||||
this.coreMods = ModFileParser.getCoreMods(this);
|
||||
this.coreMods.forEach(mi-> fmlLog.debug(LOADING,"Found coremod {}", mi.getPath()));
|
||||
this.accessTransformer = locator.findPath(this, "META-INF", "accesstransformer.cfg");
|
||||
|
||||
@@ -42,7 +42,7 @@ import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.IFMLSidedHandler;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.common.StartupQuery;
|
||||
import net.minecraftforge.fml.common.network.FMLNetworkEvent;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.Set;
|
||||
import net.minecraft.block.BlockPrismarine;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.init.Blocks;
|
||||
|
||||
@@ -28,7 +28,7 @@ import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.language.ModContainer;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
@Mod(modid = "forgemodnametooltip", name = "ForgeModNameTooltip", version = "1.0", clientSideOnly = true)
|
||||
|
||||
Reference in new issue
Block a user