From d8215143728b74b8884341acbae3f8aadacc523d Mon Sep 17 00:00:00 2001 From: cpw Date: Sat, 15 Jun 2019 21:24:45 -0400 Subject: [PATCH] Modify lex's data handler to use proper mod lifecycle event mechanisms instead. New Lifecycle Event for requesting data harvesting. Mods will be constructed, the registry will fire, and then a new Data event will fire. Submit new data tag files to the data gatherer if you wish. The game will shutdown after this. No other mod elements will happen. Signed-off-by: cpw --- .../net/minecraft/data/Main.java.patch | 26 ++---- .../net/minecraftforge/common/ForgeMod.java | 2 +- .../minecraftforge/event/GatherDataEvent.java | 50 ----------- .../fml/LifecycleEventProvider.java | 19 +++- .../net/minecraftforge/fml/ModLoader.java | 42 ++++++--- .../minecraftforge/fml/ModLoadingStage.java | 3 +- .../fml/event/lifecycle/GatherDataEvent.java | 87 +++++++++++++++++++ .../fml/javafmlmod/FMLModContainer.java | 1 + 8 files changed, 147 insertions(+), 83 deletions(-) delete mode 100644 src/main/java/net/minecraftforge/event/GatherDataEvent.java create mode 100644 src/main/java/net/minecraftforge/fml/event/lifecycle/GatherDataEvent.java diff --git a/patches/minecraft/net/minecraft/data/Main.java.patch b/patches/minecraft/net/minecraft/data/Main.java.patch index 0498c66cf..912e2d88f 100644 --- a/patches/minecraft/net/minecraft/data/Main.java.patch +++ b/patches/minecraft/net/minecraft/data/Main.java.patch @@ -7,21 +7,19 @@ import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; -@@ -21,8 +22,12 @@ +@@ -21,8 +22,10 @@ OptionSpec optionspec6 = optionparser.accepts("all", "Include all generators"); OptionSpec optionspec7 = optionparser.accepts("output", "Output folder").withRequiredArg().defaultsTo("generated"); OptionSpec optionspec8 = optionparser.accepts("input", "Input folder").withRequiredArg(); -+ OptionSpec gameDir = optionparser.accepts("gameDir").withRequiredArg().ofType(File.class).defaultsTo(new File(".")); -+ OptionSpec mod = optionparser.accepts("mod", "The mod to dump").withRequiredArg(); -+ net.minecraft.util.registry.Bootstrap.func_151354_b(); -+ net.minecraftforge.fml.ModLoader.get().loadMods(); ++ OptionSpec gameDir = optionparser.accepts("gameDir").withRequiredArg().ofType(File.class).defaultsTo(new File(".")).required(); ++ OptionSpec mod = optionparser.accepts("mod", "A modid to dump").withRequiredArg().withValuesSeparatedBy(","); OptionSet optionset = optionparser.parse(p_main_0_); - if (!optionset.has(optionspec) && optionset.hasOptions()) { + if (!optionset.has(optionspec) && optionset.hasOptions() && !(optionset.specs().size() == 1 && optionset.has(gameDir))) { Path path = Paths.get(optionspec7.value(optionset)); boolean flag = optionset.has(optionspec6); boolean flag1 = flag || optionset.has(optionspec2); -@@ -30,10 +35,23 @@ +@@ -30,10 +33,11 @@ boolean flag3 = flag || optionset.has(optionspec3); boolean flag4 = flag || optionset.has(optionspec4); boolean flag5 = flag || optionset.has(optionspec5); @@ -30,20 +28,8 @@ - }).collect(Collectors.toList()), flag1, flag2, flag3, flag4, flag5); - datagenerator.func_200392_c(); + Collection inputs = optionset.valuesOf(optionspec8).stream().map(Paths::get).collect(Collectors.toList()); -+ java.util.Set mods = optionset.valuesOf(mod).stream().collect(Collectors.toSet()); -+ net.minecraftforge.fml.ModList.get().forEachModContainer((modid, mc) -> { -+ try { -+ //We have to go to the subclass, as ModContainer doesn't have the event bus. -+ if (mods.contains(modid) && mc instanceof net.minecraftforge.fml.javafmlmod.FMLModContainer) { -+ DataGenerator gen = new DataGenerator(mods.size() == 1 ? path : path.resolve(modid), inputs); -+ ((net.minecraftforge.fml.javafmlmod.FMLModContainer)mc).getEventBus().post(new net.minecraftforge.event.GatherDataEvent(gen, flag2, flag1, flag3, flag4, flag5)); -+ gen.func_200392_c(); -+ } -+ } catch (IOException e) { -+ e.printStackTrace(); -+ } -+ }); -+ ++ java.util.Set mods = new java.util.HashSet<>(optionset.valuesOf(mod)); ++ net.minecraftforge.fml.ModLoader.get().runDataGenerator(mods, path, inputs, flag2, flag1, flag3, flag4, flag5); + if (mods.contains("minecraft") || mods.isEmpty()) + func_200264_a(mods.isEmpty() ? path : path.resolve("minecraft"), inputs, flag1, flag2, flag3, flag4, flag5).func_200392_c(); } else { diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index fe567e50a..095a3d976 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -54,7 +54,7 @@ import net.minecraftforge.common.data.ForgeBlockTagsProvider; import net.minecraftforge.common.data.ForgeItemTagsProvider; import net.minecraftforge.common.model.animation.CapabilityAnimation; import net.minecraftforge.energy.CapabilityEnergy; -import net.minecraftforge.event.GatherDataEvent; +import net.minecraftforge.fml.event.lifecycle.GatherDataEvent; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.resource.ISelectiveResourceReloadListener; diff --git a/src/main/java/net/minecraftforge/event/GatherDataEvent.java b/src/main/java/net/minecraftforge/event/GatherDataEvent.java deleted file mode 100644 index 87007cb82..000000000 --- a/src/main/java/net/minecraftforge/event/GatherDataEvent.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2019. - * - * 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.event; - -import net.minecraft.data.DataGenerator; -import net.minecraftforge.eventbus.api.Event; - -public class GatherDataEvent extends Event -{ - private final DataGenerator generator; - private final boolean server; - private final boolean client; - private final boolean dev; - private final boolean reports; - private final boolean validate; - - public GatherDataEvent(DataGenerator gen, boolean server, boolean client, boolean dev, boolean reports, boolean validate) - { - this.generator = gen; - this.server = server; - this.client = client; - this.dev = dev; - this.reports = reports; - this.validate = validate; - } - - public DataGenerator getGenerator() { return this.generator; } - public boolean includeServer() { return this.server; } - public boolean includeClient() { return this.client; } - public boolean includeDev() { return this.dev; } - public boolean includeReports() { return this.reports; } - public boolean validate() { return this.validate; } -} diff --git a/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java b/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java index b580d4355..3ad7acd5f 100644 --- a/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java +++ b/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java @@ -37,7 +37,8 @@ public enum LifecycleEventProvider SIDED_SETUP(()->new LifecycleEvent(ModLoadingStage.SIDED_SETUP)), ENQUEUE_IMC(()->new LifecycleEvent(ModLoadingStage.ENQUEUE_IMC)), PROCESS_IMC(()->new LifecycleEvent(ModLoadingStage.PROCESS_IMC)), - COMPLETE(()->new LifecycleEvent(ModLoadingStage.COMPLETE)); + COMPLETE(()->new LifecycleEvent(ModLoadingStage.COMPLETE)), + GATHERDATA(()->new GatherDataLifecycleEvent(ModLoadingStage.GATHERDATA), ModList.inlineDispatcher); private final Supplier event; private final BiConsumer>> eventDispatcher; @@ -130,4 +131,20 @@ public enum LifecycleEventProvider } } } + + private static class GatherDataLifecycleEvent extends LifecycleEvent { + GatherDataLifecycleEvent(final ModLoadingStage stage) { + super(stage); + } + + @Override + public ModLoadingStage fromStage() { + return ModLoadingStage.COMMON_SETUP; + } + + @Override + public ModLoadingStage toStage() { + return ModLoadingStage.DONE; + } + } } diff --git a/src/main/java/net/minecraftforge/fml/ModLoader.java b/src/main/java/net/minecraftforge/fml/ModLoader.java index 9920938d5..b61ea8436 100644 --- a/src/main/java/net/minecraftforge/fml/ModLoader.java +++ b/src/main/java/net/minecraftforge/fml/ModLoader.java @@ -21,12 +21,16 @@ package net.minecraftforge.fml; import com.google.common.collect.ImmutableList; import cpw.mods.modlauncher.TransformingClassLoader; +import net.minecraft.data.DataGenerator; +import net.minecraft.util.registry.Bootstrap; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.fml.config.ConfigTracker; import net.minecraftforge.fml.config.ModConfig; +import net.minecraftforge.fml.event.lifecycle.GatherDataEvent; +import net.minecraftforge.fml.event.lifecycle.ModLifecycleEvent; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.FMLPaths; import net.minecraftforge.fml.loading.LoadingModList; @@ -41,11 +45,9 @@ import net.minecraftforge.registries.ObjectHolderRegistry; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.io.IOException; +import java.nio.file.Path; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -97,6 +99,8 @@ public class ModLoader private final List loadingExceptions; private final List loadingWarnings; + private GatherDataEvent.DataGeneratorConfig dataGeneratorConfig; + private ModLoader() { INSTANCE = this; @@ -120,6 +124,15 @@ public class ModLoader } public void loadMods() { + gatherAndInitializeMods(); + DistExecutor.runWhenOn(Dist.CLIENT, ()->()-> ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.CLIENT, FMLPaths.CONFIGDIR.get())); + ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.COMMON, FMLPaths.CONFIGDIR.get()); + dispatchAndHandleError(LifecycleEventProvider.SETUP); + DistExecutor.runWhenOn(Dist.CLIENT, ModLoader::fireClientEvents); + dispatchAndHandleError(LifecycleEventProvider.SIDED_SETUP); + } + + private void gatherAndInitializeMods() { final ModList modList = ModList.of(loadingModList.getModFiles().stream().map(ModFileInfo::getFile).collect(Collectors.toList()), loadingModList.getMods()); if (!this.loadingExceptions.isEmpty()) { throw new LoadingFailedException(loadingExceptions); @@ -139,11 +152,6 @@ public class ModLoader ObjectHolderRegistry.findObjectHolders(); CapabilityManager.INSTANCE.injectCapabilities(modList.getAllScanData()); GameData.fireRegistryEvents(rl->true, LifecycleEventProvider.LOAD_REGISTRIES, this::dispatchAndHandleError); - DistExecutor.runWhenOn(Dist.CLIENT, ()->()-> ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.CLIENT, FMLPaths.CONFIGDIR.get())); - ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.COMMON, FMLPaths.CONFIGDIR.get()); - dispatchAndHandleError(LifecycleEventProvider.SETUP); - DistExecutor.runWhenOn(Dist.CLIENT, ModLoader::fireClientEvents); - dispatchAndHandleError(LifecycleEventProvider.SIDED_SETUP); } private void dispatchAndHandleError(LifecycleEventProvider event) { @@ -211,4 +219,18 @@ public class ModLoader { this.loadingWarnings.add(warning); } + + public void runDataGenerator(final Set mods, final Path path, final Collection inputs, final boolean serverGenerators, final boolean clientGenerators, final boolean devToolGenerators, final boolean reportsGenerator, final boolean structureValidator) { + if (mods.contains("minecraft") && mods.size() == 1) return; + LOGGER.info("Initializing Data Gatherer for mods {}", mods); + Bootstrap.register(); + dataGeneratorConfig = new GatherDataEvent.DataGeneratorConfig(mods, path, inputs, serverGenerators, clientGenerators, devToolGenerators, reportsGenerator, structureValidator); + gatherAndInitializeMods(); + dispatchAndHandleError(LifecycleEventProvider.GATHERDATA); + dataGeneratorConfig.runAll(); + } + + public Function getDataGeneratorEvent() { + return mc -> new GatherDataEvent(mc, dataGeneratorConfig.makeGenerator(p->dataGeneratorConfig.getMods().size() == 1 ? p : p.resolve(mc.getModId())), dataGeneratorConfig); + } } diff --git a/src/main/java/net/minecraftforge/fml/ModLoadingStage.java b/src/main/java/net/minecraftforge/fml/ModLoadingStage.java index 70d9ace42..0801911fb 100644 --- a/src/main/java/net/minecraftforge/fml/ModLoadingStage.java +++ b/src/main/java/net/minecraftforge/fml/ModLoadingStage.java @@ -36,7 +36,8 @@ public enum ModLoadingStage ENQUEUE_IMC(()-> InterModEnqueueEvent::new), PROCESS_IMC(()-> InterModProcessEvent::new), COMPLETE(()-> FMLLoadCompleteEvent::new), - DONE(null); + DONE(null), + GATHERDATA(ModLoader.get()::getDataGeneratorEvent); private final Supplier> modLifecycleEventFunction; ModLoadingStage(Supplier> modLifecycleEventFunction) diff --git a/src/main/java/net/minecraftforge/fml/event/lifecycle/GatherDataEvent.java b/src/main/java/net/minecraftforge/fml/event/lifecycle/GatherDataEvent.java new file mode 100644 index 000000000..5f273df64 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/event/lifecycle/GatherDataEvent.java @@ -0,0 +1,87 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * 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.event.lifecycle; + +import cpw.mods.modlauncher.api.LamdbaExceptionUtils; +import net.minecraft.data.DataGenerator; +import net.minecraftforge.fml.ModContainer; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.function.Function; + +public class GatherDataEvent extends ModLifecycleEvent +{ + private final DataGenerator dataGenerator; + private final DataGeneratorConfig config; + public GatherDataEvent(final ModContainer modContainer, final DataGenerator dataGenerator, final DataGeneratorConfig dataGeneratorConfig) + { + super(modContainer); + this.dataGenerator = dataGenerator; + this.config = dataGeneratorConfig; + } + + public DataGenerator getGenerator() { return this.dataGenerator; } + public boolean includeServer() { return this.config.server; } + public boolean includeClient() { return this.config.client; } + public boolean includeDev() { return this.config.dev; } + public boolean includeReports() { return this.config.reports; } + public boolean validate() { return this.config.validate; } + + public static class DataGeneratorConfig { + private final Set mods; + private final Path path; + private final Collection inputs; + private final boolean server; + private final boolean client; + private final boolean dev; + private final boolean reports; + private final boolean validate; + private List generators = new ArrayList<>(); + + public DataGeneratorConfig(final Set mods, final Path path, final Collection inputs, final boolean server, final boolean client, final boolean dev, final boolean reports, final boolean validate) { + this.mods = mods; + this.path = path; + this.inputs = inputs; + this.server = server; + this.client = client; + this.dev = dev; + this.reports = reports; + this.validate = validate; + } + + public Set getMods() { + return mods; + } + + public DataGenerator makeGenerator(final Function pathEnhancer) { + final DataGenerator generator = new DataGenerator(pathEnhancer.apply(path), inputs); + generators.add(generator); + return generator; + } + + public void runAll() { + generators.forEach(LamdbaExceptionUtils.rethrowConsumer(DataGenerator::run)); + } + } +} diff --git a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java index 750a0a891..0f13a66df 100644 --- a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java +++ b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java @@ -61,6 +61,7 @@ public class FMLModContainer extends ModContainer triggerMap.put(ModLoadingStage.ENQUEUE_IMC, dummy().andThen(this::beforeEvent).andThen(this::initMod).andThen(this::fireEvent).andThen(this::afterEvent)); triggerMap.put(ModLoadingStage.PROCESS_IMC, dummy().andThen(this::beforeEvent).andThen(this::fireEvent).andThen(this::afterEvent)); triggerMap.put(ModLoadingStage.COMPLETE, dummy().andThen(this::beforeEvent).andThen(this::completeLoading).andThen(this::fireEvent).andThen(this::afterEvent)); + triggerMap.put(ModLoadingStage.GATHERDATA, dummy().andThen(this::beforeEvent).andThen(this::fireEvent).andThen(this::afterEvent)); this.eventBus = BusBuilder.builder().setExceptionHandler(this::onEventFailed).setTrackPhases(false).build(); this.configHandler = Optional.of(event -> this.eventBus.post(event)); final FMLJavaModLoadingContext contextExtension = new FMLJavaModLoadingContext(this);