|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 AcesDephtPest 于 2024-8-30 20:16 编辑
NBT丢失,没啥好说的,有大佬解释下吗awa
public static class ItemStack implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
public static class metas {
private static Class<?> PotionTypeClass;
private static final Class<?> ArmorMetaClass = loadClass("ArmorMeta");
private static final Class<?> AxolotlBucketMetaClass = loadClass("AxolotlBucketMeta");
private static final Class<?> BannerMetaClass = loadClass("BannerMeta");
private static final Class<?> BlockDataMetaClass = loadClass("BlockData");
private static final Class<?> BlockStateMetaClass = loadClass("BlockState");
private static final Class<?> BookMetaClass = loadClass("BookMeta");
private static final Class<?> BookMetaGenerationClass = loadClass("BookMeta.Generation"); // 假设有 Generation 枚举
private static final Class<?> BundleMetaClass = loadClass("BundleMeta");
private static final Class<?> ColorableArmorMetaClass = loadClass("LeatherArmorMeta"); // 注意: 皮革盔甲是可以染色的
private static final Class<?> CompassMetaClass = loadClass("CompassMeta");
private static final Class<?> CrossbowMetaClass = loadClass("CrossbowMeta");
private static final Class<?> DamageableClass = loadClass("Damageable");
private static final Class<?> EnchantmentStorageMetaClass = loadClass("EnchantmentStorageMeta");
private static final Class<?> FireworkEffectMetaClass = loadClass("FireworkEffectMeta");
private static final Class<?> FireworkMetaClass = loadClass("FireworkMeta");
private static final Class<?> KnowledgeBookMetaClass = loadClass("KnowledgeBookMeta");
private static final Class<?> LeatherArmorMetaClass = loadClass("LeatherArmorMeta");
private static final Class<?> MapMetaClass = loadClass("MapMeta");
private static final Class<?> MusicInstrumentMetaClass = loadClass("MusicInstrumentMeta");
private static final Class<?> OminousBottleMetaClass = loadClass("OminousBottleMeta");
private static final Class<?> PotionMetaClass = loadClass("PotionMeta");
private static final Class<?> RepairableClass = loadClass("Repairable");
private static final Class<?> SkullMetaClass = loadClass("SkullMeta");
private static final Class<?> SpawnEggMetaClass = loadClass("SpawnEggMeta");
private static final Class<?> SuspiciousStewMetaClass = loadClass("SuspiciousStewMeta");
private static final Class<?> TropicalFishBucketMetaClass = loadClass("TropicalFishBucketMeta");
private static final Class<?> WritableBookMetaClass = loadClass("WritableBookMeta");
// 动态加载类的私有方法
private static Class<?> loadClass(String className) {
try {
return Class.forName("org.bukkit.inventory.meta." + className);
} catch (ClassNotFoundException e) {
System.err.println("Class org.bukkit.inventory.meta." + className + " not found.");
return null;
}
}
}
private Material type = Material.AIR;
private int amount = 0;
private List<String> lore = new ArrayList<>();
private String displayName = null;
private Map<String, Integer> enchantments = new HashMap<>(); // 存储附魔名称和级别
private Object potionType = null; // 药水类型
private boolean isSplash = false; // 是否为喷溅药水
private String Variant = null; // 代表一桶蝾螈
private List<Object> BannerMeta = null; // 旗帜的图案的列表
private Location CompassMeta = null; // 代表能追踪指定位置的指南针
private short Damageable = 0; // 代表有耐久度,可损耗的物品
private Map<String, Integer> EnchantmentStorageMeta = new HashMap<>(); // 特定于专门存储附魔的物品,而非被附魔的物品. 附魔书 就是一个可存储附魔的物品的例子.
private Object FireworkEffectMeta = null; // 烟花效果
private List<Object> FireworkMeta = new ArrayList<>(); // 烟花火箭及其效果
private List<Object> KnowledgeBookMeta = new ArrayList<>(); //与知识之书有关的元数据
private Color LeatherArmorMeta = null; // 下文中的"盔甲"可以是皮革靴子,外套,帽子,裤子任意一种,因为这个类代表了四种嘛
private Color MapMetaColor = null; // 伸缩的地图
private Object MapMetaMapView = null; // 伸缩的地图
private int Repairable = 0; //修复此物品所需的额外经验等级
private Object SkullMetaOfflinePlayer = null; //头颅的主人
private List<Object> SuspiciousStewMeta = new ArrayList<>(); //自定义药水效果的迷之炖菜
private Object TropicalFishBucketMetaBodyColor = null; //热带鱼桶
private Object TropicalFishBucketMetaPattern = null; //热带鱼桶
private Object TropicalFishBucketMetaPatternColor = null; // 热带鱼桶
private String BookMetaAuthor = null; // 热带鱼桶
private Object BookMetaGeneration = null; // 热带鱼桶
private List<String> BookMetaPages = null; // 热带鱼桶
private String BookMetaTitle = null;
public ItemStack(org.bukkit.inventory.ItemStack itemStack) {
if (itemStack != null && itemStack.getType() != Material.AIR) {
this.type = itemStack.getType();
this.amount = itemStack.getAmount();
getMeta(itemStack.getItemMeta());
this.enchantments = new HashMap<>();
for (Map.Entry<Enchantment, Integer> entry : itemStack.getEnchantments().entrySet()) {
this.enchantments.put(entry.getKey().getKey().toString(), entry.getValue());
}
}
}
public org.bukkit.inventory.ItemStack toItemStack() {
org.bukkit.inventory.ItemStack itemStack = new org.bukkit.inventory.ItemStack(this.type, this.amount);
itemStack.setItemMeta(setMeta(itemStack.getItemMeta()));
return itemStack;
}
public Object classTo(Class<?> clazz, String name,ItemMeta meta) {
if (clazz != null && clazz.isInstance(meta)) {
try {
Method method = clazz.getMethod(name);
return method.invoke(meta);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {}
}
return null;
}
public void classSet(Class<?> clazz, String name, Object object, ItemMeta meta) {
if (clazz != null && clazz.isInstance(meta)) {
try {
Method setDamageMethod = clazz.getMethod(name, object.getClass());
setDamageMethod.invoke(meta, object);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {}
}
}
@SuppressWarnings("unchecked")
public void getMeta(ItemMeta meta) {
if (meta != null) {
if (metas.DamageableClass != null && metas.DamageableClass.isInstance(meta)) {
Integer integerValue = (Integer) classTo(metas.DamageableClass, "getDamage", meta);
if (integerValue != null && integerValue >= Short.MIN_VALUE && integerValue <= Short.MAX_VALUE) this.Damageable = integerValue.shortValue();
else System.out.println(integerValue);
}
if (metas.TropicalFishBucketMetaClass != null && metas.TropicalFishBucketMetaClass.isInstance(meta)) this.Variant = (String) classTo(metas.AxolotlBucketMetaClass,"getVariant",meta);
if (metas.BannerMetaClass != null && metas.BannerMetaClass.isInstance(meta)) this.BannerMeta = (List<Object>) classTo(metas.BannerMetaClass,"getPatterns",meta);
if (metas.CompassMetaClass != null && metas.CompassMetaClass.isInstance(meta)) this.CompassMeta = (Location) classTo(metas.CompassMetaClass,"getLodestone",meta);
if (metas.EnchantmentStorageMetaClass != null && metas.EnchantmentStorageMetaClass.isInstance(meta)) {
this.EnchantmentStorageMeta = new HashMap<>();
Map<Enchantment, Integer> list = (Map<Enchantment, Integer>) classTo(metas.EnchantmentStorageMetaClass, "getStoredEnchants", meta);
for (Map.Entry<Enchantment, Integer> entry : list.entrySet()) {
this.EnchantmentStorageMeta.put(entry.getKey().getKey().toString(), entry.getValue());
}
}
if (metas.FireworkEffectMetaClass != null && metas.FireworkEffectMetaClass.isInstance(meta)) this.FireworkEffectMeta = (FireworkEffect) classTo(metas.FireworkEffectMetaClass,"getEffect",meta);
if (metas.FireworkMetaClass != null && metas.FireworkMetaClass.isInstance(meta)) this.FireworkMeta = (List<Object>) classTo(metas.FireworkMetaClass,"getEffects",meta);
if (metas.KnowledgeBookMetaClass != null && metas.KnowledgeBookMetaClass.isInstance(meta)) this.KnowledgeBookMeta = (List<Object>) classTo(metas.KnowledgeBookMetaClass,"getRecipes",meta);
if (metas.LeatherArmorMetaClass != null && metas.LeatherArmorMetaClass.isInstance(meta)) this.LeatherArmorMeta = (Color) classTo(metas.LeatherArmorMetaClass,"getColor",meta);
if (metas.MapMetaClass != null && metas.MapMetaClass.isInstance(meta)) {
this.MapMetaColor = (Color) classTo(metas.MapMetaClass, "getColor", meta);
this.MapMetaMapView = (MapView) classTo(metas.MapMetaClass, "getColor", meta);
}
if (metas.RepairableClass != null && metas.RepairableClass.isInstance(meta)) this.Repairable = (int) classTo(metas.RepairableClass, "getRepairCost", meta);
if (metas.SkullMetaClass != null && metas.SkullMetaClass.isInstance(meta)) this.SkullMetaOfflinePlayer = classTo(metas.SkullMetaClass,"getOwningPlayer",meta);
if (metas.SuspiciousStewMetaClass != null && metas.SuspiciousStewMetaClass.isInstance(meta)) this.SuspiciousStewMeta = (List<Object>) classTo(metas.SuspiciousStewMetaClass,"getCustomEffects",meta);
if (metas.TropicalFishBucketMetaClass != null && metas.TropicalFishBucketMetaClass.isInstance(meta)) {
this.TropicalFishBucketMetaPattern = classTo(metas.TropicalFishBucketMetaClass,"getPattern",meta);
this.TropicalFishBucketMetaBodyColor = classTo(metas.TropicalFishBucketMetaClass,"getBodyColor",meta);
this.TropicalFishBucketMetaPatternColor = classTo(metas.TropicalFishBucketMetaClass,"getPatternColor",meta);
}
if (metas.BookMetaClass != null && metas.BookMetaClass.isInstance(meta)) {
this.BookMetaAuthor = (String) classTo(metas.BookMetaClass, "getAuthor", meta);
this.BookMetaGeneration = classTo(metas.BookMetaClass, "getGeneration", meta);
this.BookMetaPages = (List<String>) classTo(metas.BookMetaClass, "getPages", meta);
this.BookMetaTitle = (String) classTo(metas.BookMetaClass, "getTitle", meta);
}
this.lore = Objects.requireNonNull(meta).hasLore() ? new ArrayList<>(Objects.requireNonNull(meta.getLore())) : null;
this.displayName = meta.hasDisplayName() ? meta.getDisplayName() : null;
if ((metas.PotionMetaClass != null && metas.PotionMetaClass.isInstance(meta)) &&
this.type.equals(Material.POTION) || this.type.equals(Material.SPLASH_POTION) || this.type.equals(Material.LINGERING_POTION)) {
try {
this.potionType = classTo(metas.PotionMetaClass, "getBasePotionData", meta).getClass().getMethod("getType").invoke(meta);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ignored) {}
this.isSplash = this.type == Material.SPLASH_POTION;
}
}
}
public ItemMeta setMeta(ItemMeta meta) {
if (meta != null) {
if (this.displayName != null) meta.setDisplayName(this.displayName);
if (this.lore != null) meta.setLore(this.lore);
if (this.enchantments != null && !this.enchantments.isEmpty()) for (Map.Entry<String, Integer> entry : this.enchantments.entrySet()) {
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.fromString(entry.getKey()));
if (enchantment != null) meta.addEnchant(enchantment, entry.getValue(), true);
}
if (instance(meta,metas.DamageableClass)) classSet(metas.DamageableClass,"setDamage",this.Damageable,meta);
if (instance(meta,metas.TropicalFishBucketMetaClass)) classSet(metas.AxolotlBucketMetaClass,"setVariant",this.Variant,meta);
if (instance(meta,metas.BannerMetaClass)) classSet(metas.BannerMetaClass,"setPatterns",this.BannerMeta,meta);
if (instance(meta,metas.CompassMetaClass)) classSet(metas.CompassMetaClass,"setLodestone",this.CompassMeta,meta);
if (instance(meta,metas.EnchantmentStorageMetaClass) && this.EnchantmentStorageMeta != null && !this.EnchantmentStorageMeta.isEmpty()) for (Map.Entry<String, Integer> entry : this.EnchantmentStorageMeta.entrySet()) {
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.fromString(entry.getKey()));
if (enchantment != null && metas.EnchantmentStorageMetaClass.isInstance(meta)) {
try {
Method setDamageMethod = metas.EnchantmentStorageMetaClass.getMethod("addStoredEnchant", Enchantment.class,Integer.class,Boolean.class);
setDamageMethod.invoke(meta, enchantment, entry.getValue(), true);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {}
}
}
if (instance(meta,metas.FireworkEffectMetaClass)) classSet(metas.FireworkEffectMetaClass,"setEffect",this.FireworkEffectMeta,meta);
if (instance(meta,metas.FireworkMetaClass)) classSet(metas.FireworkMetaClass,"setEffects",this.FireworkMeta,meta);
if (instance(meta,metas.KnowledgeBookMetaClass)) classSet(metas.KnowledgeBookMetaClass,"setRecipes",this.KnowledgeBookMeta,meta);
if (instance(meta,metas.LeatherArmorMetaClass)) classSet(metas.LeatherArmorMetaClass,"setColor",this.LeatherArmorMeta,meta);
if (instance(meta,metas.MapMetaClass)) {
classSet(metas.MapMetaClass, "setColor",this.MapMetaColor, meta);
classSet(metas.MapMetaClass, "setColor",this.MapMetaMapView, meta);
}
if (instance(meta,metas.RepairableClass)) classSet(metas.RepairableClass, "setRepairCost",this.Repairable, meta);
if (instance(meta,metas.SkullMetaClass)) classSet(metas.SkullMetaClass,"setOwningPlayer",this.SkullMetaOfflinePlayer,meta);
if (instance(meta,metas.SuspiciousStewMetaClass)) classSet(metas.SuspiciousStewMetaClass,"setCustomEffects",this.SuspiciousStewMeta,meta);
if (instance(meta,metas.TropicalFishBucketMetaClass)) {
classSet(metas.TropicalFishBucketMetaClass,"setPattern",this.TropicalFishBucketMetaPattern,meta);
classSet(metas.TropicalFishBucketMetaClass,"setBodyColor",this.TropicalFishBucketMetaBodyColor,meta);
classSet(metas.TropicalFishBucketMetaClass,"setPatternColor",this.TropicalFishBucketMetaPatternColor,meta);
}
if (instance(meta,metas.BookMetaClass)) {
classSet(metas.BookMetaClass, "setAuthor",this.BookMetaAuthor, meta);
classSet(metas.BookMetaClass, "setGeneration",this.BookMetaGeneration, meta);
classSet(metas.BookMetaClass, "setPages",this.BookMetaPages, meta);
classSet(metas.BookMetaClass, "setTitle",this.BookMetaTitle, meta);
}
this.lore = Objects.requireNonNull(meta).hasLore() ? new ArrayList<>(Objects.requireNonNull(meta.getLore())) : null;
this.displayName = meta.hasDisplayName() ? meta.getDisplayName() : null;
if (instance(meta,metas.PotionMetaClass) && this.type.equals(Material.POTION) || this.type.equals(Material.SPLASH_POTION) || this.type.equals(Material.LINGERING_POTION)) {
try {
this.potionType = classTo(metas.PotionMetaClass, "getBasePotionData", meta).getClass().getMethod("getType").invoke(meta);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ignored) {}
this.isSplash = this.type == Material.SPLASH_POTION;
}
if (instance(meta,metas.DamageableClass) && this.Damageable > 0) classSet(metas.DamageableClass,"setDamage",this.Damageable,meta);
if (instance(meta,metas.PotionMetaClass) && this.potionType != null) {
if (this.type.equals(Material.POTION) || this.type.equals(Material.LINGERING_POTION) || this.type.equals(Material.SPLASH_POTION)) {
if (metas.PotionMetaClass.isInstance(meta)) {
try {
Constructor<?> potionDataConstructor = metas.PotionTypeClass.getConstructor(boolean.class, boolean.class, boolean.class);
Method setBasePotionDataMethod = metas.PotionMetaClass.getMethod("setBasePotionData", metas.PotionTypeClass);
setBasePotionDataMethod.invoke(meta, potionDataConstructor.newInstance(
!isSplash && (boolean) classTo(this.potionType.getClass(),"isExtendable",meta),
isSplash && (boolean) classTo(this.potionType.getClass(),"isUpgradeable",meta),
false
));
} catch (Exception ignored) {}
}
}
}
if (instance(meta,metas.AxolotlBucketMetaClass) && this.Variant != null) {
classSet(metas.AxolotlBucketMetaClass,"setVariant",this.Variant,meta);
}
if (instance(meta,metas.BannerMetaClass) && this.BannerMeta != null) {
classSet(metas.BannerMetaClass,"setPatterns",this.BannerMeta,meta);
}
if (instance(meta,metas.CompassMetaClass) && this.CompassMeta != null) {
classSet(metas.CompassMetaClass,"setLodestone",this.CompassMeta.toLocation(),meta);
}
if (instance(meta,metas.FireworkEffectMetaClass) && this.FireworkEffectMeta != null) {
classSet(metas.FireworkEffectMetaClass,"setEffect",this.FireworkEffectMeta,meta);
}
if (instance(meta,metas.FireworkMetaClass) && this.FireworkMeta != null) {
classSet(metas.FireworkMetaClass,"addEffects",this.FireworkMeta,meta);
}
if (instance(meta,metas.KnowledgeBookMetaClass) && this.KnowledgeBookMeta != null) {
classSet(metas.KnowledgeBookMetaClass,"setRecipes",this.KnowledgeBookMeta,meta);
}
if (instance(meta,metas.LeatherArmorMetaClass) && this.LeatherArmorMeta != null) {
classSet(metas.LeatherArmorMetaClass,"setColor",this.LeatherArmorMeta,meta);
}
if (instance(meta,metas.MapMetaClass)) {
if (this.MapMetaColor != null) classSet(metas.MapMetaClass,"setColor",this.MapMetaColor,meta);
if (this.MapMetaMapView != null) classSet(metas.MapMetaClass,"setMapView",this.MapMetaMapView,meta);
}
if (instance(meta,metas.RepairableClass) && this.Repairable > 0) {
classSet(metas.RepairableClass,"setRepairCost",this.Repairable,meta);
}
if (instance(meta,metas.SkullMetaClass) && this.SkullMetaOfflinePlayer != null) {
classSet(metas.SkullMetaClass,"setOwningPlayer",this.SkullMetaOfflinePlayer,meta);
}
if (instance(meta,metas.SuspiciousStewMetaClass) && this.SuspiciousStewMeta != null) {
for (Object data : this.SuspiciousStewMeta)
if (data != null && metas.SuspiciousStewMetaClass.isInstance(meta)) {
try {
Method setDamageMethod = metas.SuspiciousStewMetaClass.getMethod("addCustomEffect", Object.class,Boolean.class);
setDamageMethod.invoke(meta, data, true);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {}
}
}
if (instance(meta,metas.TropicalFishBucketMetaClass)) {
if (this.TropicalFishBucketMetaBodyColor != null) classSet(metas.TropicalFishBucketMetaClass,"setBodyColor",this.TropicalFishBucketMetaBodyColor,meta);
if (this.TropicalFishBucketMetaPattern != null) classSet(metas.TropicalFishBucketMetaClass,"setPattern",this.TropicalFishBucketMetaPattern,meta);
if (this.TropicalFishBucketMetaPatternColor != null) classSet(metas.TropicalFishBucketMetaClass,"setPatternColor",this.TropicalFishBucketMetaPatternColor,meta);
}
if (instance(meta,metas.BookMetaClass)) {
if (this.BookMetaAuthor != null) classSet(metas.BookMetaClass,"setAuthor",this.BookMetaAuthor,meta);
if (this.BookMetaGeneration != null) classSet(metas.BookMetaClass,"setGeneration",this.BookMetaGeneration,meta);
if (this.BookMetaPages != null) classSet(metas.BookMetaClass,"setPages",this.BookMetaPages,meta);
if (this.BookMetaTitle != null) classSet(metas.BookMetaClass,"setTitle",this.BookMetaTitle,meta);
}
}
return meta;
}
public static boolean instance(ItemMeta meta,Class<?> clazz) {
return clazz != null && clazz.isInstance(meta);
}
public static class Location implements Serializable {
private final double x;
private final double y;
private final double z;
private final World world;
public Location(org.bukkit.Location location) {
this.world = location.getWorld();
this.x = location.getX();
this.y = location.getY();
this.z = location.getZ();
}
public org.bukkit.Location toLocation() {
return new org.bukkit.Location(this.world,this.x,this.y,this.z);
}
}
}
|
|