From fd045d4628d726f60a4fc4972666e9af4de2cfe9 Mon Sep 17 00:00:00 2001 From: Richard Freimer Date: Sun, 22 Nov 2020 22:45:13 -0500 Subject: [PATCH] Add support for referencing forge's resources and specifying existing mods to data generators (#7456) --- .../net/minecraft/data/Main.java.patch | 8 +++--- src/generated_test/resources/.cache/cache | 2 +- .../data/data_gen_test/tags/blocks/test.json | 1 + .../model/generators/ModelProvider.java | 2 +- .../common/data/ExistingFileHelper.java | 25 ++++++++++++++++--- .../minecraftforge/fml/DatagenModLoader.java | 14 +++++++++-- .../debug/DataGeneratorTest.java | 1 + 7 files changed, 43 insertions(+), 10 deletions(-) diff --git a/patches/minecraft/net/minecraft/data/Main.java.patch b/patches/minecraft/net/minecraft/data/Main.java.patch index 48b279199..199233885 100644 --- a/patches/minecraft/net/minecraft/data/Main.java.patch +++ b/patches/minecraft/net/minecraft/data/Main.java.patch @@ -1,10 +1,11 @@ --- a/net/minecraft/data/Main.java +++ b/net/minecraft/data/Main.java -@@ -21,8 +21,12 @@ +@@ -21,8 +21,13 @@ 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 existing = optionparser.accepts("existing", "Existing resource packs that generated resources can reference").withRequiredArg(); ++ OptionSpec existingMod = optionparser.accepts("existing-mod", "Existing mods that generated resources can reference the resource packs of").withRequiredArg(); + OptionSpec gameDir = optionparser.accepts("gameDir").withRequiredArg().ofType(java.io.File.class).defaultsTo(new java.io.File(".")).required(); //Need by modlauncher, so lets just eat it + OptionSpec mod = optionparser.accepts("mod", "A modid to dump").withRequiredArg().withValuesSeparatedBy(","); + OptionSpec flat = optionparser.accepts("flat", "Do not append modid prefix to output directory when generating for multiple mods"); @@ -14,7 +15,7 @@ Path path = Paths.get(optionspec7.value(optionset)); boolean flag = optionset.has(optionspec6); boolean flag1 = flag || optionset.has(optionspec2); -@@ -30,10 +34,13 @@ +@@ -30,10 +35,14 @@ boolean flag3 = flag || optionset.has(optionspec3); boolean flag4 = flag || optionset.has(optionspec4); boolean flag5 = flag || optionset.has(optionspec5); @@ -24,9 +25,10 @@ - datagenerator.func_200392_c(); + Collection inputs = optionset.valuesOf(optionspec8).stream().map(Paths::get).collect(Collectors.toList()); + Collection existingPacks = optionset.valuesOf(existing).stream().map(Paths::get).collect(Collectors.toList()); ++ java.util.Set existingMods = new java.util.HashSet<>(optionset.valuesOf(existingMod)); + java.util.Set mods = new java.util.HashSet<>(optionset.valuesOf(mod)); + boolean isFlat = mods.isEmpty() || optionset.has(flat); -+ net.minecraftforge.fml.DatagenModLoader.begin(mods, path, inputs, existingPacks, flag2, flag1, flag3, flag4, flag5, isFlat); ++ net.minecraftforge.fml.DatagenModLoader.begin(mods, path, inputs, existingPacks, existingMods, flag2, flag1, flag3, flag4, flag5, isFlat); + if (mods.contains("minecraft") || mods.isEmpty()) + func_200264_a(isFlat ? path : path.resolve("minecraft"), inputs, flag1, flag2, flag3, flag4, flag5).func_200392_c(); } else { diff --git a/src/generated_test/resources/.cache/cache b/src/generated_test/resources/.cache/cache index 229c89f3b..6c41d230a 100644 --- a/src/generated_test/resources/.cache/cache +++ b/src/generated_test/resources/.cache/cache @@ -79,7 +79,7 @@ cf16f861eaf5815238c2278eb48bde0688cb73b7 assets/scaffolding_test/blockstates/sca 66442c8000af9af4ba36109b3c9d09d9ffd57277 data/data_gen_test/advancements/recipes/conditional2.json ed4cbf1a3a2f5d8969f6346fdc9acdbe81d0c919 data/data_gen_test/recipes/conditional.json ca9827bff0a49957e01cf3887ef5131ad8710320 data/data_gen_test/recipes/conditional2.json -40208299608468b044f64317995f9182ec219d90 data/data_gen_test/tags/blocks/test.json +8831e79c8d15b1bc00eb29d354bb22b64d9ddcdd data/data_gen_test/tags/blocks/test.json d65c425e740dc833f29d16606a1171825876be0d data/data_gen_test/tags/blocks/thing/one.json 1f70ed4ddc878bada5e43d3c44a34157806beda8 data/data_gen_test/tags/blocks/thing/three.json 2c648bca262caaa826ddbbde796d35bb2ee5f03a data/data_gen_test/tags/blocks/thing/two.json diff --git a/src/generated_test/resources/data/data_gen_test/tags/blocks/test.json b/src/generated_test/resources/data/data_gen_test/tags/blocks/test.json index 722315de4..96988a868 100644 --- a/src/generated_test/resources/data/data_gen_test/tags/blocks/test.json +++ b/src/generated_test/resources/data/data_gen_test/tags/blocks/test.json @@ -3,6 +3,7 @@ "values": [ "minecraft:diamond_block", "#minecraft:stone_bricks", + "#forge:cobblestone", { "id": "chisel:marble/raw", "required": false diff --git a/src/main/java/net/minecraftforge/client/model/generators/ModelProvider.java b/src/main/java/net/minecraftforge/client/model/generators/ModelProvider.java index 54da7baf0..28cd1743c 100644 --- a/src/main/java/net/minecraftforge/client/model/generators/ModelProvider.java +++ b/src/main/java/net/minecraftforge/client/model/generators/ModelProvider.java @@ -47,7 +47,7 @@ public abstract class ModelProvider> implements IDataP private final ExistingFileHelper delegate; public ExistingFileHelperIncludingGenerated(ExistingFileHelper delegate) { - super(Collections.emptyList(), true); + super(Collections.emptyList(), Collections.emptySet(), true); this.delegate = delegate; } diff --git a/src/main/java/net/minecraftforge/common/data/ExistingFileHelper.java b/src/main/java/net/minecraftforge/common/data/ExistingFileHelper.java index 3d3f82c00..d69028eca 100644 --- a/src/main/java/net/minecraftforge/common/data/ExistingFileHelper.java +++ b/src/main/java/net/minecraftforge/common/data/ExistingFileHelper.java @@ -26,6 +26,8 @@ import java.util.Collection; import com.google.common.annotations.VisibleForTesting; +import java.util.Collections; +import java.util.Set; import net.minecraft.resources.FilePack; import net.minecraft.resources.FolderPack; import net.minecraft.resources.IResource; @@ -35,20 +37,29 @@ import net.minecraft.resources.ResourcePackType; import net.minecraft.resources.SimpleReloadableResourceManager; import net.minecraft.resources.VanillaPack; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.event.lifecycle.GatherDataEvent; +import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; +import net.minecraftforge.fml.packs.ModFileResourcePack; /** * Enables data providers to check if other data files currently exist. The * instance provided in the {@link GatherDataEvent} utilizes the standard - * resources (via {@link VanillaPack}), as well as any extra resource packs - * passed in via the {@code --existing} argument. + * resources (via {@link VanillaPack}), forge's resources, as well as any + * extra resource packs passed in via the {@code --existing} argument, + * or mod resources via the {@code --existing-mod} argument. */ public class ExistingFileHelper { private final SimpleReloadableResourceManager clientResources, serverData; private final boolean enable; + @Deprecated//TODO: Remove in 1.17 public ExistingFileHelper(Collection existingPacks, boolean enable) { + this(existingPacks, Collections.emptySet(), enable); + } + + public ExistingFileHelper(Collection existingPacks, Set existingMods, boolean enable) { this.clientResources = new SimpleReloadableResourceManager(ResourcePackType.CLIENT_RESOURCES); this.serverData = new SimpleReloadableResourceManager(ResourcePackType.SERVER_DATA); this.clientResources.addResourcePack(new VanillaPack("minecraft", "realms")); @@ -58,7 +69,15 @@ public class ExistingFileHelper { IResourcePack pack = file.isDirectory() ? new FolderPack(file) : new FilePack(file); this.clientResources.addResourcePack(pack); this.serverData.addResourcePack(pack); - }; + } + for (String existingMod : existingMods) { + ModFileInfo modFileInfo = ModList.get().getModFileById(existingMod); + if (modFileInfo != null) { + IResourcePack pack = new ModFileResourcePack(modFileInfo.getFile()); + this.clientResources.addResourcePack(pack); + this.serverData.addResourcePack(pack); + } + } this.enable = enable; } diff --git a/src/main/java/net/minecraftforge/fml/DatagenModLoader.java b/src/main/java/net/minecraftforge/fml/DatagenModLoader.java index 6c97ac8e1..348e88607 100644 --- a/src/main/java/net/minecraftforge/fml/DatagenModLoader.java +++ b/src/main/java/net/minecraftforge/fml/DatagenModLoader.java @@ -19,6 +19,7 @@ package net.minecraftforge.fml; +import java.util.Collections; import net.minecraft.util.registry.Bootstrap; import net.minecraftforge.common.data.ExistingFileHelper; import net.minecraftforge.fml.event.lifecycle.GatherDataEvent; @@ -39,14 +40,23 @@ public class DatagenModLoader { return runningDataGen; } - public static void begin(final Set mods, final Path path, final java.util.Collection inputs, Collection existingPacks, final boolean serverGenerators, final boolean clientGenerators, final boolean devToolGenerators, final boolean reportsGenerator, final boolean structureValidator, final boolean flat) { + @Deprecated //TODO: Remove in 1.17 + public static void begin(final Set mods, final Path path, final Collection inputs, Collection existingPacks, final boolean serverGenerators, final boolean clientGenerators, final boolean devToolGenerators, final boolean reportsGenerator, final boolean structureValidator, final boolean flat) { + begin(mods, path, inputs, existingPacks, Collections.emptySet(), serverGenerators, clientGenerators, devToolGenerators, reportsGenerator, structureValidator, flat); + } + + public static void begin(final Set mods, final Path path, final Collection inputs, Collection existingPacks, Set existingMods, final boolean serverGenerators, final boolean clientGenerators, final boolean devToolGenerators, final boolean reportsGenerator, final boolean structureValidator, final boolean flat) { if (mods.contains("minecraft") && mods.size() == 1) return; LOGGER.info("Initializing Data Gatherer for mods {}", mods); runningDataGen = true; Bootstrap.register(); dataGeneratorConfig = new GatherDataEvent.DataGeneratorConfig(mods, path, inputs, serverGenerators, clientGenerators, devToolGenerators, reportsGenerator, structureValidator, flat); - existingFileHelper = new ExistingFileHelper(existingPacks, structureValidator); ModLoader.get().gatherAndInitializeMods(ModWorkManager.syncExecutor(), ModWorkManager.parallelExecutor(), ()->{}); + if (!mods.contains("forge")) { + //If we aren't generating data for forge, automatically add forge as an existing so mods can access forge's data + existingMods.add("forge"); + } + existingFileHelper = new ExistingFileHelper(existingPacks, existingMods, structureValidator); ModLoader.get().runEventGenerator(mc->new GatherDataEvent(mc, dataGeneratorConfig.makeGenerator(p->dataGeneratorConfig.isFlat() ? p : p.resolve(mc.getModId()), dataGeneratorConfig.getMods().contains(mc.getModId())), dataGeneratorConfig, existingFileHelper)); dataGeneratorConfig.runAll(); } diff --git a/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java b/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java index 01b34b724..bcc5ce7df 100644 --- a/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java +++ b/src/test/java/net/minecraftforge/debug/DataGeneratorTest.java @@ -214,6 +214,7 @@ public class DataGeneratorTest getOrCreateBuilder(BlockTags.makeWrapperTag(new ResourceLocation(MODID, "test").toString())) .addItemEntry(Blocks.DIAMOND_BLOCK) .addTag(BlockTags.STONE_BRICKS) + .addTag(net.minecraftforge.common.Tags.Blocks.COBBLESTONE) .addOptional(new ResourceLocation("chisel", "marble/raw")) .addOptionalTag(new ResourceLocation("forge", "storage_blocks/ruby"));