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 的注册。