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 {
关于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 可能会在不同的版本中有所变化 爱玩游戏的阿坤 发表于 2024-8-26 13:21
关于itemstack的各种属性可查看api:https://bukkit.windit.net/javadoc/org/bukkit/inventory/ItemStack.ht ...
谢谢,可以了 爱玩游戏的阿坤 发表于 2024-8-26 13:21
关于itemstack的各种属性可查看api:https://bukkit.windit.net/javadoc/org/bukkit/inventory/ItemStack.ht ...
刚更新了代码,你觉得咋样awa 6,修好了: 没加判断 Damageable != 0 使用默认序列化逻辑的话,应该只需继承Serializable,writeObject/readObject不是必要的吧? 洞穴夜莺 发表于 2024-8-27 15:54
使用默认序列化逻辑的话,应该只需继承Serializable,writeObject/readObject不是必要的吧? ...
emmm,我试试 洞穴夜莺 发表于 2024-8-27 15:54
使用默认序列化逻辑的话,应该只需继承Serializable,writeObject/readObject不是必要的吧? ...
已修改,但感觉留空有更多的可能性(报错:开玩笑的)
页:
[1]