From 80d2730fecf1a33cee42f02df9c07e305860d044 Mon Sep 17 00:00:00 2001 From: LexManos Date: Mon, 29 Jun 2020 12:42:26 -0700 Subject: [PATCH] Fix tag related issues when connecting to a vanilla server. --- .../play/ClientPlayNetHandler.java.patch | 10 +- .../play/server/STagsListPacket.java.patch | 11 ++ .../tags/NetworkTagManager.java.patch | 23 +++- .../net/minecraft/tags/Tag.java.patch | 15 -- .../minecraft/tags/TagCollection.java.patch | 2 +- .../util/registry/Registry.java.patch | 6 +- .../java/net/minecraftforge/common/Tags.java | 27 +++- .../common/data/ForgeBlockTagsProvider.java | 2 +- .../common/data/ForgeItemTagsProvider.java | 1 + .../common/extensions/IForgeTagBuilder.java | 3 + .../common/util/ForgeNetworkTagManager.java | 128 ++++++++++++++++++ .../resources/META-INF/accesstransformer.cfg | 6 +- src/main/resources/forge.exc | 2 + 13 files changed, 207 insertions(+), 29 deletions(-) create mode 100644 patches/minecraft/net/minecraft/network/play/server/STagsListPacket.java.patch delete mode 100644 patches/minecraft/net/minecraft/tags/Tag.java.patch create mode 100644 src/main/java/net/minecraftforge/common/util/ForgeNetworkTagManager.java diff --git a/patches/minecraft/net/minecraft/client/network/play/ClientPlayNetHandler.java.patch b/patches/minecraft/net/minecraft/client/network/play/ClientPlayNetHandler.java.patch index d95272c61..d95409b48 100644 --- a/patches/minecraft/net/minecraft/client/network/play/ClientPlayNetHandler.java.patch +++ b/patches/minecraft/net/minecraft/client/network/play/ClientPlayNetHandler.java.patch @@ -77,14 +77,14 @@ if (effect != null) { EffectInstance effectinstance = new EffectInstance(effect, p_147260_1_.func_180755_e(), p_147260_1_.func_149428_f(), p_147260_1_.func_186984_g(), p_147260_1_.func_179707_f(), p_147260_1_.func_205527_h()); effectinstance.func_100012_b(p_147260_1_.func_149429_c()); -@@ -1426,6 +1439,7 @@ +@@ -1423,6 +1436,7 @@ + this.field_199725_m = p_199723_1_.func_199858_a(); + if (!this.field_147302_e.func_150731_c()) { + this.field_199725_m.func_232980_f_(); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.TagsUpdatedEvent(this.field_199725_m)); } this.field_147299_f.func_213253_a(SearchTreeManager.field_215360_b).func_194040_a(); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.TagsUpdatedEvent(this.field_199725_m)); - } - - public void func_175098_a(SCombatPacket p_175098_1_) { @@ -1909,10 +1923,12 @@ int l5 = packetbuffer.readInt(); this.field_147299_f.field_184132_p.field_229018_q_.func_229022_a_(blockpos8, l3, s10, l5); diff --git a/patches/minecraft/net/minecraft/network/play/server/STagsListPacket.java.patch b/patches/minecraft/net/minecraft/network/play/server/STagsListPacket.java.patch new file mode 100644 index 000000000..b118057c1 --- /dev/null +++ b/patches/minecraft/net/minecraft/network/play/server/STagsListPacket.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/network/play/server/STagsListPacket.java ++++ b/net/minecraft/network/play/server/STagsListPacket.java +@@ -19,7 +19,7 @@ + } + + public void func_148837_a(PacketBuffer p_148837_1_) throws IOException { +- this.field_199859_a = NetworkTagManager.func_199714_b(p_148837_1_); ++ this.field_199859_a = NetworkTagManager.readSafe(p_148837_1_); + } + + public void func_148840_b(PacketBuffer p_148840_1_) throws IOException { diff --git a/patches/minecraft/net/minecraft/tags/NetworkTagManager.java.patch b/patches/minecraft/net/minecraft/tags/NetworkTagManager.java.patch index 84a80899a..7889d1c1e 100644 --- a/patches/minecraft/net/minecraft/tags/NetworkTagManager.java.patch +++ b/patches/minecraft/net/minecraft/tags/NetworkTagManager.java.patch @@ -1,6 +1,27 @@ --- a/net/minecraft/tags/NetworkTagManager.java +++ b/net/minecraft/tags/NetworkTagManager.java -@@ -86,5 +86,6 @@ +@@ -47,8 +47,19 @@ + this.field_215299_d.func_200042_a(p_199716_1_); + } + ++ /* ++ * Reads a list of Network Tag Collections from the packet, but supports missing/empty tags. ++ * If the tag is missing, it will either return an empty tag when requested, or a tag with default values. ++ */ ++ public static NetworkTagManager readSafe(PacketBuffer buffer) { ++ return read(buffer, net.minecraftforge.common.util.ForgeNetworkTagManager.create()); ++ } ++ + public static NetworkTagManager func_199714_b(PacketBuffer p_199714_0_) { +- NetworkTagManager networktagmanager = new NetworkTagManager(); ++ return read(p_199714_0_, new NetworkTagManager()); ++ } ++ ++ private static NetworkTagManager read(PacketBuffer p_199714_0_, NetworkTagManager networktagmanager) { + networktagmanager.func_199717_a().func_200043_b(p_199714_0_); + networktagmanager.func_199715_b().func_200043_b(p_199714_0_); + networktagmanager.func_205704_c().func_200043_b(p_199714_0_); +@@ -86,5 +97,6 @@ FluidTags.func_206953_a(this.field_205705_c); EntityTypeTags.func_219759_a(this.field_215299_d); Blocks.func_235419_a_(); diff --git a/patches/minecraft/net/minecraft/tags/Tag.java.patch b/patches/minecraft/net/minecraft/tags/Tag.java.patch deleted file mode 100644 index 8d9fc88be..000000000 --- a/patches/minecraft/net/minecraft/tags/Tag.java.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/net/minecraft/tags/Tag.java -+++ b/net/minecraft/tags/Tag.java -@@ -18,10 +18,12 @@ - this.field_241282_b_ = ImmutableList.copyOf(p_i241226_1_); - } - -+ //TODO: empty - public static Tag func_241284_a_() { - return new Tag<>(ImmutableSet.of(), Void.class); - } - -+ //TODO OF - public static Tag func_241286_a_(Set p_241286_0_) { - return new Tag<>(p_241286_0_, func_241287_c_(p_241286_0_)); - } diff --git a/patches/minecraft/net/minecraft/tags/TagCollection.java.patch b/patches/minecraft/net/minecraft/tags/TagCollection.java.patch index 5c262afb4..1e0f13e6d 100644 --- a/patches/minecraft/net/minecraft/tags/TagCollection.java.patch +++ b/patches/minecraft/net/minecraft/tags/TagCollection.java.patch @@ -6,6 +6,6 @@ } + + public Function> getEntryLookup() { -+ return this.field_200040_e; ++ return this.field_200040_e; + } } diff --git a/patches/minecraft/net/minecraft/util/registry/Registry.java.patch b/patches/minecraft/net/minecraft/util/registry/Registry.java.patch index 0283547ed..0ad83a19c 100644 --- a/patches/minecraft/net/minecraft/util/registry/Registry.java.patch +++ b/patches/minecraft/net/minecraft/util/registry/Registry.java.patch @@ -169,7 +169,7 @@ return Activity.field_221366_b; }); public static final Registry field_239693_aY_ = func_239746_a_(field_239695_aa_, () -> { -@@ -407,6 +411,14 @@ +@@ -407,6 +411,18 @@ return ((MutableRegistry)p_218343_0_).func_218382_a(p_218343_1_, RegistryKey.func_240903_a_(p_218343_0_.field_239703_b_, new ResourceLocation(p_218343_2_)), p_218343_3_); } @@ -180,6 +180,10 @@ + private static > DefaultedRegistry forgeDefaulted(RegistryKey> key, Class cls, Supplier def) { + return Registry.func_239743_a_(key, net.minecraftforge.registries.GameData.getWrapperDefaulted(cls), def); + } ++ ++ public final RegistryKey> getRegistryKey() { ++ return field_239703_b_; ++ } + static { field_218376_a.forEach((p_239747_0_, p_239747_1_) -> { diff --git a/src/main/java/net/minecraftforge/common/Tags.java b/src/main/java/net/minecraftforge/common/Tags.java index add5e0bde..0d07f6def 100644 --- a/src/main/java/net/minecraftforge/common/Tags.java +++ b/src/main/java/net/minecraftforge/common/Tags.java @@ -19,11 +19,18 @@ package net.minecraftforge.common; +import java.util.Arrays; +import java.util.stream.Collectors; + import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.tags.BlockTags; import net.minecraft.tags.ITag; import net.minecraft.tags.ItemTags; +import net.minecraft.util.RegistryKey; +import net.minecraft.util.registry.Registry; +import net.minecraftforge.common.util.ForgeNetworkTagManager; +import net.minecraftforge.registries.IForgeRegistryEntry; public class Tags { @@ -37,10 +44,10 @@ public class Tags public static final ITag.INamedTag DIRT = tag("dirt"); public static final ITag.INamedTag END_STONES = tag("end_stones"); public static final ITag.INamedTag FENCE_GATES = tag("fence_gates"); - public static final ITag.INamedTag FENCE_GATES_WOODEN = tag("fence_gates/wooden"); + public static final ITag.INamedTag FENCE_GATES_WOODEN = defaulted("fence_gates/wooden", net.minecraft.block.Blocks.OAK_FENCE_GATE, net.minecraft.block.Blocks.BIRCH_FENCE_GATE, net.minecraft.block.Blocks.SPRUCE_FENCE_GATE, net.minecraft.block.Blocks.JUNGLE_FENCE_GATE, net.minecraft.block.Blocks.DARK_OAK_FENCE_GATE, net.minecraft.block.Blocks.ACACIA_FENCE_GATE); public static final ITag.INamedTag FENCES = tag("fences"); public static final ITag.INamedTag FENCES_NETHER_BRICK = tag("fences/nether_brick"); - public static final ITag.INamedTag FENCES_WOODEN = tag("fences/wooden"); + public static final ITag.INamedTag FENCES_WOODEN = defaulted("fences/wooden", net.minecraft.block.Blocks.OAK_FENCE, net.minecraft.block.Blocks.BIRCH_FENCE, net.minecraft.block.Blocks.SPRUCE_FENCE, net.minecraft.block.Blocks.JUNGLE_FENCE, net.minecraft.block.Blocks.DARK_OAK_FENCE, net.minecraft.block.Blocks.ACACIA_FENCE); public static final ITag.INamedTag GLASS = tag("glass"); public static final ITag.INamedTag GLASS_BLACK = tag("glass/black"); @@ -115,6 +122,12 @@ public class Tags { return BlockTags.makeWrapperTag("forge:" + name); } + + @SuppressWarnings("deprecation") + private static ITag.INamedTag defaulted(String name, Block... values) + { + return ForgeNetworkTagManager.defaulted(Registry.field_239711_l_, tag(name), Arrays.asList(values).stream().map(e -> e.getRegistryName()).collect(Collectors.toSet())); + } } public static class Items @@ -162,10 +175,10 @@ public class Tags public static final ITag.INamedTag ENDER_PEARLS = tag("ender_pearls"); public static final ITag.INamedTag FEATHERS = tag("feathers"); public static final ITag.INamedTag FENCE_GATES = tag("fence_gates"); - public static final ITag.INamedTag FENCE_GATES_WOODEN = tag("fence_gates/wooden"); + public static final ITag.INamedTag FENCE_GATES_WOODEN = defaulted("fence_gates/wooden", Blocks.FENCE_GATES_WOODEN); public static final ITag.INamedTag FENCES = tag("fences"); public static final ITag.INamedTag FENCES_NETHER_BRICK = tag("fences/nether_brick"); - public static final ITag.INamedTag FENCES_WOODEN = tag("fences/wooden"); + public static final ITag.INamedTag FENCES_WOODEN = defaulted("fences/wooden", Blocks.FENCES_WOODEN); public static final ITag.INamedTag GEMS = tag("gems"); public static final ITag.INamedTag GEMS_DIAMOND = tag("gems/diamond"); public static final ITag.INamedTag GEMS_EMERALD = tag("gems/emerald"); @@ -271,5 +284,11 @@ public class Tags { return ItemTags.makeWrapperTag("forge:" + name); } + + @SuppressWarnings("deprecation") + private static ITag.INamedTag defaulted(String name, ITag.INamedTag parent) + { + return ForgeNetworkTagManager.defaulted(Registry.field_239714_o_, tag(name), RegistryKey.func_240903_a_(Registry.field_239711_l_, parent.func_230234_a_())); + } } } diff --git a/src/main/java/net/minecraftforge/common/data/ForgeBlockTagsProvider.java b/src/main/java/net/minecraftforge/common/data/ForgeBlockTagsProvider.java index f30517042..b8718ef92 100644 --- a/src/main/java/net/minecraftforge/common/data/ForgeBlockTagsProvider.java +++ b/src/main/java/net/minecraftforge/common/data/ForgeBlockTagsProvider.java @@ -22,7 +22,6 @@ package net.minecraftforge.common.data; import net.minecraft.data.DataGenerator; import net.minecraft.item.DyeColor; import net.minecraft.tags.ITag; -import net.minecraft.tags.Tag; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.Tags; import net.minecraftforge.registries.ForgeRegistries; @@ -47,6 +46,7 @@ public class ForgeBlockTagsProvider extends BlockTagsProvider super(gen); } + @SuppressWarnings("unchecked") @Override public void registerTags() { diff --git a/src/main/java/net/minecraftforge/common/data/ForgeItemTagsProvider.java b/src/main/java/net/minecraftforge/common/data/ForgeItemTagsProvider.java index f23da7946..b1bed9e13 100644 --- a/src/main/java/net/minecraftforge/common/data/ForgeItemTagsProvider.java +++ b/src/main/java/net/minecraftforge/common/data/ForgeItemTagsProvider.java @@ -47,6 +47,7 @@ public class ForgeItemTagsProvider extends ItemTagsProvider super(gen, blockTagProvider); } + @SuppressWarnings("unchecked") @Override public void registerTags() { diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeTagBuilder.java b/src/main/java/net/minecraftforge/common/extensions/IForgeTagBuilder.java index 170908dbe..2bba2f585 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeTagBuilder.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeTagBuilder.java @@ -35,6 +35,7 @@ public interface IForgeTagBuilder return (TagsProvider.Builder) this; } + @SuppressWarnings("unchecked") default TagsProvider.Builder addTags(ITag.INamedTag... values) { TagsProvider.Builder builder = getBuilder(); for (ITag.INamedTag value : values) { @@ -57,6 +58,7 @@ public interface IForgeTagBuilder return addOptional(Arrays.asList(locations)); } + @SuppressWarnings("deprecation") default TagsProvider.Builder addOptional(final Collection locations) { return getBuilder().add(ForgeHooks.makeOptionalTag(true, locations)); @@ -67,6 +69,7 @@ public interface IForgeTagBuilder return addOptionalTag(Arrays.asList(locations)); } + @SuppressWarnings("deprecation") default TagsProvider.Builder addOptionalTag(final Collection locations) { return getBuilder().add(ForgeHooks.makeOptionalTag(false, locations)); diff --git a/src/main/java/net/minecraftforge/common/util/ForgeNetworkTagManager.java b/src/main/java/net/minecraftforge/common/util/ForgeNetworkTagManager.java new file mode 100644 index 000000000..a26106ce7 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/util/ForgeNetworkTagManager.java @@ -0,0 +1,128 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2020. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.common.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.Nullable; + +import com.google.common.collect.ImmutableSet; + +import net.minecraft.tags.ITag; +import net.minecraft.tags.NetworkTagCollection; +import net.minecraft.tags.NetworkTagManager; +import net.minecraft.tags.Tag; +import net.minecraft.util.RegistryKey; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.registry.Registry; + +@Deprecated //For Forge's internal use only. +public class ForgeNetworkTagManager extends NetworkTagManager +{ + private static Map, Set> defaults = new HashMap<>(); + + /** + * Returns a new instance of this tag manager, again, only exposed for Forge's Hook use. + */ + public static NetworkTagManager create() + { + return new ForgeNetworkTagManager(); + } + + /** + * This will provide default tags if the server side does not send us one. + * Note: If they DO send us a empty one, this DOES NOT override that. + * This is 100% intended to be only used by Forge tto make sure our tags behave correctly on vanilla servers for the edge cases where we use tags for in-game loogic. + * Notably: Furnace burnables. + */ + public static ITag.INamedTag defaulted(RegistryKey> type, ITag.INamedTag tag, Set values) + { + defaults.put(RegistryKey.func_240903_a_(type, tag.func_230234_a_()), ImmutableSet.copyOf(values)); + return tag; + } + + /** + * Copies the resource key from the parent tag to a new one. + * This simplifies the item variants of block tags. + * WILL explode if the parent hasn't been defaulted. + */ + public static ITag.INamedTag defaulted(RegistryKey> type, ITag.INamedTag tag, RegistryKey parent) + { + RegistryKey regKey = RegistryKey.func_240903_a_(type, tag.func_230234_a_()); + Set other = defaults.get(parent); + if (other == null) + throw new IllegalStateException("Attempted to set nested default without setting parent: " + regKey + " -> " + parent); + defaults.put(regKey, other); + return tag; + } + + private ForgeNetworkTagManager() + { + this.blocks = new ForgeNetworkTagCollection<>(Registry.BLOCK, "tags/blocks", "block"); + this.items = new ForgeNetworkTagCollection<>(Registry.ITEM, "tags/items", "item"); + this.fluids = new ForgeNetworkTagCollection<>(Registry.FLUID, "tags/fluids", "fluid"); + this.entityTypes = new ForgeNetworkTagCollection<>(Registry.ENTITY_TYPE, "tags/entity_types", "entity_type"); + } + + private static class ForgeNetworkTagCollection extends NetworkTagCollection + { + private final ITag EMPTY = Tag.func_241284_a_(); + private final Registry registry; + private final Map> cache = new HashMap<>(); + + public ForgeNetworkTagCollection(Registry registry, String path, String name) + { + super(registry, path, name); + this.registry = registry; + } + + @Override + @Nullable + public ITag get(ResourceLocation key) + { + ITag ret = super.get(key); + if (ret == null) + { + ret = cache.get(key); + if (ret == null) { + RegistryKey regKey = RegistryKey.func_240903_a_(this.registry.getRegistryKey(), key); + Set defaults = ForgeNetworkTagManager.defaults.get(regKey); + if (defaults == null) + { + ret = EMPTY; + } + else + { + Set values = defaults.stream().map(getEntryLookup()).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toSet()); + ret = Tag.func_241286_a_(values); + } + this.cache.put(key, ret); + } + } + + return ret; + } + } + +} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 31730d9f0..2796d1c9a 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -178,4 +178,8 @@ public net.minecraft.world.gen.layer.LayerUtil func_202829_a(JLnet/minecraft/wor private-f net.minecraft.world.server.ChunkHolder field_219320_o # block update location public net.minecraft.world.server.ServerChunkProvider field_186029_c # chunkGenerator public net.minecraft.world.server.ServerChunkProvider field_73251_h # worldObj -public net.minecraft.world.storage.FolderName (Ljava/lang/String;)V # constructor \ No newline at end of file +public net.minecraft.world.storage.FolderName (Ljava/lang/String;)V # constructor +protected-f net.minecraft.tags.NetworkTagManager field_215299_d # entityTypes +protected-f net.minecraft.tags.NetworkTagManager field_205705_c # fluids +protected-f net.minecraft.tags.NetworkTagManager field_199720_b # items +protected-f net.minecraft.tags.NetworkTagManager field_199719_a # blocks \ No newline at end of file diff --git a/src/main/resources/forge.exc b/src/main/resources/forge.exc index 0f4bb1525..a4af19e79 100644 --- a/src/main/resources/forge.exc +++ b/src/main/resources/forge.exc @@ -120,3 +120,5 @@ net/minecraft/world/storage/loot/LootEntryEmpty.(II[Lnet/minecraft/world/s net/minecraft/world/storage/loot/LootEntryItem.(Lnet/minecraft/item/Item;II[Lnet/minecraft/world/storage/loot/functions/LootFunction;[Lnet/minecraft/world/storage/loot/conditions/LootCondition;Ljava/lang/String;)V=|p_i46644_1_,p_i46644_2_,p_i46644_3_,p_i46644_4_,p_i46644_5_,entryName net/minecraft/world/storage/loot/LootEntryTable.(Lnet/minecraft/util/ResourceLocation;II[Lnet/minecraft/world/storage/loot/conditions/LootCondition;Ljava/lang/String;)V=|p_i46639_1_,p_i46639_2_,p_i46639_3_,p_i46639_4_,entryName net/minecraft/world/storage/loot/LootPool.([Lnet/minecraft/world/storage/loot/LootEntry;[Lnet/minecraft/world/storage/loot/conditions/LootCondition;Lnet/minecraft/world/storage/loot/RandomValueRange;Lnet/minecraft/world/storage/loot/RandomValueRange;Ljava/lang/String;)V=|p_i46643_1_,p_i46643_2_,p_i46643_3_,p_i46643_4_ + +net/minecraft/tags/NetworkTagManager.read(Lnet/minecraft/network/PacketBuffer;Lnet/minecraft/tags/NetworkTagManager;)Lnet/minecraft/tags/NetworkTagManager;=|p_199714_0_,networktagmanager