AcesDephtPest 发表于 2024-8-26 01:58:16

ItemStack(序列化版)

本帖最后由 AcesDephtPest 于 2024-8-28 21:24 编辑


兼容版本:目前最高版本-1.17.1


介绍:这是一个可以序列化的ItemStack对象,基本上可以兼容,也给那些想把ItemStack序列化储存进文件的后来人一点经验吧
本人新手,代码中的许多错误无法发现,如果你有更好的建议,希望可以分享分享awa
这是基于1.17.1的基础上做的改动,所以高版本的那些属性不可能完全的
以后的想法:使用Class<?>来执行/判断是否存在的接口来实现全版本通用
如果可以,请看第二页,那里是测试代码,但坑定是无法正常运行的,现在进度:映射Class实现全版本通用,
如果你可以花点时间看看第二页,顺便给点评价,那真是太好了doge

public static class ItemStack implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    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 PotionType potionType = null; // 药水类型
    private boolean isSplash = false; // 是否为喷溅药水
    private String Variant = null; // 代表一桶蝾螈
    private List<Pattern> BannerMeta = null; // 旗帜的图案的列表
    private Location CompassMeta = null; // 代表能追踪指定位置的指南针
    private short Damageable = 0; // 代表有耐久度,可损耗的物品
    private Map<String, Integer> EnchantmentStorageMeta = new HashMap<>(); // 特定于专门存储附魔的物品,而非被附魔的物品. 附魔书 就是一个可存储附魔的物品的例子.
    private FireworkEffect FireworkEffectMeta = null; // 烟花效果
    private List<FireworkEffect> FireworkMeta = new ArrayList<>(); // 烟花火箭及其效果
    private List<NamespacedKey> KnowledgeBookMeta = new ArrayList<>(); //与知识之书有关的元数据
    private Color LeatherArmorMeta = null; // 下文中的"盔甲"可以是皮革靴子,外套,帽子,裤子任意一种,因为这个类代表了四种嘛
    private Color MapMetaColor = null; // 伸缩的地图
    private MapView MapMetaMapView = null; // 伸缩的地图
    private int Repairable = 0; //修复此物品所需的额外经验等级
    private OfflinePlayer SkullMetaOfflinePlayer = null; //头颅的主人
    private List<PotionEffect> SuspiciousStewMeta = new ArrayList<>(); //自定义药水效果的迷之炖菜
    private DyeColor TropicalFishBucketMetaBodyColor = null; //热带鱼桶
    private TropicalFish.Pattern TropicalFishBucketMetaPattern = null; //热带鱼桶
    private DyeColor TropicalFishBucketMetaPatternColor = null; // 热带鱼桶
    private String BookMetaAuthor = null; // 热带鱼桶
    private BookMeta.Generation 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 void getMeta(ItemMeta meta) {
      if (meta != null) {
            if (meta instanceof Damageable) this.Damageable = (short) ((Damageable) meta).getDamage();
            if (meta instanceof AxolotlBucketMeta) this.Variant = ((AxolotlBucketMeta) meta).getVariant().toString();
            if (meta instanceof BannerMeta) this.BannerMeta = ((BannerMeta) meta).getPatterns();
            if (meta instanceof CompassMeta && ((CompassMeta) meta).getLodestone() != null) this.CompassMeta = new Location(((CompassMeta) meta).getLodestone());
            if (meta instanceof EnchantmentStorageMeta) {
                this.EnchantmentStorageMeta = new HashMap<>();
                Map<Enchantment, Integer> list = ((EnchantmentStorageMeta) meta).getStoredEnchants();
                for (Map.Entry<Enchantment, Integer> entry : list.entrySet()) {
                  this.EnchantmentStorageMeta.put(entry.getKey().getKey().toString(), entry.getValue());
                }
            }
            if (meta instanceof FireworkEffectMeta) this.FireworkEffectMeta = ((FireworkEffectMeta) meta).getEffect();
            if (meta instanceof FireworkMeta) this.FireworkMeta = ((FireworkMeta) meta).getEffects();
            if (meta instanceof KnowledgeBookMeta) this.KnowledgeBookMeta = ((KnowledgeBookMeta) meta).getRecipes();
            if (meta instanceof LeatherArmorMeta) this.LeatherArmorMeta = ((LeatherArmorMeta) meta).getColor();
            if (meta instanceof MapMeta) {
                this.MapMetaColor = ((MapMeta) meta).getColor();
                this.MapMetaMapView = ((MapMeta) meta).getMapView();
            }
            if (meta instanceof Repairable) this.Repairable = ((Repairable) meta).getRepairCost();
            if (meta instanceof SkullMeta) this.SkullMetaOfflinePlayer = ((SkullMeta) meta).getOwningPlayer();
            if (meta instanceof SuspiciousStewMeta) this.SuspiciousStewMeta = ((SuspiciousStewMeta) meta).getCustomEffects();
            if (meta instanceof TropicalFishBucketMeta) {
                this.TropicalFishBucketMetaPattern = ((TropicalFishBucketMeta) meta).getPattern();
                this.TropicalFishBucketMetaBodyColor = ((TropicalFishBucketMeta) meta).getBodyColor();
                this.TropicalFishBucketMetaPatternColor = ((TropicalFishBucketMeta) meta).getPatternColor();
            }
            if (meta instanceof BookMeta) {
                this.BookMetaAuthor = ((BookMeta) meta).getAuthor();
                this.BookMetaGeneration = ((BookMeta) meta).getGeneration();
                this.BookMetaPages = ((BookMeta) meta).getPages();
                this.BookMetaTitle = ((BookMeta) meta).getTitle();
            }
            this.lore = Objects.requireNonNull(meta).hasLore() ? new ArrayList<>(Objects.requireNonNull(meta.getLore())) : null;
            this.displayName = meta.hasDisplayName() ? meta.getDisplayName() : null;
            if (this.type.equals(Material.POTION) || this.type.equals(Material.SPLASH_POTION) || this.type.equals(Material.LINGERING_POTION)) {
                PotionMeta potionMeta = (PotionMeta) meta;
                this.potionType = potionMeta.getBasePotionData().getType();
                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 (meta instanceof Damageable && this.Damageable > 0) ((Damageable) meta).setDamage(this.Damageable);
            if (meta instanceof PotionMeta && this.potionType != null) {
                if (this.type.equals(Material.POTION) || this.type.equals(Material.LINGERING_POTION) || this.type.equals(Material.SPLASH_POTION)) {
                  PotionData potionData = new PotionData(this.potionType,
                            !this.isSplash && this.potionType.isExtendable(),
                            this.isSplash && this.potionType.isUpgradeable());
                  ((PotionMeta) meta).setBasePotionData(potionData);
                }
            }
            if (meta instanceof AxolotlBucketMeta && this.Variant != null) {
                ((AxolotlBucketMeta) meta).setVariant(Axolotl.Variant.valueOf(this.Variant));
            }
            if (meta instanceof BannerMeta && this.BannerMeta != null) {
                ((BannerMeta) meta).setPatterns(this.BannerMeta);
            }
            if (meta instanceof CompassMeta && this.CompassMeta != null) {
                ((CompassMeta) meta).setLodestone(this.CompassMeta.toLocation());
            }
            if (meta instanceof EnchantmentStorageMeta && 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) ((EnchantmentStorageMeta) meta).addStoredEnchant(enchantment, entry.getValue(), true);
            }
            if (meta instanceof FireworkEffectMeta && this.FireworkEffectMeta != null) {
                ((FireworkEffectMeta) meta).setEffect(this.FireworkEffectMeta);
            }
            if (meta instanceof FireworkMeta && this.FireworkMeta != null) {
                ((FireworkMeta) meta).addEffects(this.FireworkMeta);
            }
            if (meta instanceof KnowledgeBookMeta && this.KnowledgeBookMeta != null) {
                ((KnowledgeBookMeta) meta).setRecipes(this.KnowledgeBookMeta);
            }
            if (meta instanceof LeatherArmorMeta && this.LeatherArmorMeta != null) {
                ((LeatherArmorMeta) meta).setColor(this.LeatherArmorMeta);
            }
            if (meta instanceof MapMeta) {
                if (this.MapMetaColor != null) ((MapMeta) meta).setColor(this.MapMetaColor);
                if (this.MapMetaMapView != null) ((MapMeta) meta).setMapView(this.MapMetaMapView);
            }
            if (meta instanceof Repairable && this.Repairable > 0) {
                ((Repairable) meta).setRepairCost(this.Repairable);
            }
            if (meta instanceof SkullMeta && this.SkullMetaOfflinePlayer != null) {
                ((SkullMeta) meta).setOwningPlayer(this.SkullMetaOfflinePlayer);
            }
            if (meta instanceof SuspiciousStewMeta && this.SuspiciousStewMeta != null) {
                for (PotionEffect data : this.SuspiciousStewMeta) ((SuspiciousStewMeta) meta).addCustomEffect(data,true);
            }
            if (meta instanceof TropicalFishBucketMeta) {
                if (this.TropicalFishBucketMetaBodyColor != null) ((TropicalFishBucketMeta) meta).setBodyColor(this.TropicalFishBucketMetaBodyColor);
                if (this.TropicalFishBucketMetaPattern != null) ((TropicalFishBucketMeta) meta).setPattern(this.TropicalFishBucketMetaPattern);
                if (this.TropicalFishBucketMetaPatternColor != null) ((TropicalFishBucketMeta) meta).setPatternColor(this.TropicalFishBucketMetaPatternColor);
            }
            if (meta instanceof BookMeta) {
                if (this.BookMetaAuthor != null) ((BookMeta) meta).setAuthor(this.BookMetaAuthor);
                if (this.BookMetaGeneration != null) ((BookMeta) meta).setGeneration(this.BookMetaGeneration);
                if (this.BookMetaPages != null) ((BookMeta) meta).setPages(this.BookMetaPages);
                if (this.BookMetaTitle != null) ((BookMeta) meta).setTitle(this.BookMetaTitle);
            }
      }
      return 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);
      }
    }
}





