3
0
Mirror von https://github.com/PaperMC/Paper.git synchronisiert 2024-11-15 04:20:04 +01:00

re-implement matchesWithoutData

fixes some issues when the current item doesn't have any component on the patch
Dieser Commit ist enthalten in:
Lulu13022002 2024-11-10 20:46:17 +01:00 committet von Owen1212055
Ursprung e0bcc5ee85
Commit 0db52b8606
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 2133292072886A30
2 geänderte Dateien mit 59 neuen und 61 gelöschten Zeilen

Datei anzeigen

@ -4018,7 +4018,7 @@ index b4ef3133fdd9d79a3381cf8f659ff561ab2b4fad..d3c9fb2fd625ed6ae4882c3b16b86f32
* Get the object by its key. * Get the object by its key.
* *
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..aafbf87d21b4d40c3635f7e9323a92ce61fbc45b 100644 index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..8071624df30b36e2f96dcf7a0b2ada20179b1641 100644
--- a/src/main/java/org/bukkit/inventory/ItemStack.java --- a/src/main/java/org/bukkit/inventory/ItemStack.java
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java
@@ -1,10 +1,11 @@ @@ -1,10 +1,11 @@
@ -4187,11 +4187,11 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..aafbf87d21b4d40c3635f7e9323a92ce
+ * This is useful if you are wanting to ignore certain properties of itemstacks, such as durability. + * This is useful if you are wanting to ignore certain properties of itemstacks, such as durability.
+ * + *
+ * @param item the item to compare + * @param item the item to compare
+ * @param exclude the data component types to ignore + * @param excludeTypes the data component types to ignore
+ * @return {@code true} if the provided item is equal, ignoring the provided components + * @return {@code true} if the provided item is equal, ignoring the provided components
+ */ + */
+ public boolean matchesWithoutData(final @NotNull ItemStack item, final @NotNull io.papermc.paper.registry.set.RegistrySet<io.papermc.paper.datacomponent.@NotNull DataComponentType> exclude) { + public boolean matchesWithoutData(final @NotNull ItemStack item, final @NotNull io.papermc.paper.registry.set.RegistrySet<io.papermc.paper.datacomponent.@NotNull DataComponentType> excludeTypes) {
+ return this.matchesWithoutData(item, exclude, false); + return this.matchesWithoutData(item, excludeTypes, false);
+ } + }
+ +
+ /** + /**
@ -4199,12 +4199,12 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..aafbf87d21b4d40c3635f7e9323a92ce
+ * This is useful if you are wanting to ignore certain properties of itemstacks, such as durability. + * This is useful if you are wanting to ignore certain properties of itemstacks, such as durability.
+ * + *
+ * @param item the item to compare + * @param item the item to compare
+ * @param exclude the data component types to ignore + * @param excludeTypes the data component types to ignore
+ * @param ignoreCount ignore the count of the item + * @param ignoreCount ignore the count of the item
+ * @return {@code true} if the provided item is equal, ignoring the provided components + * @return {@code true} if the provided item is equal, ignoring the provided components
+ */ + */
+ public boolean matchesWithoutData(final @NotNull ItemStack item, final @NotNull io.papermc.paper.registry.set.RegistrySet<io.papermc.paper.datacomponent.@NotNull DataComponentType> exclude, final boolean ignoreCount) { + public boolean matchesWithoutData(final @NotNull ItemStack item, final @NotNull io.papermc.paper.registry.set.RegistrySet<io.papermc.paper.datacomponent.@NotNull DataComponentType> excludeTypes, final boolean ignoreCount) {
+ return this.craftDelegate.matchesWithoutData(item, exclude, ignoreCount); + return this.craftDelegate.matchesWithoutData(item, excludeTypes, ignoreCount);
+ } + }
+ // Paper end - data component API + // Paper end - data component API
} }

Datei anzeigen

