You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bukkit API物品名称/LORE设置后NBT冗余格式问题的替代方案咨询

解决方案:Bukkit物品NBT冗余格式标签问题

针对使用ItemMeta#setDisplayName()/setLore()后NBT出现italic: false等冗余标签导致物品比对失败的问题,以下是几种无需切换到Adventure库的解决方法:

1. 手动清理冗余NBT标签

直接操作物品的NBT结构,移除那些默认添加的、值为false的格式标签。可以借助Spigot提供的SpigotItemMeta来直接访问和修改显示名称/LORE的NBT标签:

import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SpigotItemMeta;
import net.minecraft.nbt.CompoundTag;
import java.util.List;

// 清理单个物品显示名称的冗余格式标签
public void cleanDisplayNameNBT(ItemStack item) {
    if (!item.hasItemMeta()) return;
    SpigotItemMeta spigotMeta = (SpigotItemMeta) item.getItemMeta();
    
    CompoundTag displayNameTag = spigotMeta.getDisplayNameTag();
    if (displayNameTag != null) {
        // 移除所有值为false的冗余格式标签
        String[] redundantTags = {"italic", "obfuscated", "bold", "strikethrough", "underlined"};
        for (String tag : redundantTags) {
            if (displayNameTag.getBoolean(tag) == false) {
                displayNameTag.remove(tag);
            }
        }
        spigotMeta.setDisplayNameTag(displayNameTag);
        item.setItemMeta(spigotMeta);
    }
}

// 清理LORE的冗余标签
public void cleanLoreNBT(ItemStack item) {
    if (!item.hasItemMeta()) return;
    SpigotItemMeta spigotMeta = (SpigotItemMeta) item.getItemMeta();
    
    List<CompoundTag> loreTags = spigotMeta.getLoreTags();
    if (loreTags == null || loreTags.isEmpty()) return;
    
    for (CompoundTag loreTag : loreTags) {
        String[] redundantTags = {"italic", "obfuscated", "bold", "strikethrough", "underlined"};
        for (String tag : redundantTags) {
            if (loreTag.getBoolean(tag) == false) {
                loreTag.remove(tag);
            }
        }
    }
    spigotMeta.setLoreTags(loreTags);
    item.setItemMeta(spigotMeta);
}

2. 自定义物品比对逻辑

绕过完整NBT比对,只校验物品的核心属性:物品类型、显示名称的纯文本内容、LORE纯文本、附魔、耐久等关键信息,从根源上避免冗余标签的干扰。

import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.ChatColor;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public boolean isMatchingItem(ItemStack a, ItemStack b) {
    if (a == null || b == null) return a == b;
    
    // 比对物品基础类型
    if (!a.getType().equals(b.getType())) return false;
    
    // 比对显示名称(去除所有颜色和格式代码)
    String nameA = getRawDisplayName(a.getItemMeta());
    String nameB = getRawDisplayName(b.getItemMeta());
    if (!Objects.equals(nameA, nameB)) return false;
    
    // 比对LORE内容(同样去除格式代码)
    List<String> loreA = getRawLore(a.getItemMeta());
    List<String> loreB = getRawLore(b.getItemMeta());
    if (!Objects.equals(loreA, loreB)) return false;
    
    // 按需添加其他核心属性比对:附魔、耐久、自定义持久化数据等
    return a.getDurability() == b.getDurability() && Objects.equals(a.getEnchantments(), b.getEnchantments());
}

private String getRawDisplayName(ItemMeta meta) {
    if (meta == null || !meta.hasDisplayName()) return null;
    return ChatColor.stripColor(meta.getDisplayName());
}

private List<String> getRawLore(ItemMeta meta) {
    if (meta == null || !meta.hasLore()) return null;
    return meta.getLore().stream().map(ChatColor::stripColor).collect(Collectors.toList());
}

3. 反射适配Spigot序列化逻辑(风险较高)

针对Spigot序列化时默认添加false格式标签的问题,可以通过反射修改内部序列化类的行为,避免生成冗余标签。但这种方法依赖Spigot的内部实现,版本更新后可能失效,需谨慎使用:

import net.md_5.bungee.chat.ComponentSerializer;
import java.lang.reflect.Method;

// 示例:修改ComponentSerializer的序列化逻辑,不输出false格式属性
public void fixSpigotSerialization() {
    try {
        Class<?> serializerClass = Class.forName("net.md_5.bungee.chat.ComponentSerializer");
        Method serializeMethod = serializerClass.getDeclaredMethod("serialize", net.md_5.bungee.api.chat.BaseComponent[].class);
        serializeMethod.setAccessible(true);
        
        // 具体实现需参考对应版本的Spigot/BungeeCord源码,替换原有序列化逻辑
        // 此处仅提供思路,实际代码需根据版本调整
    } catch (Exception e) {
        e.printStackTrace();
    }
}

内容的提问来源于stack exchange,提问作者JavaPro123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:53:10