diff --git a/bukkit/build.gradle.kts b/bukkit/build.gradle.kts index 75e8293ea..db41b3d52 100644 --- a/bukkit/build.gradle.kts +++ b/bukkit/build.gradle.kts @@ -5,8 +5,9 @@ plugins { repositories { maven("https://jitpack.io/") - maven("https://repo.papermc.io/repository/maven-public/") maven("https://repo.momirealms.net/releases/") + maven("https://libraries.minecraft.net/") + maven("https://repo.papermc.io/repository/maven-public/") mavenCentral() } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java index fc4745a63..3a8fc1a34 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java @@ -151,7 +151,7 @@ public class BukkitFontManager extends AbstractFontManager implements Listener { EmojiComponentProcessResult replaceProcessResult = replaceComponentEmoji(itemName, plugin.adapt(player), renameText); if (replaceProcessResult.changed()) { Item wrapped = this.plugin.itemManager().wrap(result); - wrapped.customName(AdventureHelper.componentToJson(replaceProcessResult.newText())); + wrapped.customNameJson(AdventureHelper.componentToJson(replaceProcessResult.newText())); event.setResult(wrapped.load()); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java index 1ffb12708..765d093cd 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java @@ -1,26 +1,31 @@ package net.momirealms.craftengine.bukkit.item; import com.google.gson.JsonElement; -import com.saicone.rtag.RtagItem; -import com.saicone.rtag.data.ComponentType; -import com.saicone.rtag.tag.TagBase; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.core.item.ItemWrapper; import net.momirealms.craftengine.core.util.Key; +import net.momirealms.sparrow.nbt.Tag; import org.bukkit.inventory.ItemStack; -@SuppressWarnings("UnstableApiUsage") +import java.util.Optional; + public class ComponentItemWrapper implements ItemWrapper { private final ItemStack item; + private final Object handle; public ComponentItemWrapper(final ItemStack item) { this.item = FastNMS.INSTANCE.ensureCraftItemStack(item); + this.handle = FastNMS.INSTANCE.field$CraftItemStack$handle(this.item); } public ComponentItemWrapper(final ItemStack item, int count) { this.item = FastNMS.INSTANCE.ensureCraftItemStack(item); this.item.setAmount(count); + this.handle = FastNMS.INSTANCE.field$CraftItemStack$handle(this.item); } public void removeComponent(Object type) { @@ -34,31 +39,86 @@ public class ComponentItemWrapper implements ItemWrapper { public void setComponent(Object type, final Object value) { if (value instanceof JsonElement jsonElement) { setJsonComponent(type, jsonElement); - } else if (TagBase.isTag(value)) { + } else if (Reflections.clazz$Tag.isInstance(value)) { setNBTComponent(type, value); + } else if (value instanceof Tag tag) { + setSparrowNBTComponent(type, tag); } else { setJavaComponent(type, value); } } - public Object getComponent(Object type) { + public Object getComponentExact(Object type) { return FastNMS.INSTANCE.getComponent(getLiteralObject(), ensureDataComponentType(type)); } + public Optional getJavaComponent(Object type) { + return getComponentInternal(type, Reflections.instance$JAVA_OPS); + } + + public Optional getJsonComponent(Object type) { + return getComponentInternal(type, Reflections.instance$JSON_OPS); + } + + public Optional getNBTComponent(Object type) { + return getComponentInternal(type, Reflections.instance$NBT_OPS); + } + + public Optional getSparrowNBTComponent(Object type) { + return getComponentInternal(type, Reflections.instance$SPARROW_NBT_OPS); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private Optional getComponentInternal(Object type, DynamicOps ops) { + Object componentType = ensureDataComponentType(type); + Codec codec = FastNMS.INSTANCE.method$DataComponentType$codec(componentType); + try { + Object componentData = FastNMS.INSTANCE.getComponent(getLiteralObject(), componentType); + if (componentData == null) return Optional.empty(); + DataResult result = codec.encodeStart(ops, componentData); + return (Optional) result.result(); + } catch (Throwable t) { + throw new RuntimeException("Cannot read component " + type.toString(), t); + } + } + public boolean hasComponent(Object type) { return FastNMS.INSTANCE.hasComponent(getLiteralObject(), ensureDataComponentType(type)); } + public void setComponentExact(Object type, final Object value) { + FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), value); + } + public void setJavaComponent(Object type, Object value) { - ComponentType.parseJava(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), it)); + setComponentInternal(type, Reflections.instance$JAVA_OPS, value); } public void setJsonComponent(Object type, JsonElement value) { - ComponentType.parseJson(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), it)); + setComponentInternal(type, Reflections.instance$JSON_OPS, value); } public void setNBTComponent(Object type, Object value) { - ComponentType.parseNbt(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), it)); + setComponentInternal(type, Reflections.instance$NBT_OPS, value); + } + + public void setSparrowNBTComponent(Object type, Tag value) { + setComponentInternal(type, Reflections.instance$SPARROW_NBT_OPS, value); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private void setComponentInternal(Object type, DynamicOps ops, Object value) { + Object componentType = ensureDataComponentType(type); + Codec codec = FastNMS.INSTANCE.method$DataComponentType$codec(componentType); + try { + DataResult result = codec.parse(ops, value); + if (result.isError()) { + throw new IllegalArgumentException(result.toString()); + } + result.result().ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), componentType, it)); + } catch (Throwable t) { + throw new RuntimeException("Cannot parse component " + type.toString(), t); + } } private Object ensureDataComponentType(Object type) { @@ -89,7 +149,7 @@ public class ComponentItemWrapper implements ItemWrapper { @Override public Object getLiteralObject() { - return FastNMS.INSTANCE.field$CraftItemStack$handle(this.item); + return this.handle; } @Override 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 8e7a1d159..cf5f55199 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,17 +1,11 @@ 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.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.util.AdventureHelper; import org.bukkit.inventory.ItemStack; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import java.util.Optional; public class LegacyNetworkItemHandler implements NetworkItemHandler { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java index 8606b48a6..1365980c2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java @@ -1,6 +1,5 @@ package net.momirealms.craftengine.bukkit.item.factory; -import com.google.gson.JsonElement; import com.saicone.rtag.item.ItemTagStream; import net.momirealms.craftengine.bukkit.util.ItemTags; import net.momirealms.craftengine.bukkit.util.Reflections; @@ -11,7 +10,6 @@ import net.momirealms.craftengine.core.item.JukeboxPlayable; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.Key; import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.Nullable; import java.util.Objects; import java.util.Optional; @@ -89,16 +87,6 @@ public abstract class BukkitItemFactory> extend } } - @Override - protected JsonElement encodeJson(Object type, Object component) { - throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); - } - - @Override - public Object encodeJava(Object componentType, @Nullable Object component) { - throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); - } - @Override protected void resetComponent(W item, Object type) { throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); @@ -110,7 +98,7 @@ public abstract class BukkitItemFactory> extend } @Override - protected Object getComponent(W item, Object type) { + protected Object getExactComponent(W item, Object type) { throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); } 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 9261ae98d..ea22561b0 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 @@ -1,8 +1,6 @@ package net.momirealms.craftengine.bukkit.item.factory; import com.google.gson.JsonElement; -import com.saicone.rtag.data.ComponentType; -import com.saicone.rtag.item.ItemObject; import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper; import net.momirealms.craftengine.bukkit.item.ComponentTypes; import net.momirealms.craftengine.bukkit.nms.FastNMS; @@ -11,15 +9,14 @@ import net.momirealms.craftengine.core.item.Enchantment; import net.momirealms.craftengine.core.item.Trim; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.Key; +import net.momirealms.sparrow.nbt.Tag; import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; -@SuppressWarnings("UnstableApiUsage") public class ComponentItemFactory1_20_5 extends BukkitItemFactory { public ComponentItemFactory1_20_5(CraftEngine plugin) { @@ -82,8 +79,23 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory customModelData(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.CUSTOM_MODEL_DATA)) return Optional.empty(); - return Optional.ofNullable( - (Integer) ComponentType.encodeJava( - ComponentTypes.CUSTOM_MODEL_DATA, - item.getComponent(ComponentTypes.CUSTOM_MODEL_DATA) - ).orElse(null)); + return item.getJavaComponent(ComponentTypes.CUSTOM_MODEL_DATA); } @Override - protected void customName(ComponentItemWrapper item, String json) { + protected void customNameJson(ComponentItemWrapper item, String json) { if (json == null) { item.resetComponent(ComponentTypes.CUSTOM_NAME); } else { @@ -135,18 +132,12 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory customName(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.CUSTOM_NAME)) return Optional.empty(); - return Optional.ofNullable( - (String) ComponentType.encodeJava( - ComponentTypes.CUSTOM_NAME, - item.getComponent(ComponentTypes.CUSTOM_NAME) - ).orElse(null) - ); + protected Optional customNameJson(ComponentItemWrapper item) { + return item.getJavaComponent(ComponentTypes.CUSTOM_NAME); } @Override - protected void itemName(ComponentItemWrapper item, String json) { + protected void itemNameJson(ComponentItemWrapper item, String json) { if (json == null) { item.resetComponent(ComponentTypes.ITEM_NAME); } else { @@ -155,14 +146,8 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory itemName(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.ITEM_NAME)) return Optional.empty(); - return Optional.ofNullable( - (String) ComponentType.encodeJava( - ComponentTypes.ITEM_NAME, - item.getComponent(ComponentTypes.ITEM_NAME) - ).orElse(null) - ); + protected Optional itemNameJson(ComponentItemWrapper item) { + return item.getJavaComponent(ComponentTypes.ITEM_NAME); } @Override @@ -175,20 +160,13 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory> lore(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.LORE)) return Optional.empty(); - return Optional.ofNullable( - (List) ComponentType.encodeJava( - ComponentTypes.LORE, - item.getComponent(ComponentTypes.LORE) - ).orElse(null) - ); + protected Optional> loreJson(ComponentItemWrapper item) { + return item.getJavaComponent(ComponentTypes.LORE); } @Override - protected void lore(ComponentItemWrapper item, List lore) { + protected void loreJson(ComponentItemWrapper item, List lore) { if (lore == null || lore.isEmpty()) { item.resetComponent(ComponentTypes.LORE); } else { @@ -212,7 +190,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory glint(ComponentItemWrapper item) { - return Optional.ofNullable((Boolean) item.getComponent(ComponentTypes.ENCHANTMENT_GLINT_OVERRIDE)); + return Optional.ofNullable((Boolean) item.getComponentExact(ComponentTypes.ENCHANTMENT_GLINT_OVERRIDE)); } @Override @@ -226,13 +204,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory damage(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.DAMAGE)) return Optional.empty(); - return Optional.ofNullable( - (Integer) ComponentType.encodeJava( - ComponentTypes.DAMAGE, - item.getComponent(ComponentTypes.DAMAGE) - ).orElse(null) - ); + return item.getJavaComponent(ComponentTypes.DAMAGE); } @Override @@ -247,10 +219,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory dyedColor(ComponentItemWrapper item) { if (!item.hasComponent(ComponentTypes.DYED_COLOR)) return Optional.empty(); - Object javaObj = ComponentType.encodeJava( - ComponentTypes.DYED_COLOR, - item.getComponent(ComponentTypes.DYED_COLOR) - ).orElse(null); + Object javaObj = getJavaComponent(item, ComponentTypes.DYED_COLOR); if (javaObj instanceof Integer integer) { return Optional.of(integer); } else if (javaObj instanceof Map map) { @@ -269,14 +238,9 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory maxDamage(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.MAX_DAMAGE)) return Optional.of((int) item.getItem().getType().getMaxDurability()); - return Optional.ofNullable( - (Integer) ComponentType.encodeJava( - ComponentTypes.MAX_DAMAGE, - item.getComponent(ComponentTypes.MAX_DAMAGE) - ).orElse(null) - ); + protected int maxDamage(ComponentItemWrapper item) { + Optional damage = item.getJavaComponent(ComponentTypes.MAX_DAMAGE); + return damage.orElseGet(() -> (int) item.getItem().getType().getMaxDurability()); } @Override @@ -290,7 +254,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory getEnchantment(ComponentItemWrapper item, Key key) { - Object enchant = item.getComponent(ComponentTypes.ENCHANTMENTS); + Object enchant = item.getComponentExact(ComponentTypes.ENCHANTMENTS); try { Map map = EnchantmentUtils.toMap(enchant); Integer level = map.get(key.toString()); @@ -330,7 +294,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory map = EnchantmentUtils.toMap(enchant); map.put(enchantment.id().toString(), enchantment.level()); @@ -342,7 +306,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory map = EnchantmentUtils.toMap(enchant); map.put(enchantment.id().toString(), enchantment.level()); @@ -359,9 +323,8 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory stackSize = item.getJavaComponent(ComponentTypes.MAX_STACK_SIZE); + return stackSize.orElseGet(() -> item.getItem().getType().getMaxStackSize()); } @Override @@ -384,8 +347,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory repairCost(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.REPAIR_COST)) return Optional.empty(); - return Optional.ofNullable((Integer) ComponentType.encodeJava(ComponentTypes.REPAIR_COST, item.getComponent(ComponentTypes.REPAIR_COST)).orElse(null)); + return item.getJavaComponent(ComponentTypes.REPAIR_COST); } @Override @@ -402,8 +364,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory trim(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.TRIM)) return Optional.empty(); - Optional trim = ComponentType.encodeJava(ComponentTypes.TRIM, item.getComponent(ComponentTypes.TRIM)); + Optional trim = item.getJavaComponent(ComponentTypes.TRIM); if (trim.isEmpty()) { return Optional.empty(); } @@ -418,7 +379,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory jukeboxSong(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.JUKEBOX_PLAYABLE)) return Optional.empty(); - @SuppressWarnings("unchecked") - Map map = (Map) ComponentType.encodeJava( - ComponentTypes.JUKEBOX_PLAYABLE, - item.getComponent(ComponentTypes.JUKEBOX_PLAYABLE) - ).orElse(null); - if (map == null) return Optional.empty(); - return Optional.of(new JukeboxPlayable((String) map.get("song"), (boolean) map.getOrDefault("show_in_tooltip", true))); + Optional> map = item.getJavaComponent(ComponentTypes.JUKEBOX_PLAYABLE); + return map.map(song -> new JukeboxPlayable( + (String) song.get("song"), + (boolean) song.getOrDefault("show_in_tooltip", true)) + ); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_2.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_2.java index 3f05e1c44..13f9be33f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_2.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_2.java @@ -1,6 +1,5 @@ package net.momirealms.craftengine.bukkit.item.factory; -import com.saicone.rtag.data.ComponentType; import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper; import net.momirealms.craftengine.bukkit.item.ComponentTypes; import net.momirealms.craftengine.core.item.EquipmentData; @@ -8,7 +7,6 @@ import net.momirealms.craftengine.core.plugin.CraftEngine; import java.util.Optional; -@SuppressWarnings("UnstableApiUsage") public class ComponentItemFactory1_21_2 extends ComponentItemFactory1_21 { public ComponentItemFactory1_21_2(CraftEngine plugin) { @@ -26,13 +24,7 @@ public class ComponentItemFactory1_21_2 extends ComponentItemFactory1_21 { @Override protected Optional tooltipStyle(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.TOOLTIP_STYLE)) return Optional.empty(); - return Optional.ofNullable( - (String) ComponentType.encodeJava( - ComponentTypes.TOOLTIP_STYLE, - item.getComponent(ComponentTypes.TOOLTIP_STYLE) - ).orElse(null) - ); + return item.getJavaComponent(ComponentTypes.TOOLTIP_STYLE); } @Override @@ -46,13 +38,7 @@ public class ComponentItemFactory1_21_2 extends ComponentItemFactory1_21 { @Override protected Optional itemModel(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.ITEM_MODEL)) return Optional.empty(); - return Optional.ofNullable( - (String) ComponentType.encodeJava( - ComponentTypes.ITEM_MODEL, - item.getComponent(ComponentTypes.ITEM_MODEL) - ).orElse(null) - ); + return item.getJavaComponent(ComponentTypes.ITEM_MODEL); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_4.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_4.java index f6d14478b..df4ed6d31 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_4.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_4.java @@ -1,6 +1,5 @@ package net.momirealms.craftengine.bukkit.item.factory; -import com.saicone.rtag.data.ComponentType; import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper; import net.momirealms.craftengine.bukkit.item.ComponentTypes; import net.momirealms.craftengine.core.plugin.CraftEngine; @@ -9,7 +8,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -@SuppressWarnings("UnstableApiUsage") public class ComponentItemFactory1_21_4 extends ComponentItemFactory1_21_2 { public ComponentItemFactory1_21_4(CraftEngine plugin) { @@ -18,8 +16,7 @@ public class ComponentItemFactory1_21_4 extends ComponentItemFactory1_21_2 { @Override protected Optional customModelData(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.CUSTOM_MODEL_DATA)) return Optional.empty(); - Optional optional = ComponentType.encodeJava(ComponentTypes.CUSTOM_MODEL_DATA, item.getComponent(ComponentTypes.CUSTOM_MODEL_DATA)); + Optional optional = item.getJavaComponent(ComponentTypes.CUSTOM_MODEL_DATA); if (optional.isEmpty()) return Optional.empty(); @SuppressWarnings("unchecked") Map data = (Map) optional.get(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java index ab79741f7..1e249d52e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java @@ -3,14 +3,16 @@ package net.momirealms.craftengine.bukkit.item.factory; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.saicone.rtag.data.ComponentType; -import com.saicone.rtag.tag.TagList; -import com.saicone.rtag.util.ChatComponent; +import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper; import net.momirealms.craftengine.bukkit.item.ComponentTypes; -import net.momirealms.craftengine.bukkit.util.ComponentUtils; import net.momirealms.craftengine.core.item.JukeboxPlayable; import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.util.AdventureHelper; import net.momirealms.craftengine.core.util.GsonHelper; +import net.momirealms.sparrow.nbt.ListTag; +import net.momirealms.sparrow.nbt.Tag; +import net.momirealms.sparrow.nbt.serializer.NBTComponentSerializer; import java.util.ArrayList; import java.util.List; @@ -24,60 +26,91 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { } @Override - protected void customName(ComponentItemWrapper item, String json) { + protected void customNameJson(ComponentItemWrapper item, String json) { if (json == null) { item.resetComponent(ComponentTypes.CUSTOM_NAME); } else { - item.setNBTComponent(ComponentTypes.CUSTOM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json))); + item.setSparrowNBTComponent(ComponentTypes.CUSTOM_NAME, NBTComponentSerializer.nbt().serialize(AdventureHelper.jsonToComponent(json))); } } @Override - protected Optional customName(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.CUSTOM_NAME)) return Optional.empty(); - return ComponentType.encodeJson(ComponentTypes.CUSTOM_NAME, item.getComponent(ComponentTypes.CUSTOM_NAME)).map(jsonElement -> GsonHelper.get().toJson(jsonElement)); + protected Optional customNameJson(ComponentItemWrapper item) { + return item.getJsonComponent(ComponentTypes.CUSTOM_NAME).map(it -> GsonHelper.get().toJson(it)); } @Override - protected void itemName(ComponentItemWrapper item, String json) { + protected void customNameComponent(ComponentItemWrapper item, Component component) { + if (component == null) { + item.resetComponent(ComponentTypes.CUSTOM_NAME); + } else { + item.setSparrowNBTComponent(ComponentTypes.CUSTOM_NAME, NBTComponentSerializer.nbt().serialize(component)); + } + } + + @Override + protected Optional customNameComponent(ComponentItemWrapper item) { + return customNameJson(item).map(AdventureHelper::jsonToComponent); + } + + @Override + protected void itemNameJson(ComponentItemWrapper item, String json) { if (json == null) { item.resetComponent(ComponentTypes.ITEM_NAME); } else { - item.setNBTComponent(ComponentTypes.ITEM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json))); + item.setSparrowNBTComponent(ComponentTypes.ITEM_NAME, NBTComponentSerializer.nbt().serialize(AdventureHelper.jsonToComponent(json))); } } @Override - protected Optional itemName(ComponentItemWrapper item) { - if (!item.hasComponent(ComponentTypes.ITEM_NAME)) return Optional.empty(); - return ComponentType.encodeJson(ComponentTypes.ITEM_NAME, item.getComponent(ComponentTypes.ITEM_NAME)).map(jsonElement -> GsonHelper.get().toJson(jsonElement)); + protected void itemNameComponent(ComponentItemWrapper item, Component component) { + if (component == null) { + item.resetComponent(ComponentTypes.ITEM_NAME); + } else { + item.setSparrowNBTComponent(ComponentTypes.ITEM_NAME, NBTComponentSerializer.nbt().serialize(component)); + } } @Override - protected Optional> lore(ComponentItemWrapper item) { + protected Optional itemNameJson(ComponentItemWrapper item) { + return item.getJsonComponent(ComponentTypes.ITEM_NAME).map(it -> GsonHelper.get().toJson(it)); + } + + @Override + protected Optional> loreJson(ComponentItemWrapper item) { if (!item.hasComponent(ComponentTypes.LORE)) return Optional.empty(); - return ComponentType.encodeJson( - ComponentTypes.LORE, - item.getComponent(ComponentTypes.LORE) - ).map(list -> { - List lore = new ArrayList<>(); - for (JsonElement jsonElement : (JsonArray) list) { - lore.add(GsonHelper.get().toJson(jsonElement)); - } - return lore; - }); + Optional json = item.getJsonComponent(ComponentTypes.LORE); + if (json.isEmpty()) return Optional.empty(); + List lore = new ArrayList<>(); + for (JsonElement jsonElement : (JsonArray) json.get()) { + lore.add(GsonHelper.get().toJson(jsonElement)); + } + return Optional.of(lore); } @Override - protected void lore(ComponentItemWrapper item, List lore) { + protected void loreComponent(ComponentItemWrapper item, List lore) { if (lore == null || lore.isEmpty()) { item.resetComponent(ComponentTypes.LORE); } else { - List loreTags = new ArrayList<>(); - for (String json : lore) { - loreTags.add(ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json))); + List loreTags = new ArrayList<>(); + for (Component component : lore) { + loreTags.add(NBTComponentSerializer.nbt().serialize(component)); } - item.setNBTComponent(ComponentTypes.LORE, TagList.newTag(loreTags)); + item.setSparrowNBTComponent(ComponentTypes.LORE, new ListTag(loreTags)); + } + } + + @Override + protected void loreJson(ComponentItemWrapper item, List lore) { + if (lore == null || lore.isEmpty()) { + item.resetComponent(ComponentTypes.LORE); + } else { + List loreTags = new ArrayList<>(); + for (String json : lore) { + loreTags.add(NBTComponentSerializer.nbt().serialize(AdventureHelper.jsonToComponent(json))); + } + item.setSparrowNBTComponent(ComponentTypes.LORE, new ListTag(loreTags)); } } @@ -86,7 +119,7 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { if (!item.hasComponent(ComponentTypes.JUKEBOX_PLAYABLE)) return Optional.empty(); String song = (String) ComponentType.encodeJava( ComponentTypes.JUKEBOX_PLAYABLE, - item.getComponent(ComponentTypes.JUKEBOX_PLAYABLE)).orElse(null); + item.getComponentExact(ComponentTypes.JUKEBOX_PLAYABLE)).orElse(null); if (song == null) return Optional.empty(); return Optional.of(new JukeboxPlayable(song, true)); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/UniversalItemFactory.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/UniversalItemFactory.java index dbf97a69d..689efd276 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/UniversalItemFactory.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/UniversalItemFactory.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.bukkit.item.factory; +import com.google.gson.JsonElement; import com.saicone.rtag.RtagItem; import com.saicone.rtag.item.ItemObject; import com.saicone.rtag.tag.TagBase; @@ -12,6 +13,7 @@ import net.momirealms.craftengine.core.item.modifier.IdModifier; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.SkullUtils; +import net.momirealms.sparrow.nbt.Tag; import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.bukkit.inventory.ItemFlag; @@ -31,6 +33,21 @@ public class UniversalItemFactory extends BukkitItemFactory { return new LegacyItemWrapper(new RtagItem(item), item.getAmount()); } + @Override + protected Object getJavaComponent(LegacyItemWrapper item, Object type) { + throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); + } + + @Override + protected JsonElement getJsonComponent(LegacyItemWrapper item, Object type) { + throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); + } + + @Override + protected Tag getNBTComponent(LegacyItemWrapper item, Object type) { + throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); + } + @Override protected void setTag(LegacyItemWrapper item, Object value, Object... path) { item.set(value, path); @@ -64,7 +81,7 @@ public class UniversalItemFactory extends BukkitItemFactory { } @Override - protected void customName(LegacyItemWrapper item, String json) { + protected void customNameJson(LegacyItemWrapper item, String json) { if (json != null) { item.set(json, "display", "Name"); } else { @@ -73,19 +90,19 @@ public class UniversalItemFactory extends BukkitItemFactory { } @Override - protected Optional customName(LegacyItemWrapper item) { + protected Optional customNameJson(LegacyItemWrapper item) { if (!item.hasTag("display", "Name")) return Optional.empty(); return Optional.of(item.get("display", "Name")); } @Override - protected void itemName(LegacyItemWrapper item, String json) { - customName(item, json); + protected void itemNameJson(LegacyItemWrapper item, String json) { + customNameJson(item, json); } @Override - protected Optional itemName(LegacyItemWrapper item) { - return customName(item); + protected Optional itemNameJson(LegacyItemWrapper item) { + return customNameJson(item); } @Override @@ -117,13 +134,13 @@ public class UniversalItemFactory extends BukkitItemFactory { } @Override - protected Optional> lore(LegacyItemWrapper item) { + protected Optional> loreJson(LegacyItemWrapper item) { if (!item.hasTag("display", "Lore")) return Optional.empty(); return Optional.of(item.get("display", "Lore")); } @Override - protected void lore(LegacyItemWrapper item, List lore) { + protected void loreJson(LegacyItemWrapper item, List lore) { if (lore == null || lore.isEmpty()) { item.remove("display", "Lore"); } else { @@ -168,8 +185,8 @@ public class UniversalItemFactory extends BukkitItemFactory { } @Override - protected Optional maxDamage(LegacyItemWrapper item) { - return Optional.of((int) item.getItem().getType().getMaxDurability()); + protected int maxDamage(LegacyItemWrapper item) { + return item.getItem().getType().getMaxDurability(); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java index 469cb7e1e..ab9c32643 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java @@ -512,7 +512,7 @@ public class RecipeEventListener implements Listener { Item wrappedFirst = BukkitItemManager.instance().wrap(first.clone()); - int maxDamage = wrappedFirst.maxDamage().orElse(0); + int maxDamage = wrappedFirst.maxDamage(); int damage = wrappedFirst.damage().orElse(0); // not a repairable item if (damage == 0 || maxDamage == 0) return; @@ -577,8 +577,8 @@ public class RecipeEventListener implements Listener { if (renameText != null && !renameText.isBlank()) { try { - if (!renameText.equals(Reflections.method$Component$getString.invoke(ComponentUtils.jsonToMinecraft(wrappedFirst.hoverName().orElse(AdventureHelper.EMPTY_COMPONENT))))) { - wrappedFirst.customName(AdventureHelper.componentToJson(Component.text(renameText))); + if (!renameText.equals(Reflections.method$Component$getString.invoke(ComponentUtils.jsonToMinecraft(wrappedFirst.hoverNameJson().orElse(AdventureHelper.EMPTY_COMPONENT))))) { + wrappedFirst.customNameJson(AdventureHelper.componentToJson(Component.text(renameText))); repairCost += 1; } else if (repairCost == 0) { hasResult = false; @@ -588,10 +588,10 @@ public class RecipeEventListener implements Listener { } } else if (VersionHelper.isOrAbove1_20_5() && wrappedFirst.hasComponent(ComponentTypes.CUSTOM_NAME)) { repairCost += 1; - wrappedFirst.customName(null); + wrappedFirst.customNameJson(null); } else if (!VersionHelper.isOrAbove1_20_5() && wrappedFirst.hasTag("display", "Name")) { repairCost += 1; - wrappedFirst.customName(null); + wrappedFirst.customNameJson(null); } int finalCost = repairCost + repairPenalty; @@ -665,7 +665,7 @@ public class RecipeEventListener implements Listener { } if (renameText != null && !renameText.isBlank()) { try { - if (!renameText.equals(Reflections.method$Component$getString.invoke(ComponentUtils.jsonToMinecraft(wrappedFirst.hoverName().orElse(AdventureHelper.EMPTY_COMPONENT))))) { + if (!renameText.equals(Reflections.method$Component$getString.invoke(ComponentUtils.jsonToMinecraft(wrappedFirst.hoverNameJson().orElse(AdventureHelper.EMPTY_COMPONENT))))) { event.setResult(null); } } catch (Exception e) { @@ -721,7 +721,7 @@ public class RecipeEventListener implements Listener { } int totalDamage = right.damage().orElse(0) + left.damage().orElse(0); - int totalMaxDamage = left.maxDamage().get() + right.maxDamage().get(); + int totalMaxDamage = left.maxDamage() + right.maxDamage(); // should be impossible, but take care if (totalDamage >= totalMaxDamage) { inventory.setResult(null); @@ -750,7 +750,7 @@ public class RecipeEventListener implements Listener { Item newItem = customItem.buildItem(ItemBuildContext.of(plugin.adapt(player))); int remainingDurability = totalMaxDamage - totalDamage; - int newItemDamage = Math.max(0, newItem.maxDamage().get() - remainingDurability); + int newItemDamage = Math.max(0, newItem.maxDamage() - remainingDurability); newItem.damage(newItemDamage); inventory.setResult(newItem.load()); } else if (Reflections.clazz$ArmorDyeRecipe.isInstance(mcRecipe)) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java index a7698e25c..bb29be78b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java @@ -1,7 +1,6 @@ package net.momirealms.craftengine.bukkit.plugin.network.id; import net.momirealms.craftengine.bukkit.plugin.network.PacketIds; -import net.momirealms.craftengine.bukkit.util.Reflections; public class PacketIds1_20_5 implements PacketIds { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index 0d71d0e68..fba7a0f92 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -3,6 +3,8 @@ package net.momirealms.craftengine.bukkit.util; import com.google.common.collect.ImmutableList; import com.google.gson.Gson; import com.google.gson.JsonElement; +import com.mojang.serialization.DynamicOps; +import com.mojang.serialization.JsonOps; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; @@ -14,6 +16,8 @@ import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.core.util.ReflectionUtils; import net.momirealms.craftengine.core.util.VersionHelper; +import net.momirealms.sparrow.nbt.Tag; +import net.momirealms.sparrow.nbt.codec.NBTOps; import org.bukkit.NamespacedKey; import org.bukkit.block.BlockState; import org.bukkit.block.data.BlockData; @@ -6855,4 +6859,53 @@ public class Reflections { "network.protocol.game.ServerboundContainerClickPacket" ) ); + + public static final Class clazz$RegistryOps = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "resources.RegistryOps", + "resources.RegistryOps" + ) + ); + + public static final Class clazz$JavaOps = requireNonNull( + ReflectionUtils.getClazz("com.mojang.serialization.JavaOps") + ); + + public static final Class clazz$NbtOps = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "nbt.DynamicOpsNBT", + "nbt.NbtOps" + ) + ); + + public static final Method method$RegistryOps$create = requireNonNull( + ReflectionUtils.getStaticMethod( + clazz$RegistryOps, clazz$RegistryOps, DynamicOps.class, clazz$HolderLookup$Provider + ) + ); + + public static final DynamicOps instance$NBT_OPS; + public static final DynamicOps instance$SPARROW_NBT_OPS; + public static final DynamicOps instance$JAVA_OPS; + public static final DynamicOps instance$JSON_OPS; + + static { + try { + Object nbtOps = ReflectionUtils.getDeclaredField(clazz$NbtOps, clazz$NbtOps, 0).get(null); + instance$NBT_OPS = (DynamicOps) method$RegistryOps$create.invoke(null, nbtOps, instance$MinecraftRegistry); + Object javaOps = ReflectionUtils.getDeclaredField(clazz$JavaOps, clazz$JavaOps, 0).get(null); + instance$JAVA_OPS = (DynamicOps) method$RegistryOps$create.invoke(null, javaOps, instance$MinecraftRegistry); + instance$JSON_OPS = (DynamicOps) method$RegistryOps$create.invoke(null, JsonOps.INSTANCE, instance$MinecraftRegistry); + instance$SPARROW_NBT_OPS = (DynamicOps) method$RegistryOps$create.invoke(null, NBTOps.INSTANCE, instance$MinecraftRegistry); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public static final Class clazz$Tag = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "nbt.NBTBase", + "nbt.Tag" + ) + ); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java index 8d2010eca..92ae329cb 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java @@ -1,7 +1,6 @@ package net.momirealms.craftengine.core.font; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; 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 70fbf6d8f..919f8c62b 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 @@ -1,8 +1,10 @@ package net.momirealms.craftengine.core.item; import com.google.gson.JsonElement; +import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.util.Key; +import net.momirealms.sparrow.nbt.Tag; import java.util.List; import java.util.Optional; @@ -89,7 +91,7 @@ public class AbstractItem, I> implements Item { } @Override - public Optional maxDamage() { + public int maxDamage() { return this.factory.maxDamage(this.item); } @@ -180,25 +182,47 @@ public class AbstractItem, I> implements Item { } @Override - public Optional customName() { - return this.factory.customName(this.item); + public Optional customNameJson() { + return this.factory.customNameJson(this.item); } @Override - public Item customName(String displayName) { - this.factory.customName(this.item, displayName); + public Item customNameJson(String displayName) { + this.factory.customNameJson(this.item, displayName); return this; } @Override - public Item lore(List lore) { - this.factory.lore(this.item, lore); + public Optional customNameComponent() { + return this.factory.customNameComponent(this.item); + } + + @Override + public Item customNameComponent(Component displayName) { + this.factory.customNameComponent(this.item, displayName); return this; } @Override - public Optional> lore() { - return this.factory.lore(this.item); + public Item loreJson(List lore) { + this.factory.loreJson(this.item, lore); + return this; + } + + @Override + public Optional> loreJson() { + return this.factory.loreJson(this.item); + } + + @Override + public Item loreComponent(List lore) { + this.factory.loreComponent(this.item, lore); + return this; + } + + @Override + public Optional> loreComponent() { + return this.factory.loreComponent(this.item); } @Override @@ -212,18 +236,28 @@ public class AbstractItem, I> implements Item { return this.factory.unbreakable(this.item); } - @Override - public Optional itemName() { - return this.factory.itemName(this.item); + public Item itemNameJson(String itemName) { + this.factory.itemNameJson(this.item, itemName); + return this; } @Override - public Item itemName(String itemName) { - this.factory.itemName(this.item, itemName); + public Optional itemNameJson() { + return this.factory.itemNameJson(this.item); + } + + @Override + public Item itemNameComponent(Component itemName) { + this.factory.itemNameComponent(this.item, itemName); return this; } + @Override + public Optional itemNameComponent() { + return this.factory.itemNameComponent(this.item); + } + @Override public Item skull(String data) { this.factory.skull(this.item, data); @@ -308,18 +342,23 @@ public class AbstractItem, I> implements Item { } @Override - public Object getComponent(Object type) { - return this.factory.getComponent(this.item, type); + public Object getExactComponent(Object type) { + return this.factory.getExactComponent(this.item, type); } @Override - public Object getJavaTypeComponent(Object type) { - return this.factory.encodeJava(type, getComponent(type)); + public Object getJavaComponent(Object type) { + return this.factory.getJavaComponent(this.item, type); } @Override - public JsonElement getJsonTypeComponent(Object type) { - return this.factory.encodeJson(type, getComponent(type)); + public JsonElement getJsonComponent(Object type) { + return this.factory.getJsonComponent(this.item, type); + } + + @Override + public Tag getNBTComponent(Object type) { + return this.factory.getNBTComponent(this.item, type); } @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java index 9b0b5be71..cf3df095b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java @@ -437,7 +437,7 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl }, "external"); registerDataFunction((obj) -> { String name = obj.toString(); - return new DisplayNameModifier<>(name); + return new CustomNameModifier<>(name); }, "custom-name"); registerDataFunction((obj) -> { String name = obj.toString(); 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 50786ace9..e2c005e07 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 @@ -1,8 +1,10 @@ package net.momirealms.craftengine.core.item; import com.google.gson.JsonElement; +import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.util.Key; +import net.momirealms.sparrow.nbt.Tag; import java.util.List; import java.util.Optional; @@ -54,23 +56,35 @@ public interface Item { Item maxDamage(Integer data); - Optional maxDamage(); + int maxDamage(); Item dyedColor(Integer data); Optional dyedColor(); - Item customName(String displayName); + Item customNameJson(String displayName); - Optional customName(); + Item customNameComponent(Component displayName); - default Optional hoverName() { - return customName().or(this::itemName); + Optional customNameJson(); + + Optional customNameComponent(); + + default Optional hoverNameJson() { + return customNameJson().or(this::itemNameJson); } - Item itemName(String itemName); + default Optional hoverNameComponent() { + return customNameComponent().or(this::itemNameComponent); + } - Optional itemName(); + Item itemNameJson(String itemName); + + Item itemNameComponent(Component itemName); + + Optional itemNameJson(); + + Optional itemNameComponent(); Item itemModel(String itemModel); @@ -80,7 +94,13 @@ public interface Item { Optional tooltipStyle(); - Item lore(List lore); + Item loreJson(List lore); + + Item loreComponent(List lore); + + Optional> loreJson(); + + Optional> loreComponent(); Optional jukeboxSong(); @@ -90,7 +110,6 @@ public interface Item { Item equippable(EquipmentData equipmentData); - Optional> lore(); Item unbreakable(boolean unbreakable); @@ -122,11 +141,13 @@ public interface Item { void removeComponent(Object type); - Object getComponent(Object type); + Object getExactComponent(Object type); - Object getJavaTypeComponent(Object type); + Object getJavaComponent(Object type); - JsonElement getJsonTypeComponent(Object type); + JsonElement getJsonComponent(Object type); + + Tag getNBTComponent(Object type); void setComponent(Object type, Object value); 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 eb3c9fada..ea15a3823 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 @@ -1,13 +1,16 @@ package net.momirealms.craftengine.core.item; import com.google.gson.JsonElement; +import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.util.AdventureHelper; import net.momirealms.craftengine.core.util.Key; -import org.jetbrains.annotations.Nullable; +import net.momirealms.sparrow.nbt.Tag; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; public abstract class ItemFactory, I> { protected final CraftEngine plugin; @@ -25,10 +28,6 @@ public abstract class ItemFactory, I> { protected abstract void merge(W item1, W item2); - protected abstract Object encodeJava(Object type, @Nullable Object component); - - protected abstract JsonElement encodeJson(Object type, Object component); - protected abstract W wrapInternal(I item); protected abstract Object getTag(W item, Object... path); @@ -41,7 +40,13 @@ public abstract class ItemFactory, I> { protected abstract void setComponent(W item, Object type, Object value); - protected abstract Object getComponent(W item, Object type); + protected abstract Object getExactComponent(W item, Object type); + + protected abstract Object getJavaComponent(W item, Object type); + + protected abstract JsonElement getJsonComponent(W item, Object type); + + protected abstract Tag getNBTComponent(W item, Object type); protected abstract boolean hasComponent(W item, Object type); @@ -57,20 +62,56 @@ public abstract class ItemFactory, I> { protected abstract Optional customModelData(W item); - protected abstract void customName(W item, String json); + protected abstract void customNameJson(W item, String json); - protected abstract Optional customName(W item); + protected abstract Optional customNameJson(W item); - protected abstract void itemName(W item, String json); + protected void customNameComponent(W item, Component component) { + if (component != null) { + customNameJson(item, AdventureHelper.componentToJson(component)); + } else { + customNameJson(item, null); + } + } - protected abstract Optional itemName(W item); + protected Optional customNameComponent(W item) { + return customNameJson(item).map(AdventureHelper::jsonToComponent); + } + + protected abstract void itemNameJson(W item, String json); + + protected abstract Optional itemNameJson(W item); + + protected void itemNameComponent(W item, Component component) { + if (component != null) { + itemNameJson(item, AdventureHelper.componentToJson(component)); + } else { + itemNameJson(item, null); + } + } + + protected Optional itemNameComponent(W item) { + return itemNameJson(item).map(AdventureHelper::jsonToComponent); + } + + protected abstract Optional> loreJson(W item); + + protected abstract void loreJson(W item, List lore); + + protected void loreComponent(W item, List component) { + if (component != null && !component.isEmpty()) { + loreJson(item, component.stream().map(AdventureHelper::componentToJson).collect(Collectors.toList())); + } else { + loreJson(item, null); + } + } + + protected Optional> loreComponent(W item) { + return loreJson(item).map(list -> list.stream().map(AdventureHelper::jsonToComponent).toList()); + } protected abstract void skull(W item, String skullData); - protected abstract Optional> lore(W item); - - protected abstract void lore(W item, List lore); - protected abstract boolean unbreakable(W item); protected abstract void unbreakable(W item, boolean unbreakable); @@ -87,7 +128,7 @@ public abstract class ItemFactory, I> { protected abstract void dyedColor(W item, Integer color); - protected abstract Optional maxDamage(W item); + protected abstract int maxDamage(W item); protected abstract void maxDamage(W item, Integer damage); @@ -144,5 +185,4 @@ public abstract class ItemFactory, I> { protected abstract Optional equippable(W item); protected abstract byte[] toByteArray(W item); - } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentModifier.java index 216c7740c..d13e28e4b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentModifier.java @@ -65,7 +65,7 @@ public class ComponentModifier implements ItemDataModifier { item.setComponent(entry.left(), entry.right()); } if (this.customData != null) { - JsonObject tag = (JsonObject) item.getJsonTypeComponent(ComponentKeys.CUSTOM_DATA); + JsonObject tag = (JsonObject) item.getJsonComponent(ComponentKeys.CUSTOM_DATA); if (tag != null) { item.setComponent(ComponentKeys.CUSTOM_DATA, GsonHelper.shallowMerge(this.customData, tag)); } else { @@ -80,7 +80,7 @@ public class ComponentModifier implements ItemDataModifier { item.resetComponent(entry.left()); } if (this.customData != null) { - JsonObject tag = (JsonObject) item.getJsonTypeComponent(ComponentKeys.CUSTOM_DATA); + JsonObject tag = (JsonObject) item.getJavaComponent(ComponentKeys.CUSTOM_DATA); if (tag != null) { // crude method for (String key : this.customData.keySet()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DisplayNameModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/CustomNameModifier.java similarity index 65% rename from core/src/main/java/net/momirealms/craftengine/core/item/modifier/DisplayNameModifier.java rename to core/src/main/java/net/momirealms/craftengine/core/item/modifier/CustomNameModifier.java index cf468756c..6814092ce 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DisplayNameModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/CustomNameModifier.java @@ -5,25 +5,25 @@ import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.AdventureHelper; -public class DisplayNameModifier implements ItemDataModifier { +public class CustomNameModifier implements ItemDataModifier { private final String argument; - public DisplayNameModifier(String argument) { + public CustomNameModifier(String argument) { this.argument = Config.nonItalic() ? "" + argument : argument; } @Override public String name() { - return "display-name"; + return "custom-name"; } @Override public void apply(Item item, ItemBuildContext context) { - item.customName(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(this.argument, context.tagResolvers()))); + item.customNameComponent(AdventureHelper.miniMessage().deserialize(this.argument, context.tagResolvers())); } @Override public void remove(Item item) { - item.customName(null); + item.customNameJson(null); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemNameModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemNameModifier.java index 8ba7e0967..b575874f0 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemNameModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemNameModifier.java @@ -19,11 +19,11 @@ public class ItemNameModifier implements ItemDataModifier { @Override public void apply(Item item, ItemBuildContext context) { - item.itemName(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(this.argument, context.tagResolvers()))); + item.itemNameComponent(AdventureHelper.miniMessage().deserialize(this.argument, context.tagResolvers())); } @Override public void remove(Item item) { - item.itemName(null); + item.itemNameJson(null); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/LoreModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/LoreModifier.java index 5515ab4d2..5bda4c5d5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/LoreModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/LoreModifier.java @@ -21,12 +21,12 @@ public class LoreModifier implements ItemDataModifier { @Override public void apply(Item item, ItemBuildContext context) { - item.lore(this.argument.stream().map(it -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize( - it, context.tagResolvers()))).toList()); + item.loreComponent(this.argument.stream().map(it -> AdventureHelper.miniMessage().deserialize( + it, context.tagResolvers())).toList()); } @Override public void remove(Item item) { - item.lore(null); + item.loreJson(null); } } 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 b4698e00b..ce2b96cd1 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 @@ -219,7 +219,7 @@ public class CustomSmithingTransformRecipe implements Recipe { @Override public void accept(Item item1, Item item2, Item item3) { for (Key component : this.components) { - Object componentObj = item1.getComponent(component); + Object componentObj = item1.getExactComponent(component); if (componentObj != null) { item3.setComponent(component, componentObj); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java index 7fc4915ef..ca5695c38 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java @@ -163,8 +163,8 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { this.plugin.logger().warn("Can't not find item " + it.icon() + " for category icon"); return null; } - item.customName(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(it.displayName(), ItemBuildContext.EMPTY.tagResolvers()))); - item.lore(it.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY.tagResolvers()))).toList()); + item.customNameJson(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(it.displayName(), ItemBuildContext.EMPTY.tagResolvers()))); + item.loreJson(it.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY.tagResolvers()))).toList()); item.load(); return new ItemWithAction(item, (element, click) -> { click.cancel(); @@ -249,13 +249,13 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (!subCategory.icon().equals(ItemKeys.AIR)) { this.plugin.logger().warn("Can't find item " + subCategory.icon() + " as icon for sub category " + subCategoryId); item = this.plugin.itemManager().createWrappedItem(ItemKeys.BARRIER, player); - item.customName(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(subCategory.displayName(), ItemBuildContext.EMPTY.tagResolvers()))); - item.lore(subCategory.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY.tagResolvers()))).toList()); + item.customNameJson(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(subCategory.displayName(), ItemBuildContext.EMPTY.tagResolvers()))); + item.loreJson(subCategory.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY.tagResolvers()))).toList()); item.load(); } } else { - item.customName(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(subCategory.displayName(), ItemBuildContext.EMPTY.tagResolvers()))); - item.lore(subCategory.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY.tagResolvers()))).toList()); + item.customNameJson(AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(subCategory.displayName(), ItemBuildContext.EMPTY.tagResolvers()))); + item.loreJson(subCategory.displayLore().stream().map(lore -> AdventureHelper.componentToJson(AdventureHelper.miniMessage().deserialize(lore, ItemBuildContext.EMPTY.tagResolvers()))).toList()); item.load(); } return new ItemWithAction(item, (element, click) -> { @@ -271,7 +271,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (!itemId.equals(ItemKeys.AIR)) { this.plugin.logger().warn("Can't find item " + itemId + " for category " + categoryId); item = this.plugin.itemManager().createWrappedItem(ItemKeys.BARRIER, player); - item.customName(AdventureHelper.componentToJson(Component.text(it).decoration(TextDecoration.ITALIC, TextDecoration.State.FALSE).color(NamedTextColor.RED))); + item.customNameJson(AdventureHelper.componentToJson(Component.text(it).decoration(TextDecoration.ITALIC, TextDecoration.State.FALSE).color(NamedTextColor.RED))); } canGoFurther = false; } else { diff --git a/gradle.properties b/gradle.properties index de82be993..4a1852463 100644 --- a/gradle.properties +++ b/gradle.properties @@ -39,18 +39,18 @@ 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.7.3 +sparrow_nbt_version=0.8.1 sparrow_util_version=0.47 fastutil_version=8.5.15 netty_version=4.1.121.Final joml_version=1.10.8 -datafixerupper_version=6.0.8 +datafixerupper_version=8.0.16 mojang_brigadier_version=1.0.18 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.2 +nms_helper_version=0.66.3 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23