From 30c1affdc9296c1c04f2ac743817a6a1870e1fff Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Thu, 29 May 2025 18:47:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=97=A7=E7=89=88=E5=8F=91?= =?UTF-8?q?=E5=8C=85=E7=89=A9=E5=93=81tag=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/item/BukkitItemManager.java | 2 +- .../bukkit/item/LegacyItemWrapper.java | 54 ++++++++- .../bukkit/item/LegacyNetworkItemHandler.java | 110 ++++++++++++++++-- .../factory/ComponentItemFactory1_20_5.java | 7 +- .../factory/ComponentItemFactory1_21_5.java | 1 - .../item/factory/UniversalItemFactory.java | 70 ++++++----- .../item/listener/DebugStickListener.java | 4 +- .../plugin/network/BukkitNetworkManager.java | 1 - .../craftengine/core/item/AbstractItem.java | 9 +- .../craftengine/core/item/ComponentIds.java | 1 + .../craftengine/core/item/Item.java | 4 +- .../craftengine/core/item/ItemFactory.java | 4 +- .../core/item/NetworkItemHandler.java | 16 +-- .../recipe/CustomSmithingTransformRecipe.java | 2 +- .../core/util/AdventureHelper.java | 4 - .../craftengine/core/util/StringUtils.java | 28 +++++ gradle.properties | 4 +- 17 files changed, 252 insertions(+), 69 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/util/StringUtils.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index 4c6f37d7c..ad0671248 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -59,7 +59,7 @@ public class BukkitItemManager extends AbstractItemManager { this.itemEventListener = new ItemEventListener(plugin); this.debugStickListener = new DebugStickListener(plugin); this.armorEventListener = new ArmorEventListener(); - this.networkItemHandler = VersionHelper.isOrAbove1_20_5() ? new ModernNetworkItemHandler() : new LegacyNetworkItemHandler(this); + this.networkItemHandler = VersionHelper.isOrAbove1_20_5() ? new ModernNetworkItemHandler() : new LegacyNetworkItemHandler(); this.registerAllVanillaItems(); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyItemWrapper.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyItemWrapper.java index 154e121e5..188bfcdd6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyItemWrapper.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyItemWrapper.java @@ -1,9 +1,19 @@ package net.momirealms.craftengine.bukkit.item; import com.saicone.rtag.RtagItem; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.core.item.ItemWrapper; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.util.VersionHelper; +import net.momirealms.sparrow.nbt.NBT; +import net.momirealms.sparrow.nbt.Tag; import org.bukkit.inventory.ItemStack; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.util.Arrays; + public class LegacyItemWrapper implements ItemWrapper { private final RtagItem rtagItem; private int count; @@ -20,18 +30,50 @@ public class LegacyItemWrapper implements ItemWrapper { return itemStack; } - public boolean set(Object value, Object... path) { - return this.rtagItem.set(value, path); + public boolean setTag(Object value, Object... path) { + if (value instanceof Tag tag) { + try { + Object nmsTag = FastNMS.INSTANCE.method$NbtIo$fromBytes(NBT.toBytes(tag, !VersionHelper.isOrAbove1_20_3())); + return this.rtagItem.set(nmsTag, path); + } catch (IOException e) { + CraftEngine.instance().logger().warn("Failed to set NBT tag " + Arrays.toString(path), e); + return false; + } + } else { + return this.rtagItem.set(value, path); + } } public boolean add(Object value, Object... path) { - return this.rtagItem.add(value, path); + if (value instanceof Tag tag) { + try { + // Incompatible DFU version + // return this.rtagItem.add(Reflections.instance$SPARROW_NBT_OPS.convertTo(Reflections.instance$NBT_OPS, tag), path); + Object nmsTag = FastNMS.INSTANCE.method$NbtIo$fromBytes(NBT.toBytes(tag, !VersionHelper.isOrAbove1_20_3())); + return this.rtagItem.add(nmsTag, path); + } catch (IOException e) { + CraftEngine.instance().logger().warn("Failed to add NBT tag " + Arrays.toString(path), e); + return false; + } + } else { + return this.rtagItem.add(value, path); + } } - public V get(Object... path) { + public V getJavaTag(Object... path) { return this.rtagItem.get(path); } + public Tag getNBTTag(Object... path) { + Object tag = getExactTag(path); + try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(FastNMS.INSTANCE.method$NbtIo$toBytes(tag)))) { + return NBT.readUnnamedTag(dis, !VersionHelper.isOrAbove1_20_3()); + } catch (IOException e) { + CraftEngine.instance().logger().warn("Failed to read NBT tag " + Arrays.toString(path), e); + return null; + } + } + public int count() { return this.count; } @@ -41,8 +83,8 @@ public class LegacyItemWrapper implements ItemWrapper { this.count = amount; } - public V getExact(Object... path) { - return this.rtagItem.get(path); + public Object getExactTag(Object... path) { + return this.rtagItem.getExact(path); } public boolean remove(Object... path) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java index b09bf7b5c..37081736d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java @@ -1,26 +1,122 @@ package net.momirealms.craftengine.bukkit.item; +import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.core.item.CustomItem; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.config.Config; +import net.momirealms.craftengine.core.util.AdventureHelper; +import net.momirealms.sparrow.nbt.CompoundTag; +import net.momirealms.sparrow.nbt.ListTag; +import net.momirealms.sparrow.nbt.StringTag; +import net.momirealms.sparrow.nbt.Tag; import org.bukkit.inventory.ItemStack; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.function.BiConsumer; public class LegacyNetworkItemHandler implements NetworkItemHandler { - private final BukkitItemManager itemManager; - public LegacyNetworkItemHandler(BukkitItemManager itemManager) { - this.itemManager = itemManager; + @Override + public Optional> c2s(Item wrapped, ItemBuildContext context) { + if (!wrapped.hasTag(NETWORK_ITEM_TAG)) return Optional.empty(); + CompoundTag networkData = (CompoundTag) wrapped.getNBTTag(NETWORK_ITEM_TAG); + if (networkData == null) return Optional.empty(); + wrapped.removeTag(NETWORK_ITEM_TAG); + for (Map.Entry entry : networkData.entrySet()) { + if (entry.getValue() instanceof CompoundTag tag) { + NetworkItemHandler.apply(entry.getKey(), tag, wrapped); + } + } + return Optional.of(wrapped); } @Override - public Optional> c2s(Item itemStack, ItemBuildContext context) { + public Optional> s2c(Item wrapped, ItemBuildContext context) { + Optional> optionalCustomItem = wrapped.getCustomItem(); + if (optionalCustomItem.isEmpty()) { + if (!Config.interceptItem()) return Optional.empty(); + return new OtherItem(wrapped).process(); + } return Optional.empty(); } - @Override - public Optional> s2c(Item itemStack, ItemBuildContext context) { - return Optional.empty(); + public static boolean processCustomName(Item item, BiConsumer callback) { + Optional optionalCustomName = item.customNameJson(); + if (optionalCustomName.isPresent()) { + String line = optionalCustomName.get(); + Map tokens = CraftEngine.instance().fontManager().matchTags(line); + if (!tokens.isEmpty()) { + item.customNameJson(AdventureHelper.componentToJson(AdventureHelper.replaceText(AdventureHelper.jsonToComponent(line), tokens))); + callback.accept("display.Name", NetworkItemHandler.pack(Operation.ADD, new StringTag(line))); + return true; + } + } + return false; + } + + private static boolean processLore(Item item, BiConsumer callback) { + Optional> optionalLore = item.loreJson(); + if (optionalLore.isPresent()) { + boolean changed = false; + List lore = optionalLore.get(); + List newLore = new ArrayList<>(lore.size()); + for (String line : lore) { + Map tokens = CraftEngine.instance().fontManager().matchTags(line); + if (tokens.isEmpty()) { + newLore.add(line); + } else { + newLore.add(AdventureHelper.componentToJson(AdventureHelper.replaceText(AdventureHelper.jsonToComponent(line), tokens))); + changed = true; + } + } + if (changed) { + item.loreJson(newLore); + ListTag listTag = new ListTag(); + for (String line : lore) { + listTag.add(new StringTag(line)); + } + callback.accept("display.Lore", NetworkItemHandler.pack(Operation.ADD, listTag)); + return true; + } + } + return false; + } + + static class OtherItem { + private final Item item; + private boolean globalChanged = false; + private CompoundTag networkTag; + + public OtherItem(Item item) { + this.item = item; + } + + public Optional> process() { + if (processLore(this.item, (s, c) -> networkTag().put(s, c))) { + this.globalChanged = true; + } + if (processCustomName(this.item, (s, c) -> networkTag().put(s, c))) { + this.globalChanged = true; + } + if (this.globalChanged) { + this.item.setTag(this.networkTag, NETWORK_ITEM_TAG); + return Optional.of(this.item); + } else { + return Optional.empty(); + } + } + + public CompoundTag networkTag() { + if (this.networkTag == null) { + this.networkTag = new CompoundTag(); + } + return this.networkTag; + } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java index b039709a6..f79b48f36 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java @@ -39,7 +39,12 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory { @Override protected void setTag(LegacyItemWrapper item, Object value, Object... path) { - item.set(value, path); + item.setTag(value, path); } @Override - protected Object getTag(LegacyItemWrapper item, Object... path) { - return item.get(path); + protected Object getJavaTag(LegacyItemWrapper item, Object... path) { + return item.getJavaTag(path); + } + + @Override + protected Tag getNBTTag(LegacyItemWrapper item, Object... path) { + return item.getNBTTag(path); } @Override @@ -53,20 +59,20 @@ public class UniversalItemFactory extends BukkitItemFactory { @Override protected Optional customId(LegacyItemWrapper item) { - Object id = item.get(IdModifier.CRAFT_ENGINE_ID); + Object id = item.getJavaTag(IdModifier.CRAFT_ENGINE_ID); if (id == null) return Optional.empty(); return Optional.of(Key.of(id.toString())); } @Override protected void customId(LegacyItemWrapper item, Key id) { - item.set(id.toString(), IdModifier.CRAFT_ENGINE_ID); + item.setTag(id.toString(), IdModifier.CRAFT_ENGINE_ID); } @Override protected void customNameJson(LegacyItemWrapper item, String json) { if (json != null) { - item.set(json, "display", "Name"); + item.setTag(json, "display", "Name"); } else { item.remove("display", "Name"); } @@ -75,7 +81,7 @@ public class UniversalItemFactory extends BukkitItemFactory { @Override protected Optional customNameJson(LegacyItemWrapper item) { if (!item.hasTag("display", "Name")) return Optional.empty(); - return Optional.of(item.get("display", "Name")); + return Optional.of(item.getJavaTag("display", "Name")); } @Override @@ -93,14 +99,14 @@ public class UniversalItemFactory extends BukkitItemFactory { if (data == null) { item.remove("CustomModelData"); } else { - item.set(data, "CustomModelData"); + item.setTag(data, "CustomModelData"); } } @Override protected Optional customModelData(LegacyItemWrapper item) { if (!item.hasTag("CustomModelData")) return Optional.empty(); - return Optional.of(item.get("CustomModelData")); + return Optional.of(item.getJavaTag("CustomModelData")); } @Override @@ -108,8 +114,8 @@ public class UniversalItemFactory extends BukkitItemFactory { if (skullData == null) { item.remove("SkullOwner"); } else { - item.set(UUID.nameUUIDFromBytes(SkullUtils.identifierFromBase64(skullData).getBytes(StandardCharsets.UTF_8)), "SkullOwner", "Id"); - item.set( + item.setTag(UUID.nameUUIDFromBytes(SkullUtils.identifierFromBase64(skullData).getBytes(StandardCharsets.UTF_8)), "SkullOwner", "Id"); + item.setTag( List.of(Map.of("Value", skullData)), "SkullOwner", "Properties", "textures" ); @@ -119,7 +125,7 @@ public class UniversalItemFactory extends BukkitItemFactory { @Override protected Optional> loreJson(LegacyItemWrapper item) { if (!item.hasTag("display", "Lore")) return Optional.empty(); - return Optional.of(item.get("display", "Lore")); + return Optional.of(item.getJavaTag("display", "Lore")); } @Override @@ -127,35 +133,35 @@ public class UniversalItemFactory extends BukkitItemFactory { if (lore == null || lore.isEmpty()) { item.remove("display", "Lore"); } else { - item.set(lore, "display", "Lore"); + item.setTag(lore, "display", "Lore"); } } @Override protected boolean unbreakable(LegacyItemWrapper item) { - return Optional.ofNullable((Boolean) item.get("Unbreakable")).orElse(false); + return Optional.ofNullable((Boolean) item.getJavaTag("Unbreakable")).orElse(false); } @Override protected void unbreakable(LegacyItemWrapper item, boolean unbreakable) { - item.set(unbreakable, "Unbreakable"); + item.setTag(unbreakable, "Unbreakable"); } @Override protected Optional damage(LegacyItemWrapper item) { if (!item.hasTag("Damage")) return Optional.empty(); - return Optional.of(item.get("Damage")); + return Optional.of(item.getJavaTag("Damage")); } @Override protected void damage(LegacyItemWrapper item, Integer damage) { - item.set(damage, "Damage"); + item.setTag(damage, "Damage"); } @Override protected Optional dyedColor(LegacyItemWrapper item) { if (!item.hasTag("display", "color")) return Optional.empty(); - return Optional.of(item.get("display", "color")); + return Optional.of(item.getJavaTag("display", "color")); } @Override @@ -163,7 +169,7 @@ public class UniversalItemFactory extends BukkitItemFactory { if (color == null) { item.remove("display", "color"); } else { - item.set(color, "display", "color"); + item.setTag(color, "display", "color"); } } @@ -187,7 +193,7 @@ public class UniversalItemFactory extends BukkitItemFactory { for (Enchantment enchantment : enchantments) { tags.add((Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level()))); } - item.set(tags, "Enchantments"); + item.setTag(tags, "Enchantments"); } @Override @@ -200,12 +206,12 @@ public class UniversalItemFactory extends BukkitItemFactory { for (Enchantment enchantment : enchantments) { tags.add((Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level()))); } - item.set(tags, "StoredEnchantments"); + item.setTag(tags, "StoredEnchantments"); } @Override protected void addEnchantment(LegacyItemWrapper item, Enchantment enchantment) { - Object enchantments = item.getExact("Enchantments"); + Object enchantments = item.getExactTag("Enchantments"); if (enchantments != null) { for (Object enchant : TagList.getValue(enchantments)) { if (TagBase.getValue(TagCompound.get(enchant, "id")).equals(enchant.toString())) { @@ -215,13 +221,13 @@ public class UniversalItemFactory extends BukkitItemFactory { } item.add(Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level()), "Enchantments"); } else { - item.set(List.of(Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level())), "Enchantments"); + item.setTag(List.of(Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level())), "Enchantments"); } } @Override protected void addStoredEnchantment(LegacyItemWrapper item, Enchantment enchantment) { - Object enchantments = item.getExact("StoredEnchantments"); + Object enchantments = item.getExactTag("StoredEnchantments"); if (enchantments != null) { for (Object enchant : TagList.getValue(enchantments)) { if (TagBase.getValue(TagCompound.get(enchant, "id")).equals(enchant.toString())) { @@ -231,7 +237,7 @@ public class UniversalItemFactory extends BukkitItemFactory { } item.add(Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level()), "StoredEnchantments"); } else { - item.set(List.of(Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level())), "StoredEnchantments"); + item.setTag(List.of(Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level())), "StoredEnchantments"); } } @@ -254,7 +260,7 @@ public class UniversalItemFactory extends BukkitItemFactory { ItemFlag itemFlag = ItemFlag.valueOf(flag); f = f | 1 << itemFlag.ordinal(); } - item.set(f, "HideFlags"); + item.setTag(f, "HideFlags"); } @Override @@ -269,13 +275,13 @@ public class UniversalItemFactory extends BukkitItemFactory { @Override protected void repairCost(LegacyItemWrapper item, Integer data) { - item.set(data, "RepairCost"); + item.setTag(data, "RepairCost"); } @Override protected Optional repairCost(LegacyItemWrapper item) { if (!item.hasTag("RepairCost")) return Optional.empty(); - return Optional.of(item.get("RepairCost")); + return Optional.of(item.getJavaTag("RepairCost")); } @Override @@ -284,14 +290,14 @@ public class UniversalItemFactory extends BukkitItemFactory { item.remove("Trim"); return; } - item.set(trim.material(), "Trim", "material"); - item.set(trim.pattern(), "Trim", "pattern"); + item.setTag(trim.material(), "Trim", "material"); + item.setTag(trim.pattern(), "Trim", "pattern"); } @Override protected Optional trim(LegacyItemWrapper item) { - String material = item.get("Trim", "material"); - String pattern = item.get("Trim", "pattern"); + String material = item.getJavaTag("Trim", "material"); + String pattern = item.getJavaTag("Trim", "pattern"); if (material == null || pattern == null) return Optional.empty(); return Optional.of(new Trim(material, pattern)); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java index 19a70df37..8cd11ae9c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java @@ -74,7 +74,7 @@ public class DebugStickListener implements Listener { player.sendPacket(systemChatPacket, false); } else { LegacyItemWrapper wrapped = new LegacyItemWrapper(new RtagItem(itemInHand), itemInHand.getAmount()); - Object storedData = wrapped.get("craftengine:debug_stick_state"); + Object storedData = wrapped.getJavaTag("craftengine:debug_stick_state"); if (storedData == null) storedData = new HashMap<>(); if (storedData instanceof Map map) { Map data = MiscUtils.castToMap(map, false); @@ -96,7 +96,7 @@ public class DebugStickListener implements Listener { } else { currentProperty = getRelative(properties, currentProperty, player.isSecondaryUseActive()); data.put(blockId, currentProperty.name()); - wrapped.set(data, "craftengine:debug_stick_state"); + wrapped.setTag(data, "craftengine:debug_stick_state"); wrapped.load(); Object systemChatPacket = Reflections.constructor$ClientboundSystemChatPacket.newInstance( ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.select") diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java index f4e3a6e22..11db3f193 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java @@ -3,7 +3,6 @@ package net.momirealms.craftengine.bukkit.plugin.network; import com.google.gson.JsonObject; import io.netty.buffer.ByteBuf; import io.netty.channel.*; -import io.netty.handler.codec.MessageToMessageCodec; import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.util.internal.logging.InternalLogger; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java index 51d20ad81..48e4b70af 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java @@ -311,8 +311,13 @@ public class AbstractItem, I> implements Item { } @Override - public Object getTag(Object... path) { - return this.factory.getTag(this.item, path); + public Object getJavaTag(Object... path) { + return this.factory.getJavaTag(this.item, path); + } + + @Override + public Tag getNBTTag(Object... path) { + return this.factory.getNBTTag(this.item, path); } @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ComponentIds.java b/core/src/main/java/net/momirealms/craftengine/core/item/ComponentIds.java index 629439c97..9cfa7771f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ComponentIds.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ComponentIds.java @@ -5,5 +5,6 @@ public final class ComponentIds { public static final String ITEM_NAME = "minecraft:item_name"; public static final String CUSTOM_NAME = "minecraft:custom_name"; + public static final String ENCHANTMENTS = "minecraft:enchantments"; public static final String LORE = "minecraft:lore"; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/Item.java b/core/src/main/java/net/momirealms/craftengine/core/item/Item.java index 97770fd37..26f3f39e8 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/Item.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/Item.java @@ -129,7 +129,9 @@ public interface Item { Item itemFlags(List flags); - Object getTag(Object... path); + Object getJavaTag(Object... path); + + Tag getNBTTag(Object... path); Item setTag(Object value, Object... path); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java index 04777f90e..b27853e93 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java @@ -30,7 +30,9 @@ public abstract class ItemFactory, I> { protected abstract W wrapInternal(I item); - protected abstract Object getTag(W item, Object... path); + protected abstract Object getJavaTag(W item, Object... path); + + protected abstract Tag getNBTTag(W item, Object... path); protected abstract void setTag(W item, Object value, Object... path); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/NetworkItemHandler.java b/core/src/main/java/net/momirealms/craftengine/core/item/NetworkItemHandler.java index c6d9a0138..263f74abf 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/NetworkItemHandler.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/NetworkItemHandler.java @@ -1,6 +1,8 @@ package net.momirealms.craftengine.core.item; +import net.momirealms.craftengine.core.util.StringUtils; import net.momirealms.craftengine.core.util.TriConsumer; +import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.sparrow.nbt.ByteTag; import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.Tag; @@ -31,25 +33,25 @@ public interface NetworkItemHandler { return new CompoundTag(Map.of(NETWORK_OPERATION, operation.tag())); } - static void apply(String componentType, CompoundTag networkData, Item item) { + static void apply(String tagPath, CompoundTag networkData, Item item) { byte index = networkData.getByte(NETWORK_OPERATION); Operation operation = BY_INDEX[index]; - operation.consumer.accept(item, componentType, operation == Operation.ADD ? networkData.get(NETWORK_VALUE) : null); + operation.consumer.accept(item, tagPath, operation == Operation.ADD ? networkData.get(NETWORK_VALUE) : null); } enum Operation { - ADD(0, Item::setNBTComponent), - REMOVE(1, (i, s, t) -> i.removeComponent(s)), - RESET(2, (i, s, t) -> i.resetComponent(s)); + ADD(0, Item::setNBTComponent, (i, s, t) -> i.setTag(t, (Object[]) StringUtils.splitByDot(s))), + REMOVE(1, (i, s, t) -> i.removeComponent(s), (i, s, t) -> i.removeTag((Object[]) StringUtils.splitByDot(s))), + RESET(2, (i, s, t) -> i.resetComponent(s), (i, s, t) -> i.removeTag((Object[]) StringUtils.splitByDot(s))); private final int id; private final ByteTag tag; private final TriConsumer, String, Tag> consumer; - Operation(int id, TriConsumer, String, Tag> consumer) { + Operation(int id, TriConsumer, String, Tag> componentConsumer, TriConsumer, String, Tag> nbtConsumer) { this.id = id; this.tag = new ByteTag((byte) id); - this.consumer = consumer; + this.consumer = VersionHelper.isOrAbove1_20_5() ? componentConsumer : nbtConsumer; } public int id() { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java index ce2b96cd1..2a8ee7318 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java @@ -256,7 +256,7 @@ public class CustomSmithingTransformRecipe implements Recipe { @Override public void accept(Item item1, Item item2, Item item3) { for (String[] tag : this.tags) { - Object tagObj = item1.getTag((Object[]) tag); + Object tagObj = item1.getJavaTag((Object[]) tag); if (tagObj != null) { item3.setTag(tagObj, (Object[]) tag); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java b/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java index a5d21f27d..51bcb5f9e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java @@ -11,10 +11,6 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.json.JSONOptions; import net.kyori.adventure.text.serializer.json.legacyimpl.NBTLegacyHoverEventSerializer; -import net.momirealms.craftengine.core.item.Item; -import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.Tag; import net.momirealms.sparrow.nbt.serializer.NBTComponentSerializer; import net.momirealms.sparrow.nbt.serializer.NBTSerializerOptions; diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/StringUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/StringUtils.java new file mode 100644 index 000000000..a0cbe3adb --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/util/StringUtils.java @@ -0,0 +1,28 @@ +package net.momirealms.craftengine.core.util; + +public final class StringUtils { + private StringUtils() {} + + public static String[] splitByDot(String s) { + if (s == null || s.isEmpty()) { + return new String[0]; + } + int dotCount = 0; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '.') { + dotCount++; + } + } + String[] result = new String[dotCount + 1]; + int start = 0; + int index = 0; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '.') { + result[index++] = s.substring(start, i); + start = i + 1; + } + } + result[index] = s.substring(start); + return result; + } +} diff --git a/gradle.properties b/gradle.properties index d38f0bd12..750471733 100644 --- a/gradle.properties +++ b/gradle.properties @@ -39,7 +39,7 @@ geantyref_version=1.3.16 zstd_version=1.5.7-2 commons_io_version=2.18.0 commons_imaging_version=1.0.0-alpha6 -sparrow_nbt_version=0.8.3 +sparrow_nbt_version=0.8.4 sparrow_util_version=0.47 fastutil_version=8.5.15 netty_version=4.1.121.Final @@ -50,7 +50,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.17 -nms_helper_version=0.66.4 +nms_helper_version=0.66.5 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23