From 12d0f96fc225a7b30ee318051b8afd1d4bd3ed24 Mon Sep 17 00:00:00 2001 From: Commoble Date: Wed, 18 Aug 2021 15:49:29 -0500 Subject: [PATCH] Add support for forge's "remove" list to tag datagenerators (#7911) --- build.gradle | 1 + .../net/minecraft/tags/Tag.java.patch | 18 +++- src/generated_test/resources/.cache/cache | 3 +- .../data/minecraft/tags/blocks/test_tag.json | 15 ++++ .../extensions/IForgeRawTagBuilder.java | 86 +++++++++++++++++++ .../common/extensions/IForgeTagAppender.java | 82 +++++++++++++++++- .../resources/META-INF/accesstransformer.cfg | 2 + .../debug/RemoveTagDatagenTest.java | 67 +++++++++++++++ src/test/resources/META-INF/mods.toml | 4 +- 9 files changed, 272 insertions(+), 6 deletions(-) create mode 100644 src/generated_test/resources/data/minecraft/tags/blocks/test_tag.json create mode 100644 src/main/java/net/minecraftforge/common/extensions/IForgeRawTagBuilder.java create mode 100644 src/test/java/net/minecraftforge/debug/RemoveTagDatagenTest.java diff --git a/build.gradle b/build.gradle index deba6e80de..c53d98da79 100644 --- a/build.gradle +++ b/build.gradle @@ -930,6 +930,7 @@ project(':forge') { '--mod', 'scaffolding_test', '--mod', 'custom_tag_types_test', '--mod', 'new_model_loader_test', + '--mod', 'remove_tag_datagen_test', '--output', rootProject.file('src/generated_test/resources/'), '--existing', sourceSets.main.resources.srcDirs[0], '--existing', sourceSets.test.resources.srcDirs[0] diff --git a/patches/minecraft/net/minecraft/tags/Tag.java.patch b/patches/minecraft/net/minecraft/tags/Tag.java.patch index 92710b5ca0..50e2cc3d9b 100644 --- a/patches/minecraft/net/minecraft/tags/Tag.java.patch +++ b/patches/minecraft/net/minecraft/tags/Tag.java.patch @@ -1,8 +1,18 @@ --- a/net/minecraft/tags/Tag.java +++ b/net/minecraft/tags/Tag.java -@@ -49,6 +_,7 @@ +@@ -47,8 +_,16 @@ + return SetTag.m_13222_(p_13301_); + } - public static class Builder { +- public static class Builder { ++ public static class Builder implements net.minecraftforge.common.extensions.IForgeRawTagBuilder { ++ private final List removeEntries = Lists.newArrayList(); // FORGE: internal field for tracking "remove" entries ++ /** FORGE: Gets a view of this builder's "remove" entries (only used during datagen) **/ ++ public Stream getRemoveEntries() { return this.removeEntries.stream(); } ++ public Tag.Builder remove(final Tag.BuilderEntry proxy) { // internal forge method for adding remove entries ++ this.removeEntries.add(proxy); ++ return this; ++ } private final List f_13302_ = Lists.newArrayList(); + private boolean replace = false; @@ -32,15 +42,17 @@ list.forEach((p_13319_) -> { this.f_13302_.add(new Tag.BuilderEntry(p_13319_, p_13314_)); }); -@@ -155,7 +_,7 @@ +@@ -155,8 +_,9 @@ tag$builderentry.m_13347_().m_6383_(jsonarray); } - jsonobject.addProperty("replace", false); + jsonobject.addProperty("replace", replace); jsonobject.add("values", jsonarray); ++ this.serializeTagAdditions(jsonobject); return jsonobject; } + } @@ -211,6 +_,7 @@ public String toString() { return this.f_13349_.toString(); diff --git a/src/generated_test/resources/.cache/cache b/src/generated_test/resources/.cache/cache index a1cd4eb2bc..f09fa3f64a 100644 --- a/src/generated_test/resources/.cache/cache +++ b/src/generated_test/resources/.cache/cache @@ -74,10 +74,10 @@ bab7cd04569c8aa63320772acdc3c91a5ceda14a assets/new_model_loader_test/models/blo d2c8e860521c5e738ed0798337f5728d610825ff assets/piston_event_test/models/block/shiftonmove.json f51f026a75e27a0a53a76771d553c0e3385a2966 assets/piston_event_test/models/item/shiftonmove.json cf16f861eaf5815238c2278eb48bde0688cb73b7 assets/scaffolding_test/blockstates/scaffolding_method_test.json +9405b72d54aad3f4377035d9707bb9947e9032a3 data/custom_tag_types_test/tags/block_entity_types/storage.json 862196702dcd5538c5ceb4ac6202e57eb5c8a97f data/custom_tag_types_test/tags/custom_tag_types_test/custom_types/tests.json 8c1969250406edfbd470cc06aca4dcccfd6ce682 data/custom_tag_types_test/tags/enchantments/fire.json 44985f1cb0df54b632187ed97a6a443455f1e51c data/custom_tag_types_test/tags/potions/damage.json -9405b72d54aad3f4377035d9707bb9947e9032a3 data/custom_tag_types_test/tags/tile_entity_types/storage.json 806659ba3e9c12797df0fe7211a222795834fdfd data/data_gen_test/advancements/conditional.json 76e760c8e8a1bbd3fb5538bc2d773c117016c0ce data/data_gen_test/advancements/recipes/conditional2.json ed4cbf1a3a2f5d8969f6346fdc9acdbe81d0c919 data/data_gen_test/recipes/conditional.json @@ -91,3 +91,4 @@ f4d3a59005dafa334c835e43ed0047487e17324d data/forge/loot_modifiers/global_loot_m 5bd8a05038d2633f89b3b1c5ac319eb4b347b335 data/global_loot_test/loot_modifiers/dungeon_loot.json f65e40b06ce7ad18e053ec88058b951f98ae5f40 data/global_loot_test/loot_modifiers/smelting.json a263b2535439eb5af22cbc9aa48252d8e983eb08 data/global_loot_test/loot_modifiers/wheat_harvest.json +f10f0cf9694892eccfddfa67e0ef4aa1f24fb6db data/minecraft/tags/blocks/test_tag.json diff --git a/src/generated_test/resources/data/minecraft/tags/blocks/test_tag.json b/src/generated_test/resources/data/minecraft/tags/blocks/test_tag.json new file mode 100644 index 0000000000..ed67f1118a --- /dev/null +++ b/src/generated_test/resources/data/minecraft/tags/blocks/test_tag.json @@ -0,0 +1,15 @@ +{ + "replace": false, + "values": [], + "remove": [ + "minecraft:dirt", + "minecraft:oak_door", + "minecraft:dark_oak_door", + "minecraft:anvil", + "minecraft:basalt", + "minecraft:polished_basalt", + "#minecraft:beehives", + "#minecraft:banners", + "#minecraft:beds" + ] +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeRawTagBuilder.java b/src/main/java/net/minecraftforge/common/extensions/IForgeRawTagBuilder.java new file mode 100644 index 0000000000..5f06b6c208 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeRawTagBuilder.java @@ -0,0 +1,86 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2021. + * + * 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.common.extensions; + +import java.util.stream.Stream; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.Tag; + +public interface IForgeRawTagBuilder +{ + default Tag.Builder getRawBuilder() + { + return (Tag.Builder)this; + } + + /** + * internal, called when a raw builder is written to json to add forge additions (e.g. the remove list) + */ + default void serializeTagAdditions(final JsonObject tagJson) + { + Tag.Builder rawBuilder = this.getRawBuilder(); + Stream removeEntries = rawBuilder.getRemoveEntries(); + JsonArray removeEntriesAsJsonArray = new JsonArray(); + removeEntries.forEach(proxy ->proxy.getEntry().serializeTo(removeEntriesAsJsonArray)); + if (removeEntriesAsJsonArray.size() > 0) + { + tagJson.add("remove", removeEntriesAsJsonArray); + } + + } + + /** + * Adds a tag entry to the remove list. + * @param entry The tag entry to add to the remove list + * @param source The source of the caller for logging purposes (generally a modid) + * @return The builder for chaining purposes + */ + default Tag.Builder remove(final Tag.Entry tagEntry, final String source) + { + return this.getRawBuilder().remove(new Tag.BuilderEntry(tagEntry,source)); + } + + /** + * Adds a single-element entry to the remove list. + * @param elementID The ID of the element to add to the remove list + * @param source The source of the caller for logging purposes (generally a modid) + * @return The builder for chaining purposes + */ + default Tag.Builder removeElement(final ResourceLocation elementID, final String source) + { + return this.remove(new Tag.ElementEntry(elementID), source); + } + + + /** + * Adds a tag to the remove list. + * @param tagID The ID of the tag to add to the remove list + * @param source The source of the caller for logging purposes (generally a modid) + * @return The builder for chaining purposes + */ + default Tag.Builder removeTag(final ResourceLocation tagID, final String source) + { + return this.remove(new Tag.TagEntry(tagID), source); + } +} diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeTagAppender.java b/src/main/java/net/minecraftforge/common/extensions/IForgeTagAppender.java index ca7ddd74ff..0df21314ca 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeTagAppender.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeTagAppender.java @@ -24,7 +24,6 @@ import net.minecraft.tags.Tag; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -//TODO, Tag removal support. public interface IForgeTagAppender { private TagsProvider.TagAppender self() { @@ -66,4 +65,85 @@ public interface IForgeTagAppender { return self().add(new Tag.OptionalTagEntry(location)); } + + /** + * Adds a registry entry to the tag json's remove list. Callable during datageneration. + * @param element The entry to remove + * @return The builder for chaining + */ + default TagsProvider.TagAppender remove(final T entry) + { + return remove(this.self().registry.getKey(entry)); + } + + /** + * Adds multiple registry entries to the tag json's remove list. Callable during datageneration. + * @param entries The entries to remove + * @return The builder for chaining + */ + @SuppressWarnings("unchecked") + default TagsProvider.TagAppender remove(final T first, final T...entries) + { + this.remove(first); + for (T entry : entries) + { + this.remove(entry); + } + return self(); + } + + /** + * Adds a single element's ID to the tag json's remove list. Callable during datageneration. + * @param location The ID of the element to remove + * @return The builder for chaining + */ + default TagsProvider.TagAppender remove(final ResourceLocation location) + { + TagsProvider.TagAppender builder = self(); + builder.getInternalBuilder().removeElement(location, builder.getModID()); + return builder; + } + + /** + * Adds multiple elements' IDs to the tag json's remove list. Callable during datageneration. + * @param locations The IDs of the elements to remove + * @return The builder for chaining + */ + default TagsProvider.TagAppender remove(final ResourceLocation first, final ResourceLocation... locations) + { + this.remove(first); + for (ResourceLocation location : locations) + { + this.remove(location); + } + return self(); + } + + /** + * Adds a tag to the tag json's remove list. Callable during datageneration. + * @param tag The ID of the tag to remove + * @return The builder for chaining + */ + default TagsProvider.TagAppender remove(Tag.Named tag) + { + TagsProvider.TagAppender builder = self(); + builder.getInternalBuilder().removeTag(tag.getName(), builder.getModID()); + return builder; + } + + /** + * Adds multiple tags to the tag json's remove list. Callable during datageneration. + * @param tags The IDs of the tags to remove + * @return The builder for chaining + */ + @SuppressWarnings("unchecked") + default TagsProvider.TagAppender remove(Tag.Named first, Tag.Named...tags) + { + this.remove(first); + for (Tag.Named tag : tags) + { + this.remove(tag); + } + return self(); + } } diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 68e2174682..16b067c419 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -187,6 +187,7 @@ protected net.minecraft.data.recipes.RecipeProvider m_126013_(Lnet/minecraft/dat protected net.minecraft.data.recipes.RecipeProvider m_176531_(Ljava/util/function/Consumer;)V # buildCraftingRecipes public net.minecraft.data.recipes.ShapedRecipeBuilder$Result protected net.minecraft.data.tags.TagsProvider f_126543_ # builders +public net.minecraft.data.tags.TagsProvider$TagAppender f_126569_ # registry public net.minecraft.data.worldgen.Features$Decorators public net.minecraft.network.protocol.status.ClientboundStatusResponsePacket f_134885_ # GSON public net.minecraft.resources.RegistryReadOps f_179860_ # registryAccess @@ -200,6 +201,7 @@ public net.minecraft.server.level.ServerPlayer m_143399_(Lnet/minecraft/world/in public net.minecraft.server.level.ServerPlayer m_9217_()V # nextContainerCounter public net.minecraft.server.packs.AbstractPackResources f_10203_ # file public net.minecraft.server.packs.resources.FallbackResourceManager f_10599_ # fallbacks +public net.minecraft.tags.Tag$BuilderEntry (Lnet/minecraft/tags/Tag$Entry;Ljava/lang/String;)V # constructor public net.minecraft.tags.BlockTags m_13116_(Ljava/lang/String;)Lnet/minecraft/tags/Tag$Named; # bind public net.minecraft.tags.EntityTypeTags m_13127_(Ljava/lang/String;)Lnet/minecraft/tags/Tag$Named; # bind public net.minecraft.tags.FluidTags m_13134_(Ljava/lang/String;)Lnet/minecraft/tags/Tag$Named; # bind diff --git a/src/test/java/net/minecraftforge/debug/RemoveTagDatagenTest.java b/src/test/java/net/minecraftforge/debug/RemoveTagDatagenTest.java new file mode 100644 index 0000000000..7910a69714 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/RemoveTagDatagenTest.java @@ -0,0 +1,67 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2021. + * + * 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.debug; + +import net.minecraft.data.DataGenerator; +import net.minecraft.data.tags.BlockTagsProvider; +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.Tag; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.forge.event.lifecycle.GatherDataEvent; + +@Mod(RemoveTagDatagenTest.MODID) +public class RemoveTagDatagenTest +{ + public static final String MODID = "remove_tag_datagen_test"; + public static final Tag.Named TEST_TAG = BlockTags.bind("test_tag"); + + public RemoveTagDatagenTest() + { + IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus(); + modBus.addListener(this::onGatherData); + } + + private void onGatherData(GatherDataEvent event) + { + DataGenerator generator = event.getGenerator(); + ExistingFileHelper helper = event.getExistingFileHelper(); + + generator.addProvider(new BlockTagsProvider(generator, MODID, helper) + { + @SuppressWarnings("unchecked") + @Override + protected void addTags() + { + this.tag(TEST_TAG) + .remove(Blocks.DIRT.getRegistryName()) + .remove(Blocks.OAK_DOOR.getRegistryName(), Blocks.DARK_OAK_DOOR.getRegistryName()) + .remove(Blocks.ANVIL) + .remove(Blocks.BASALT, Blocks.POLISHED_BASALT) + .remove(BlockTags.BEEHIVES) + .remove(BlockTags.BANNERS, BlockTags.BEDS); + } + }); + } +} diff --git a/src/test/resources/META-INF/mods.toml b/src/test/resources/META-INF/mods.toml index 4ca74069c9..9e7c2523d5 100644 --- a/src/test/resources/META-INF/mods.toml +++ b/src/test/resources/META-INF/mods.toml @@ -142,9 +142,11 @@ license="LGPL v2.1" modId="entity_renderer_events_test" [[mods]] modId="send_datapacks_to_client" +[[mods]] + modId="remove_tag_datagen_test" [[mods]] modId="tag_based_tool_types" -[[mods]] +[[mods]] modId="check_spawn_event_test" # ADD ABOVE THIS LINE