diff --git a/patches/server/0287-PaperPR-Fix-exact-choice-recipe-book-clicks.patch b/patches/server/0287-PaperPR-Fix-exact-choice-recipe-book-clicks.patch new file mode 100644 index 000000000..c7b90fd16 --- /dev/null +++ b/patches/server/0287-PaperPR-Fix-exact-choice-recipe-book-clicks.patch @@ -0,0 +1,129 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 14 May 2022 15:42:34 -0700 +Subject: [PATCH] PaperPR Fix exact choice recipe book clicks + + +diff --git a/src/main/java/net/minecraft/world/entity/player/StackedContents.java b/src/main/java/net/minecraft/world/entity/player/StackedContents.java +index efee1a8e0e3ad566cd550e51d3e559c5a495889a..0331830815f14779e578e3fe94c400e4ab55c6a0 100644 +--- a/src/main/java/net/minecraft/world/entity/player/StackedContents.java ++++ b/src/main/java/net/minecraft/world/entity/player/StackedContents.java +@@ -37,8 +37,62 @@ public class StackedContents { + int i = getStackingIndex(stack); + int j = Math.min(maxCount, stack.getCount()); + this.put(i, j); ++ // PaperPR start ++ if (stack.hasTag()) { ++ this.put(getExactStackingIndex(stack), j); ++ } ++ } ++ ++ } ++ private static final net.minecraft.core.IdMap EXACT_MATCHES_ID_MAP = new net.minecraft.core.IdMap<>() { ++ private final java.util.concurrent.atomic.AtomicInteger idCounter = new java.util.concurrent.atomic.AtomicInteger(Registry.ITEM.size()); ++ private final it.unimi.dsi.fastutil.objects.Object2IntMap itemstackToId = new it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap<>(new it.unimi.dsi.fastutil.Hash.Strategy<>() { ++ @Override ++ public int hashCode(ItemStack o) { ++ return java.util.Objects.hash(o.getItem(), o.getTag()); ++ } ++ ++ @Override ++ public boolean equals(@Nullable ItemStack a, @Nullable ItemStack b) { ++ if (a == null || b == null) { ++ return false; ++ } ++ return ItemStack.tagMatches(a, b); ++ } ++ }); ++ private final it.unimi.dsi.fastutil.ints.Int2ObjectMap idToItemstack = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); ++ ++ @Override ++ public int getId(ItemStack value) { ++ if (!this.itemstackToId.containsKey(value)) { ++ final int id = this.idCounter.incrementAndGet(); ++ final ItemStack copy = value.copy(); ++ this.itemstackToId.put(copy, id); ++ this.idToItemstack.put(id, copy); ++ return id; ++ } ++ return this.itemstackToId.getInt(value); ++ } ++ ++ @Override ++ public @Nullable ItemStack byId(int index) { ++ return this.idToItemstack.get(index); ++ } ++ ++ @Override ++ public int size() { ++ return this.itemstackToId.size(); ++ } ++ ++ @Override ++ public java.util.Iterator iterator() { ++ return this.idToItemstack.values().iterator(); + } ++ }; + ++ public static int getExactStackingIndex(ItemStack stack) { ++ return EXACT_MATCHES_ID_MAP.getId(stack); ++ // PaperPR end + } + + public static int getStackingIndex(ItemStack stack) { +@@ -80,6 +134,12 @@ public class StackedContents { + } + + public static ItemStack fromStackingIndex(int itemId) { ++ // PaperPR start ++ if (itemId > Registry.ITEM.size()) { ++ final ItemStack stack = EXACT_MATCHES_ID_MAP.byId(itemId); ++ return stack == null ? ItemStack.EMPTY : stack.copy(); ++ } ++ // PaperPR end + return itemId == 0 ? ItemStack.EMPTY : new ItemStack(Item.byId(itemId)); + } + +diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java +index 4ec80c52cbee9b484e47a93551df4dbf62f6d83e..5c84b0f8478d20dc3c1593118addeabea28c8e73 100644 +--- a/src/main/java/net/minecraft/world/item/ItemStack.java ++++ b/src/main/java/net/minecraft/world/item/ItemStack.java +@@ -105,6 +105,7 @@ import org.bukkit.event.world.StructureGrowEvent; + + public final class ItemStack { + ++ public boolean isExactRecipeIngredient = false; // PaperPR + public static final Codec CODEC = RecordCodecBuilder.create((instance) -> { + return instance.group(Registry.ITEM.byNameCodec().fieldOf("id").forGetter((itemstack) -> { + return itemstack.item; +diff --git a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java +index 4f7e02c8a99ec9012a09baac52717df7504a5049..809c6531d056cc9538e9bec9cdc5ca6e4c9f4792 100644 +--- a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java ++++ b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java +@@ -55,7 +55,11 @@ public final class Ingredient implements Predicate { + if (this.itemStacks == null) { + this.itemStacks = (ItemStack[]) Arrays.stream(this.values).flatMap((recipeitemstack_provider) -> { + return recipeitemstack_provider.getItems().stream(); +- }).distinct().toArray((i) -> { ++ // PaperPR start ++ }).distinct().peek(stack -> { ++ stack.isExactRecipeIngredient = this.exact; ++ }).toArray((i) -> { ++ // PaperPR end + return new ItemStack[i]; + }); + } +@@ -111,7 +115,13 @@ public final class Ingredient implements Predicate { + for (int j = 0; j < i; ++j) { + ItemStack itemstack = aitemstack[j]; + ++ // PaperPR start ++ if (itemstack.isExactRecipeIngredient) { ++ this.stackingIds.add(StackedContents.getExactStackingIndex(itemstack)); ++ } else { ++ // PaperPR end + this.stackingIds.add(StackedContents.getStackingIndex(itemstack)); ++ } // PaperPR + } + + this.stackingIds.sort(IntComparators.NATURAL_COMPARATOR);