现在进度:
<blockquote>public static class ItemStack implements Serializable {


爱玩游戏的阿坤 发表于 2024-8-26 13:21:51

关于itemstack的各种属性可查看api:https://bukkit.windit.net/javadoc/org/bukkit/inventory/ItemStack.html

旗帜图案一般用 BannerMeta

以下是chatgpt给予的示例代码:
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BannerMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.BannerMeta.Pattern;
import org.bukkit.Color;

public class BannerItemExample {

    public static ItemStack createCustomBanner() {
      // 创建一个新的物品堆栈,这里我们使用白色旗帜(Banner)
      ItemStack banner = new ItemStack(Material.WHITE_BANNER);

      // 获取物品的 ItemMeta 对象
      BannerMeta bannerMeta = (BannerMeta) banner.getItemMeta();
      
      // 检查是否成功获取到 BannerMeta
      if (bannerMeta != null) {
            // 创建并添加自定义图案
            bannerMeta.addPattern(new Pattern(Color.RED, PatternType.STRIPE_TOP));
            bannerMeta.addPattern(new Pattern(Color.BLUE, PatternType.CIRCLE));

            // 将修改后的 ItemMeta 设置回物品堆栈
            banner.setItemMeta(bannerMeta);
      }

      return banner;
    }
}

代码解析
ItemStack:创建一个白色旗帜物品(Material.WHITE_BANNER)
BannerMeta:用于设置旗帜的元数据。
Pattern:定义旗帜上的图案。PatternType 是预定义的图案类型,比如 STRIPE_TOP 和 CIRCLE
addPattern:将图案添加到旗帜上

PatternType 类提供了多种图案类型,您可以根据需求选择不同的图案。
确保您使用的 Bukkit API 版本支持这些功能,因为 API 可能会在不同的版本中有所变化

AcesDephtPest 发表于 2024-8-26 23:14:13

爱玩游戏的阿坤 发表于 2024-8-26 13:21
关于itemstack的各种属性可查看api:https://bukkit.windit.net/javadoc/org/bukkit/inventory/ItemStack.ht ...

谢谢,可以了

AcesDephtPest 发表于 2024-8-27 14:17:08

爱玩游戏的阿坤 发表于 2024-8-26 13:21
关于itemstack的各种属性可查看api:https://bukkit.windit.net/javadoc/org/bukkit/inventory/ItemStack.ht ...

刚更新了代码,你觉得咋样awa

AcesDephtPest 发表于 2024-8-27 14:32:32

6,修好了: 没加判断 Damageable != 0

洞穴夜莺 发表于 2024-8-27 15:54:14

使用默认序列化逻辑的话,应该只需继承Serializable,writeObject/readObject不是必要的吧?

AcesDephtPest 发表于 2024-8-27 16:04:18

洞穴夜莺 发表于 2024-8-27 15:54
使用默认序列化逻辑的话,应该只需继承Serializable,writeObject/readObject不是必要的吧? ...

emmm,我试试

AcesDephtPest 发表于 2024-8-27 16:57:55

洞穴夜莺 发表于 2024-8-27 15:54
使用默认序列化逻辑的话,应该只需继承Serializable,writeObject/readObject不是必要的吧? ...

已修改,但感觉留空有更多的可能性(报错:开玩笑的)
页: [1]
查看完整版本: ItemStack(序列化版)