Memorial Edition

查看: 559|回复: 2

ItemStack(映射版,但是是NBT丢失)

[复制链接]

Lv.5 农夫

人气
17 点
金粒
132 粒
宝石
1 颗
爱心
0 颗
钻石
87 颗
贡献
0 点

石镐矿工勋章

发表于 2024-8-28 21:27:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

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);
            }
        }
    }



Lv.5 农夫

人气
17 点
金粒
132 粒
宝石
1 颗
爱心
0 颗
钻石
87 颗
贡献
0 点

石镐矿工勋章

 楼主| 发表于 2024-8-30 20:17:57 | 显示全部楼层
最后修改的代码:第二页
作者放弃时间:2024/8/30  20:17
问题描述:基本上全部报错,无法映射
回复

使用道具 举报

Lv.5 农夫

人气
17 点
金粒
132 粒
宝石
1 颗
爱心
0 颗
钻石
87 颗
贡献
0 点

石镐矿工勋章

 楼主| 发表于 2024-8-28 21:28:35 | 显示全部楼层
代码那个是只显示一格,还请见谅
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 需要先绑定手机号


Archiver|小黑屋| MCBBS纪念版 ( 新ICP备2024014954号-1|兵公网安备66010002000149号 )|隐私政策| 手机版

GMT+8, 2024-11-15 14:24 , Processed in 0.087899 second(s), 14 queries , Redis On.

"Minecraft"以及"我的世界"为美国微软公司的商标 本站与微软公司没有从属关系

© 2010-2024 MCBBS纪念版 版权所有 本站内原创内容版权属于其原创作者,除作者或版规特别声明外未经许可不得转载

返回顶部