From 8618c046e03de7468d6611bfbf829f30a6182ebd Mon Sep 17 00:00:00 2001
From: Matyrobbrt <matyrobbrt@gmail.com>
Date: Sat, 9 Nov 2024 15:23:38 +0200
Subject: [PATCH] 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<T> writableregistry = new MappedRegistry<>(p_335741_.registryKey(), Lifecycle.experimental());
                  Map<ResourceLocation, T> map = new HashMap<>();
 +                Map<ResourceLocation, Optional<T>> 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 <T> RegistryLookup<T> resolveLookup(ResourceKey<? extends Registry
         return null;
     }
 
+    /**
+     * Extracts a {@link HolderLookup.Provider} from the given {@code ops}, if possible.
+     *
+     * @throws IllegalArgumentException if the ops were not created using a {@linkplain HolderLookup.Provider}
+     */
+    public static HolderLookup.Provider extractLookupProvider(RegistryOps<?> 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 <init>(Lnet/minecraft/gametest/framework/GameTestInfo;)V # <init>
 protected net.minecraft.resources.RegistryOps <init>(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