From ffca39bcca649dbd652e70a0b5d2e9ef3021f168 Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 9 Nov 2024 14:35:44 +0200 Subject: [PATCH 1/3] Add registry context to `LootTableLoadEvent` See #1625 --- .../ReloadableServerRegistries.java.patch | 2 +- .../neoforged/neoforge/event/EventHooks.java | 6 ++-- .../neoforge/event/LootTableLoadEvent.java | 29 +++++++++++++++++-- .../resources/META-INF/accesstransformer.cfg | 1 + .../neoforge/debug/loot/LootPoolTest.java | 6 ++-- 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch index ff31d3b5cf..fd59dfd417 100644 --- a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch +++ b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch @@ -11,7 +11,7 @@ + optionalMap.forEach((rl, optionalEntry) -> { + optionalEntry.ifPresent(entry -> p_335741_.idSetter().accept(entry, rl)); + T value = optionalEntry.orElse(p_335741_.defaultValue()); -+ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(rl, lootTable); ++ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(rl, lootTable, (HolderLookup.Provider) p_336173_.lookupProvider); + if (value != null) + map.put(rl, value); + }); diff --git a/src/main/java/net/neoforged/neoforge/event/EventHooks.java b/src/main/java/net/neoforged/neoforge/event/EventHooks.java index c5109000f3..1c71958c91 100644 --- a/src/main/java/net/neoforged/neoforge/event/EventHooks.java +++ b/src/main/java/net/neoforged/neoforge/event/EventHooks.java @@ -26,6 +26,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup.RegistryLookup; import net.minecraft.core.NonNullList; import net.minecraft.core.RegistryAccess; @@ -688,10 +689,11 @@ public static boolean onProjectileImpact(Projectile projectile, HitResult ray) { * which maps to an empty {@link Optional} in {@link LootDataType#deserialize(ResourceLocation, DynamicOps, Object)} */ @Nullable - public static LootTable loadLootTable(ResourceLocation name, LootTable table) { + @ApiStatus.Internal + public static LootTable loadLootTable(ResourceLocation name, LootTable table, HolderLookup.Provider registries) { if (table == LootTable.EMPTY) // Empty table has a null name, and shouldn't be modified anyway. return null; - LootTableLoadEvent event = new LootTableLoadEvent(name, table); + LootTableLoadEvent event = new LootTableLoadEvent(registries, name, table); if (NeoForge.EVENT_BUS.post(event).isCanceled() || event.getTable() == LootTable.EMPTY) return null; return event.getTable(); diff --git a/src/main/java/net/neoforged/neoforge/event/LootTableLoadEvent.java b/src/main/java/net/neoforged/neoforge/event/LootTableLoadEvent.java index 6c1cff856a..e09f4b9d0c 100644 --- a/src/main/java/net/neoforged/neoforge/event/LootTableLoadEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/LootTableLoadEvent.java @@ -6,12 +6,17 @@ package net.neoforged.neoforge.event; import java.util.Objects; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.storage.loot.LootTable; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.fml.LogicalSide; import net.neoforged.neoforge.common.NeoForge; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; /** * Fired when a {@link LootTable} is loaded from JSON. @@ -26,16 +31,36 @@ * only on the {@linkplain LogicalSide#SERVER logical server}.

