Stack Stringify Handler(元素物品 NBT 序列化)

基本信息

属性 值
类型 NEI 栈序列化扩展(IStackStringifyHandler)
源码类 com.gtnewhorizons.aspectrecipeindex.nei.TCAspectStringifyHandler
注册时机 NEIConfig.loadConfig(),整段包在 try / catch (NoSuchMethodError ignored) 里
作用对象 aspectrecipeindex:aspect(见 Aspect 物品)

功能:给 NEI 提供本模组元素的紧凑序列化格式。用元素物品搜索时,NEI 的已存历史 / 收藏 / 书签里只保存元素的 NBT tag,而不是完整物品栈。

为什么需要它

元素物品用 NBT 键 Aspect 存元素 tag(见 Aspect 物品),而 NEI 自己的 IStackStringifyHandler 只处理 Item + metadata,无法区分同一物品下的不同 NBT。ARI 补上这一层。

顺带的实际效果:NEI 在搜索框里输入元素名时,能正确把历史记录里的元素物品还原出来。

序列化:convertItemStackToNBT

步骤 行为
非 ItemAspect 返回 null(交回 NEI 默认处理)
ItemAspect.getAspect(stack) 为 null 返回 null
正常情况 返回 NBTTagCompound

生成的 NBT:

字段 类型 值
TCAspect String aspect.getTag()
Count int Math.max(saveStackSize ? stack.stackSize : 1, 1)

Count 的语义:第二个参数 saveStackSize 为真时取真实堆叠数,否则强制为 1;外层 Math.max(..., 1) 保证不会存 0 或负数。

字段名 TCAspect 沿用 TCNEIPlugin 的历史约定——FMLMissingMappingsEvent 处理器正是特意忽略 thaumcraftneiplugin:Aspect 的物品映射,让 TCNEIPlugin 存的历史记录可以平滑迁移。

反序列化:convertNBTToItemStack

步骤 行为
nbtTag == null 或不含 TCAspect 键 返回 null
正常情况 new ItemStack(ModItems.itemAspect, nbtTag.getInteger("Count")),再 ItemAspect.setAspect(stack, Aspect.getAspect(tag))

metadata 恒为默认 0(构造函数只传了物品与堆叠数)。这意味着反序列化出来的元素物品遵循 Aspect 物品 里的 metadata 规则:需要"永远显示图标"的场合应当走 meta = 1,但本 handler 不会主动设置它。

Aspect.getAspect(String tag) 对未知 tag 返回 null,此时 setAspect 会 NPE——setAspect 里 aspect.getTag() 无判空。这是一条潜在的崩溃路径(只在存档里出现从未知 tag 时触发)。

静默降级

注册处:

try {
    API.registerStackStringifyHandler(new TCAspectStringifyHandler());
} catch (NoSuchMethodError ignored) {}

用的是 NoSuchMethodError——不是 NoSuchMethodException。这说明目标 API 在二进制层面缺失(编译期有、运行期 NEI 版本没有该方法),正是跨 NEI 版本兼容的典型写法。捕获后完全静默,不打日志、不影响其余 6 个 handler 的注册。

相关条目