这里引用一个有关的帖子: 关于Lore中PlaceholderAPI刷新问题
总所周知,物品的Lore和Name都是写死在NBT中的,官方并没有给出能实现动态Lore的方法(低版本)
如何动态修改:
传统上的能实现动态修改Lore的方法有两种:
①监听Bukkit提供的事件,然后修改ItemStack(Bukkit)
②拦截发包PacketPlayOutSetSlot,将NBTTagCompond应用到ItemStack(NMS),然后再发包
这两种都涉及到了修改NBT,这是不可避免的
但是对于多变的变量,我们还需要自发的发包或者修改玩家背包,
因为PacketPlayOutSetSlot只会在物品被设置到背包时发送,背包内移动不算;
Bukkit事件也只会在玩家操作物品时触发。
不同版本的应用:
对于高版本(1.16+),我们可以使用NBT组件,将变量存到自定义NBT里,再在display中调用;
对于低版本,可以将原始的Lore或Name存一份到自定义NBT中,然后再复制到display并解析(应用变量)。
缺陷:
高版本
高版本还好说,你只需要改存在自定义NBT里的变量,不需要考虑其他插件的干扰,
但是如果改变的不是几个固定位置的变量,而是一整个Lore(多页Lore),这就需要考虑其他插件的干扰了
干扰:
你是要重写一遍Lore的,如果其他插件修改了这个物品的Lore,
Lore的重写会直接让这个“其他插件”的修改失效(覆盖)。
低版本:
但是在低版本,目前就只有重写Lore这一种方法。
不通用的解决办法:
不过这也是有解决办法的,可以用上述修改发包的方法,在发包时解析变量
但即使这样,也还有缺陷,就是在聊天展示物品(聊天插件功能)时,会显示原始Lore,
你需要去主动适配!这就很麻烦,不具备通用性。
讨论:
那么,是否存在一种高效且具备通用性的方法,能够实现Lore的动态变换?
总所周知,物品的Lore和Name都是写死在NBT中的,官方并没有给出能实现动态Lore的方法(低版本)
如何动态修改:
传统上的能实现动态修改Lore的方法有两种:
①监听Bukkit提供的事件,然后修改ItemStack(Bukkit)
②拦截发包PacketPlayOutSetSlot,将NBTTagCompond应用到ItemStack(NMS),然后再发包
这两种都涉及到了修改NBT,这是不可避免的
但是对于多变的变量,我们还需要自发的发包或者修改玩家背包,
因为PacketPlayOutSetSlot只会在物品被设置到背包时发送,背包内移动不算;
Bukkit事件也只会在玩家操作物品时触发。
不同版本的应用:
对于高版本(1.16+),我们可以使用NBT组件,将变量存到自定义NBT里,再在display中调用;
对于低版本,可以将原始的Lore或Name存一份到自定义NBT中,然后再复制到display并解析(应用变量)。
缺陷:
高版本
高版本还好说,你只需要改存在自定义NBT里的变量,不需要考虑其他插件的干扰,
但是如果改变的不是几个固定位置的变量,而是一整个Lore(多页Lore),这就需要考虑其他插件的干扰了
干扰:
你是要重写一遍Lore的,如果其他插件修改了这个物品的Lore,
Lore的重写会直接让这个“其他插件”的修改失效(覆盖)。
低版本:
但是在低版本,目前就只有重写Lore这一种方法。
不通用的解决办法:
不过这也是有解决办法的,可以用上述修改发包的方法,在发包时解析变量
但即使这样,也还有缺陷,就是在聊天展示物品(聊天插件功能)时,会显示原始Lore,
你需要去主动适配!这就很麻烦,不具备通用性。
讨论:
那么,是否存在一种高效且具备通用性的方法,能够实现Lore的动态变换?