*/ public class LootTableLoadEvent extends Event implements ICancellableEvent { + private final HolderLookup.Provider registries; private final ResourceLocation name; private LootTable table; - public LootTableLoadEvent(ResourceLocation name, LootTable table) { + @Nullable + private ResourceKey key; + + @ApiStatus.Internal + public LootTableLoadEvent(HolderLookup.Provider registries, ResourceLocation name, LootTable table) { + this.registries = registries; this.name = name; this.table = table; } + /** + * {@return a lookup provider that can be used to access registries} + */ + public HolderLookup.Provider getRegistries() { + return registries; + } + public ResourceLocation getName() { - return this.name; + return name; + } + + public ResourceKey getKey() { + if (this.key == null) { + this.key = ResourceKey.create(Registries.LOOT_TABLE, name); + } + return this.key; } public LootTable getTable() { diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index a9634170b7..67400f327c 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -158,6 +158,7 @@ public net.minecraft.gametest.framework.GameTestHelper testInfo # testInfo public net.minecraft.gametest.framework.GameTestInfo sequences # sequences public net.minecraft.gametest.framework.GameTestSequence (Lnet/minecraft/gametest/framework/GameTestInfo;)V # protected net.minecraft.resources.RegistryOps (Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/resources/RegistryOps$RegistryInfoLookup;)V # constructor +public net.minecraft.resources.RegistryOps lookupProvider public net.minecraft.resources.ResourceLocation validNamespaceChar(C)Z # validNamespaceChar protected net.minecraft.server.MinecraftServer nextTickTimeNanos # nextTickTimeNanos public net.minecraft.server.MinecraftServer$ReloadableResources diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java b/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java index fce7b70d4a..10773f8c91 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java @@ -92,7 +92,7 @@ static void pinkConcreteLootTableCanceled(final DynamicTest test, final Registra event.getLookupProvider())); NeoForge.EVENT_BUS.addListener((final LootTableLoadEvent event) -> { - if (event.getName().equals(lootTableToUse.location())) { + if (event.getKey() == lootTableToUse) { event.setCanceled(true); } }); @@ -131,7 +131,7 @@ static void orangeConcreteLootTableReplaced(final DynamicTest test, final Regist event.getLookupProvider())); NeoForge.EVENT_BUS.addListener((final LootTableLoadEvent event) -> { - if (event.getName().equals(lootTableToUse.location())) { + if (event.getKey() == lootTableToUse) { LootPoolSingletonContainer.Builder entry = LootItem.lootTableItem(Items.BLUE_CONCRETE); LootPool.Builder pool = LootPool.lootPool().setRolls(ConstantValue.exactly(1)).add(entry).when(ExplosionCondition.survivesExplosion()); event.setTable(new LootTable.Builder().withPool(pool).build()); @@ -172,7 +172,7 @@ static void yellowConcreteLootTableAppended(final DynamicTest test, final Regist event.getLookupProvider())); NeoForge.EVENT_BUS.addListener((final LootTableLoadEvent event) -> { - if (event.getName().equals(lootTableToUse.location())) { + if (event.getKey() == lootTableToUse) { LootPoolSingletonContainer.Builder entry = LootItem.lootTableItem(Items.YELLOW_CONCRETE); LootPool.Builder pool = LootPool.lootPool().setRolls(ConstantValue.exactly(1)).add(entry).when(ExplosionCondition.survivesExplosion()); event.getTable().addPool(pool.build()); From 8618c046e03de7468d6611bfbf829f30a6182ebd Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 9 Nov 2024 15:23:38 +0200 Subject: [PATCH 2/3] Expose HLA and extract correctly --- .../server/ReloadableServerRegistries.java.patch | 7 +++++-- .../net/neoforged/neoforge/common/CommonHooks.java | 13 +++++++++++++ src/main/resources/META-INF/accesstransformer.cfg | 2 ++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch index fd59dfd417..8b362eb690 100644 --- a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch +++ b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch @@ -1,7 +1,10 @@ --- a/net/minecraft/server/ReloadableServerRegistries.java +++ b/net/minecraft/server/ReloadableServerRegistries.java -@@ -61,8 +_,16 @@ +@@ -59,10 +_,19 @@ + ) { + return CompletableFuture.supplyAsync( () -> { ++ var provider = net.neoforged.neoforge.common.CommonHooks.extractLookupProvider(p_336173_); WritableRegistry writableregistry = new MappedRegistry<>(p_335741_.registryKey(), Lifecycle.experimental()); Map map = new HashMap<>(); + Map> optionalMap = new HashMap<>(); @@ -11,7 +14,7 @@ + optionalMap.forEach((rl, optionalEntry) -> { + optionalEntry.ifPresent(entry -> p_335741_.idSetter().accept(entry, rl)); + T value = optionalEntry.orElse(p_335741_.defaultValue()); -+ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(rl, lootTable, (HolderLookup.Provider) p_336173_.lookupProvider); ++ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(rl, lootTable, provider); + if (value != null) + map.put(rl, value); + }); diff --git a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java index d81c78914c..a25ecbbe6b 100644 --- a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java @@ -65,6 +65,7 @@ import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; import net.minecraft.network.syncher.EntityDataSerializer; +import net.minecraft.resources.RegistryOps; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; @@ -1524,6 +1525,18 @@ public static RegistryLookup resolveLookup(ResourceKey ops) { + if (ops.lookupProvider instanceof RegistryOps.HolderLookupAdapter hla) { + return hla.lookupProvider; + } + throw new IllegalArgumentException("Registry ops has lookup provider " + ops.lookupProvider + " which is not a HolderLookupAdapter"); + } + /** * Creates a {@link UseOnContext} for {@link net.minecraft.core.dispenser.DispenseItemBehavior dispense behavior}. * diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 67400f327c..38bf188b44 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -159,6 +159,8 @@ public net.minecraft.gametest.framework.GameTestInfo sequences # sequences public net.minecraft.gametest.framework.GameTestSequence (Lnet/minecraft/gametest/framework/GameTestInfo;)V # protected net.minecraft.resources.RegistryOps (Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/resources/RegistryOps$RegistryInfoLookup;)V # constructor public net.minecraft.resources.RegistryOps lookupProvider +public net.minecraft.resources.RegistryOps$HolderLookupAdapter +public net.minecraft.resources.RegistryOps$HolderLookupAdapter lookupProvider public net.minecraft.resources.ResourceLocation validNamespaceChar(C)Z # validNamespaceChar protected net.minecraft.server.MinecraftServer nextTickTimeNanos # nextTickTimeNanos public net.minecraft.server.MinecraftServer$ReloadableResources From ff4d83fd8949ee62394a4edeeb693bd2a98158a2 Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Wed, 4 Dec 2024 23:28:07 +0200 Subject: [PATCH 3/3] Reimplement patch --- .../minecraft/server/ReloadableServerRegistries.java.patch | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch index 7fb8e44291..6ef1590a62 100644 --- a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch +++ b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch @@ -1,16 +1,17 @@ --- a/net/minecraft/server/ReloadableServerRegistries.java +++ b/net/minecraft/server/ReloadableServerRegistries.java -@@ -61,7 +_,15 @@ +@@ -61,7 +_,16 @@ () -> { WritableRegistry writableregistry = new MappedRegistry<>(p_335741_.registryKey(), Lifecycle.experimental()); Map map = new HashMap<>(); - SimpleJsonResourceReloadListener.scanDirectory(p_335893_, p_335741_.registryKey(), p_336173_, p_335741_.codec(), map); ++ var provider = net.neoforged.neoforge.common.CommonHooks.extractLookupProvider(p_336173_); + Map> optionalMap = new HashMap<>(); + SimpleJsonResourceReloadListener.scanDirectoryWithOptionalValues(p_335893_, p_335741_.registryKey(), p_336173_, p_335741_.conditionalCodec(), optionalMap); + optionalMap.forEach((rl, optionalEntry) -> { + optionalEntry.ifPresent(entry -> p_335741_.idSetter().accept(entry, rl)); + T value = optionalEntry.orElse(p_335741_.defaultValue()); -+ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(rl, lootTable); ++ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(rl, lootTable, provider); + if (value != null) + map.put(rl, value); + });