SPIGOT-7496: Failure to load datapacks with multiple identical predicates

By: md_5 <git@md-5.net>
This commit is contained in:
CraftBukkit/Spigot 2023-10-02 20:01:30 +11:00
parent 88114a4558
commit 0c3b8eb4b9
3 changed files with 30 additions and 19 deletions

View file

@ -1,14 +1,15 @@
--- a/net/minecraft/world/level/storage/loot/LootDataManager.java
+++ b/net/minecraft/world/level/storage/loot/LootDataManager.java
@@ -30,6 +30,7 @@
public static final LootDataId<LootTable> EMPTY_LOOT_TABLE_KEY = new LootDataId<>(LootDataType.TABLE, LootTables.EMPTY);
private Map<LootDataId<?>, ?> elements = Map.of();
private Multimap<LootDataType<?>, MinecraftKey> typeKeys = ImmutableMultimap.of();
+ public Map<?, MinecraftKey> lootTableToKey = ImmutableMap.of(); // CraftBukkit
@@ -21,6 +21,8 @@
import net.minecraft.server.packs.resources.ResourceDataJson;
import net.minecraft.util.profiling.GameProfilerFiller;
import net.minecraft.world.level.storage.loot.parameters.LootContextParameterSets;
+import org.bukkit.craftbukkit.CraftLootTable;
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.slf4j.Logger;
public LootDataManager() {}
@@ -87,7 +88,7 @@
public class LootDataManager implements IReloadListener, LootDataResolver {
@@ -87,7 +89,7 @@
@Nullable
@Override
public <T> T getElement(LootDataId<T> lootdataid) {
@ -17,15 +18,19 @@
}
});
@@ -99,16 +100,21 @@
@@ -97,18 +99,25 @@
lootcollector.getProblems().forEach((s, s1) -> {
LootDataManager.LOGGER.warn("Found loot table element validation problem in {}: {}", s, s1);
});
+ // CraftBukkit start
+ map1.forEach((key, lootTable) -> {
+ if (object instanceof LootTable table) {
+ table.craftLootTable = new CraftLootTable(CraftNamespacedKey.fromMinecraft(key.location()), table);
+ }
+ });
+ // CraftBukkit end
this.elements = map1;
this.typeKeys = com_google_common_collect_immutablemultimap_builder.build();
+ // CraftBukkit start - build a reversed registry map
+ ImmutableMap.Builder<Object, MinecraftKey> lootTableToKeyBuilder = ImmutableMap.builder();
+ this.elements.forEach((key, lootTable) -> lootTableToKeyBuilder.put((Object) lootTable, key.location()));
+ this.lootTableToKey = lootTableToKeyBuilder.build();
+ // CraftBukkit end
}
private static <T> void castAndValidate(LootCollector lootcollector, LootDataId<T> lootdataid, Object object) {

View file

@ -5,7 +5,7 @@
import org.slf4j.Logger;
+// CraftBukkit start
+import java.util.stream.Collectors;
+import org.bukkit.craftbukkit.CraftLootTable;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.event.world.LootGenerateEvent;
@ -14,7 +14,15 @@
public class LootTable {
private static final Logger LOGGER = LogUtils.getLogger();
@@ -149,9 +156,22 @@
@@ -50,6 +57,7 @@
private final List<LootSelector> pools;
private final List<LootItemFunction> functions;
private final BiFunction<ItemStack, LootTableInfo, ItemStack> compositeFunction;
+ public CraftLootTable craftLootTable; // CraftBukkit
LootTable(LootContextParameterSet lootcontextparameterset, Optional<MinecraftKey> optional, List<LootSelector> list, List<LootItemFunction> list1) {
this.paramSet = lootcontextparameterset;
@@ -149,9 +157,22 @@
}
public void fill(IInventory iinventory, LootParams lootparams, long i) {

View file

@ -1741,11 +1741,9 @@ public class CraftEventFactory {
public static LootGenerateEvent callLootGenerateEvent(IInventory inventory, LootTable lootTable, LootTableInfo lootInfo, List<ItemStack> loot, boolean plugin) {
CraftWorld world = lootInfo.getLevel().getWorld();
Entity entity = lootInfo.getParamOrNull(LootContextParameters.THIS_ENTITY);
NamespacedKey key = CraftNamespacedKey.fromMinecraft(world.getHandle().getServer().getLootData().lootTableToKey.get(lootTable));
CraftLootTable craftLootTable = new CraftLootTable(key, lootTable);
List<org.bukkit.inventory.ItemStack> bukkitLoot = loot.stream().map(CraftItemStack::asCraftMirror).collect(Collectors.toCollection(ArrayList::new));
LootGenerateEvent event = new LootGenerateEvent(world, (entity != null ? entity.getBukkitEntity() : null), inventory.getOwner(), craftLootTable, CraftLootTable.convertContext(lootInfo), bukkitLoot, plugin);
LootGenerateEvent event = new LootGenerateEvent(world, (entity != null ? entity.getBukkitEntity() : null), inventory.getOwner(), lootTable.craftLootTable, CraftLootTable.convertContext(lootInfo), bukkitLoot, plugin);
Bukkit.getPluginManager().callEvent(event);
return event;
}