From 64d2cd07d9bd07694c35fa8cea57bdbff555ded5 Mon Sep 17 00:00:00 2001 From: NotAlexNoyle Date: Thu, 4 Jun 2026 11:26:35 -0400 Subject: [PATCH] Fix 1.8-1.15.2 bobbing --- .../me/dniym/checks/BadAttributeCheck.java | 184 ++++++++++++++---- .../main/java/me/dniym/utils/NBTStuff.java | 44 +++-- 2 files changed, 173 insertions(+), 55 deletions(-) diff --git a/src/main/java/main/java/me/dniym/checks/BadAttributeCheck.java b/src/main/java/main/java/me/dniym/checks/BadAttributeCheck.java index 7940039..edd7052 100644 --- a/src/main/java/main/java/me/dniym/checks/BadAttributeCheck.java +++ b/src/main/java/main/java/me/dniym/checks/BadAttributeCheck.java @@ -1,6 +1,10 @@ package main.java.me.dniym.checks; +import com.google.common.collect.Multimap; import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; import main.java.me.dniym.IllegalStack; import main.java.me.dniym.enums.Msg; import main.java.me.dniym.enums.Protections; @@ -12,6 +16,7 @@ import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; import org.bukkit.entity.Player; import org.bukkit.inventory.CraftingInventory; +import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -53,51 +58,99 @@ public class BadAttributeCheck { } - return is != null && is.getType() != Material.AIR && checkForBadCustomData(is, obj); + return hasNonDefaultAttributeModifiers(is); + + } + + /** + * Pure predicate: true iff the item carries at least one AttributeModifier that + * is NOT part of the vanilla default modifier set for its Material. Vanilla + * defaults are exposed via ItemMeta on 1.20.5+, so a naive + * hasAttributeModifiers() check false-positives every vanilla weapon/armor and + * causes inventory churn when the periodic scanner rewrites the meta. + */ + public static boolean hasNonDefaultAttributeModifiers(ItemStack is) { + + if (is == null || is.getType() == Material.AIR) { + + return false; + + } + + if (IllegalStack.isHasAttribAPI()) { + + ItemMeta meta = is.getItemMeta(); + return meta != null && hasCustomModifier(meta, is.getType()); + + } + + if (IllegalStack.isNbtAPI()) { + + return NBTApiStuff.hasBadCustomDataLegacy(is); + + } + + return false; } public static boolean checkForBadCustomData(ItemStack itemStack, Object obj) { - ItemMeta itemMeta = itemStack.getItemMeta(); if (IllegalStack.isHasAttribAPI()) { - if (itemMeta.hasAttributeModifiers()) { + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null || !itemMeta.hasAttributeModifiers()) { - StringBuilder attribs = new StringBuilder(); - HashSet toRemove = new HashSet<>(); - for (Attribute a : itemMeta.getAttributeModifiers().keySet()) { - - for (AttributeModifier st : itemMeta.getAttributeModifiers(a)) { - - attribs.append(" ").append(st.getName()).append(" value: ").append(st.getAmount()); - - } - - toRemove.add(a); - - } - - fListener.getLog().append(Msg.CustomAttribsRemoved3.getValue(itemStack, obj, attribs), - Protections.RemoveCustomAttributes); - - for (Attribute remove : toRemove) { - - itemMeta.removeAttributeModifier(remove); - - } - - for (ItemFlag iFlag : itemMeta.getItemFlags()) { - - itemMeta.removeItemFlags(iFlag); - - } - - itemStack.setItemMeta(itemMeta); - return true; + return false; } + Set defaultUuids = collectDefaultModifierUuids(itemStack.getType()); + Multimap mods = itemMeta.getAttributeModifiers(); + + StringBuilder attribs = new StringBuilder(); + boolean anyCustom = false; + for (Map.Entry entry : mods.entries()) { + + AttributeModifier mod = entry.getValue(); + if (!defaultUuids.contains(mod.getUniqueId())) { + + anyCustom = true; + attribs.append(" ").append(mod.getName()).append(" value: ").append(mod.getAmount()); + + } + + } + + if (!anyCustom) { + + return false; + + } + + fListener.getLog().append(Msg.CustomAttribsRemoved3.getValue(itemStack, obj, attribs), + Protections.RemoveCustomAttributes); + + for (Map.Entry entry : mods.entries()) { + + AttributeModifier mod = entry.getValue(); + if (!defaultUuids.contains(mod.getUniqueId())) { + + itemMeta.removeAttributeModifier(entry.getKey(), mod); + + } + + } + + for (ItemFlag iFlag : itemMeta.getItemFlags()) { + + itemMeta.removeItemFlags(iFlag); + + } + + itemStack.setItemMeta(itemMeta); + return true; + } else if (IllegalStack.isNbtAPI()) { return NBTApiStuff.checkForBadCustomDataLegacy(itemStack, obj); @@ -113,4 +166,67 @@ public class BadAttributeCheck { } + private static boolean hasCustomModifier(ItemMeta meta, Material type) { + + if (!meta.hasAttributeModifiers()) { + + return false; + + } + + Set defaultUuids = collectDefaultModifierUuids(type); + Multimap mods = meta.getAttributeModifiers(); + for (AttributeModifier mod : mods.values()) { + + if (!defaultUuids.contains(mod.getUniqueId())) { + + return true; + + } + + } + + return false; + + } + + public static Set collectDefaultModifierUuidsPublic(Material type) { + + return collectDefaultModifierUuids(type); + + } + + private static Set collectDefaultModifierUuids(Material type) { + + Set uuids = new HashSet<>(); + for (EquipmentSlot slot : EquipmentSlot.values()) { + + try { + + Multimap defaults = type.getDefaultAttributeModifiers(slot); + if (defaults == null) { + + continue; + + } + + for (AttributeModifier defMod : defaults.values()) { + + uuids.add(defMod.getUniqueId()); + + } + + } catch (Throwable ignored) { + + // Method may not exist on older servers, or the slot is incompatible + // with this material. Degrade gracefully: treat as no defaults known + // for that slot. + } + + } + + return uuids; + + } + } diff --git a/src/main/java/main/java/me/dniym/utils/NBTStuff.java b/src/main/java/main/java/me/dniym/utils/NBTStuff.java index d66fe7f..04c79a4 100644 --- a/src/main/java/main/java/me/dniym/utils/NBTStuff.java +++ b/src/main/java/main/java/me/dniym/utils/NBTStuff.java @@ -1,6 +1,5 @@ package main.java.me.dniym.utils; -import java.util.HashSet; import main.java.me.dniym.IllegalStack; import main.java.me.dniym.enums.Msg; import main.java.me.dniym.enums.Protections; @@ -216,19 +215,7 @@ public class NBTStuff { public static boolean hasBadCustomData(ItemStack is) { - ItemMeta im = is.getItemMeta(); - - if (IllegalStack.isHasAttribAPI() && is.hasItemMeta() && im.hasAttributeModifiers()) { - - return true; - - } else if (IllegalStack.isNbtAPI()) { - - return NBTApiStuff.hasBadCustomDataLegacy(is); - - } - - return false; + return main.java.me.dniym.checks.BadAttributeCheck.hasNonDefaultAttributeModifiers(is); } @@ -269,17 +256,27 @@ public class NBTStuff { if (IllegalStack.isHasAttribAPI() && im.hasAttributeModifiers()) { + java.util.Set defaultUuids = main.java.me.dniym.checks.BadAttributeCheck + .collectDefaultModifierUuidsPublic(is.getType()); + com.google.common.collect.Multimap mods = im.getAttributeModifiers(); + StringBuilder attribs = new StringBuilder(); - HashSet toRemove = new HashSet<>(); - for (Attribute a : im.getAttributeModifiers().keySet()) { + boolean anyCustom = false; + for (java.util.Map.Entry entry : mods.entries()) { - for (AttributeModifier st : im.getAttributeModifiers(a)) { + AttributeModifier mod = entry.getValue(); + if (!defaultUuids.contains(mod.getUniqueId())) { - attribs.append(" ").append(st.getName()).append(" value: ").append(st.getAmount()); + anyCustom = true; + attribs.append(" ").append(mod.getName()).append(" value: ").append(mod.getAmount()); } - toRemove.add(a); + } + + if (!anyCustom) { + + return; } @@ -294,9 +291,14 @@ public class NBTStuff { } - for (Attribute remove : toRemove) { + for (java.util.Map.Entry entry : mods.entries()) { - im.removeAttributeModifier(remove); + AttributeModifier mod = entry.getValue(); + if (!defaultUuids.contains(mod.getUniqueId())) { + + im.removeAttributeModifier(entry.getKey(), mod); + + } }