@ -3854,7 +3854,7 @@ index 12220f78ffaf06433ada72fd0c7f22b97d55287d..e1c6f514f45a02d7401b5390aefd0a49
// data-drivens // data-drivens
entry(Registries.STRUCTURE, RegistryKey.STRUCTURE, Structure.class, CraftStructure::new).delayed(), entry(Registries.STRUCTURE, RegistryKey.STRUCTURE, Structure.class, CraftStructure::new).delayed(),
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
index 756c73a401437566258813946fa10c7caa8f2469..528b6705b714376766bcab507781323a7a3e90b9 100644 index 756c73a401437566258813946fa10c7caa8f2469..4fe0543754ba644a7ce2231ec267007215f823c4 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
@@ -206,7 +206,7 @@ public final class CraftItemStack extends ItemStack { @@ -206,7 +206,7 @@ public final class CraftItemStack extends ItemStack {
@ -3948,7 +3948,7 @@ index 756c73a401437566258813946fa10c7caa8f2469..528b6705b714376766bcab507781323a
} }
static Map<Enchantment, Integer> getEnchantments(net.minecraft.world.item.ItemStack item) { static Map<Enchantment, Integer> getEnchantments(net.minecraft.world.item.ItemStack item) {
@@ -526,4 +545,140 @@ public final class CraftItemStack extends ItemStack { @@ -526,4 +545,129 @@ public final class CraftItemStack extends ItemStack {
return this.pdcView; return this.pdcView;
} }
// Paper end - pdc // Paper end - pdc
@ -4033,58 +4033,47 @@ index 756c73a401437566258813946fa10c7caa8f2469..528b6705b714376766bcab507781323a
+ } + }
+ +
+ @Override + @Override
+ public boolean matchesWithoutData(final ItemStack item, final io.papermc.paper.registry.set.RegistrySet<io.papermc.paper.datacomponent.DataComponentType> exclude, final boolean ignoreCount) { + public boolean matchesWithoutData(final ItemStack item, final io.papermc.paper.registry.set.RegistrySet<io.papermc.paper.datacomponent.DataComponentType> excludeTypes, final boolean ignoreCount) {
+ // Extracted from base equals + // Extracted from base equals
+ if (!(item instanceof final org.bukkit.inventory.ItemStack bukkit)) return false; + final CraftItemStack craftStack = getCraftStack(item);
+ final CraftItemStack craftStack = getCraftStack(bukkit);
+ if (this.handle == craftStack.handle) return true; + if (this.handle == craftStack.handle) return true;
+ else if (this.handle == null || craftStack.handle == null) return false; + if (this.handle == null || craftStack.handle == null) return false;
+ else if (this.handle.isEmpty() && craftStack.handle.isEmpty()) return true; + if (this.handle.isEmpty() && craftStack.handle.isEmpty()) return true;
+ else {
+ net.minecraft.world.item.ItemStack left = this.handle;
+ net.minecraft.world.item.ItemStack right = craftStack.handle;
+ if (!ignoreCount && left.getCount() != right.getCount()) {
+ return false;
+ }
+ if (!left.is(right.getItem())) {
+ return false;
+ }
+ +
+ // It can be assumed that the prototype is equal since the type is the same. This way all we need to check is the patch + net.minecraft.world.item.ItemStack left = this.handle;
+ + net.minecraft.world.item.ItemStack right = craftStack.handle;
+ // Flatten registry set into registry elements + if (!ignoreCount && left.getCount() != right.getCount()) {
+ java.util.Collection<io.papermc.paper.datacomponent.DataComponentType> excludeTypes; + return false;
+ if (exclude instanceof io.papermc.paper.registry.set.RegistryKeySet<io.papermc.paper.datacomponent.DataComponentType> keySet) {
+ excludeTypes = keySet.resolve(org.bukkit.Registry.DATA_COMPONENT_TYPE);
+ } else if (exclude instanceof io.papermc.paper.registry.set.RegistryValueSet<io.papermc.paper.datacomponent.DataComponentType> valueSet) {
+ excludeTypes = valueSet.values();
+ } else {
+ throw new UnsupportedOperationException();
+ }
+
+ // Collect all the NMS types into a set
+ java.util.Set<net.minecraft.core.component.DataComponentType<?>> skippingTypes = exclude.isEmpty() ? java.util.Set.of() : new java.util.HashSet<>(exclude.size()); // micro op
+ for (io.papermc.paper.datacomponent.DataComponentType api : excludeTypes) {
+ net.minecraft.core.component.DataComponentType<?> type = io.papermc.paper.datacomponent.PaperComponentType.bukkitToMinecraft(api);
+ skippingTypes.add(type);
+ }
+
+ // Iterate over the entries in the left item, where we will then check to make sure the right entry has the same value.
+ // But, ignore if in our special set
+ java.util.Set<java.util.Map.Entry<net.minecraft.core.component.DataComponentType<?>, java.util.Optional<?>>> rightEntries = right.getComponentsPatch().entrySet();
+ for (java.util.Map.Entry<net.minecraft.core.component.DataComponentType<?>, java.util.Optional<?>> leftEntry : left.getComponentsPatch().entrySet()) {
+ // This type should be skipped!
+ if (skippingTypes.contains(leftEntry.getKey())) {
+ continue;
+ }
+ // This will check if the right value contains the KEY & VALUE of leftEntry
+ if (!rightEntries.contains(leftEntry)) {
+ return false;
+ }
+ }
+
+ return true;
+ } + }
+ if (!left.is(right.getItem())) {
+ return false;
+ }
+
+ // It can be assumed that the prototype is equal since the type is the same. This way all we need to check is the patch
+
+ // Fast path when excluded types is empty to not flatten the set
+ if (excludeTypes.isEmpty()) {
+ return left.getComponentsPatch().equals(right.getComponentsPatch());
+ }
+
+ // Flatten registry set into registry elements
+ java.util.Collection<io.papermc.paper.datacomponent.DataComponentType> exclude;
+ if (excludeTypes instanceof io.papermc.paper.registry.set.RegistryKeySet<io.papermc.paper.datacomponent.DataComponentType> keySet) {
+ exclude = keySet.resolve(org.bukkit.Registry.DATA_COMPONENT_TYPE);
+ } else if (excludeTypes instanceof io.papermc.paper.registry.set.RegistryValueSet<io.papermc.paper.datacomponent.DataComponentType> valueSet) {
+ exclude = valueSet.values();
+ } else {
+ throw new UnsupportedOperationException();
+ }
+
+ // Collect all the NMS types into a set
+ java.util.Set<net.minecraft.core.component.DataComponentType<?>> skippingTypes = new java.util.HashSet<>(exclude.size());
+ for (io.papermc.paper.datacomponent.DataComponentType api : exclude) {
+ skippingTypes.add(io.papermc.paper.datacomponent.PaperComponentType.bukkitToMinecraft(api));
+ }
+
+ // Check the patch by first stripping excluded types and then compare the trimmed patches
+ return left.getComponentsPatch().forget(skippingTypes::contains).equals(right.getComponentsPatch().forget(skippingTypes::contains));
+ } + }
+ +
+ // Paper end - data component API + // Paper end - data component API
@ -4173,10 +4162,10 @@ index 0000000000000000000000000000000000000000..852ab097181491735fb9ee5ee4f70e4c
+io.papermc.paper.datacomponent.item.consumable.ConsumableTypesBridgeImpl +io.papermc.paper.datacomponent.item.consumable.ConsumableTypesBridgeImpl
diff --git a/src/test/java/io/papermc/paper/item/ItemStackDataComponentEqualsTest.java b/src/test/java/io/papermc/paper/item/ItemStackDataComponentEqualsTest.java diff --git a/src/test/java/io/papermc/paper/item/ItemStackDataComponentEqualsTest.java b/src/test/java/io/papermc/paper/item/ItemStackDataComponentEqualsTest.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..451ebde6856d2f128c623c42bf8f88d31683f407 index 0000000000000000000000000000000000000000..6a287dcd4b42fa494117ae3f07def596c69d29da
--- /dev/null --- /dev/null
+++ b/src/test/java/io/papermc/paper/item/ItemStackDataComponentEqualsTest.java +++ b/src/test/java/io/papermc/paper/item/ItemStackDataComponentEqualsTest.java
@@ -0,0 +1,85 @@ @@ -0,0 +1,94 @@
+package io.papermc.paper.item; +package io.papermc.paper.item;
+ +
+import io.papermc.paper.datacomponent.DataComponentTypes; +import io.papermc.paper.datacomponent.DataComponentTypes;
@ -4188,7 +4177,6 @@ index 0000000000000000000000000000000000000000..451ebde6856d2f128c623c42bf8f88d3
+import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ItemStack;
+import org.bukkit.support.environment.AllFeatures; +import org.bukkit.support.environment.AllFeatures;
+import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Test;
+ +
+@AllFeatures +@AllFeatures
@ -4230,7 +4218,6 @@ index 0000000000000000000000000000000000000000..451ebde6856d2f128c623c42bf8f88d3
+ } + }
+ +
+ @Test + @Test
+ @Disabled // todo look into that
+ public void testEqualWithoutComponent() { + public void testEqualWithoutComponent() {
+ ItemStack item1 = ItemStack.of(Material.STONE, 1); + ItemStack item1 = ItemStack.of(Material.STONE, 1);
+ +
@ -4241,6 +4228,17 @@ index 0000000000000000000000000000000000000000..451ebde6856d2f128c623c42bf8f88d3
+ } + }
+ +
+ @Test + @Test
+ public void testEqualRemoveComponent() {
+ ItemStack item1 = ItemStack.of(Material.STONE, 1);
+ item1.unsetData(DataComponentTypes.MAX_STACK_SIZE);
+
+ ItemStack item2 = ItemStack.of(Material.STONE, 1);
+ item2.unsetData(DataComponentTypes.MAX_STACK_SIZE);
+
+ Assertions.assertTrue(item1.matchesWithoutData(item2, RegistrySet.keySet(RegistryKey.DATA_COMPONENT_TYPE)));
+ }
+
+ @Test
+ public void testEqualIncludeComponentIgnoreSize() { + public void testEqualIncludeComponentIgnoreSize() {
+ ItemStack item1 = ItemStack.of(Material.STONE, 2); + ItemStack item1 = ItemStack.of(Material.STONE, 2);
+ item1.setData(DataComponentTypes.MAX_STACK_SIZE, 1); + item1.setData(DataComponentTypes.MAX_STACK_SIZE, 1);