From b327ed11d51157a49dcf68f24c61a6a58b3e6ced Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Mon, 14 Apr 2025 02:27:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96component=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/item/BukkitCustomItem.java | 2 +- .../item/factory/BukkitItemFactory.java | 20 --- .../item/factory/ComponentItemFactory.java | 163 +++++++++++++----- .../factory/ComponentItemFactory1_21_4.java | 4 +- .../factory/ComponentItemFactory1_21_5.java | 12 +- .../item/factory/UniversalItemFactory.java | 50 ++++++ .../plugin/command/feature/TestCommand.java | 3 +- .../craftengine/core/item/AbstractItem.java | 35 +++- .../craftengine/core/item/ComponentKeys.java | 37 ++-- .../craftengine/core/item/Item.java | 19 +- .../craftengine/core/item/ItemFactory.java | 17 +- .../craftengine/core/item/Trim.java | 4 + .../core/item/modifier/ComponentModifier.java | 61 ++++++- .../core/item/modifier/IdModifier.java | 10 +- .../core/item/modifier/TrimModifier.java | 14 +- .../recipe/CustomSmithingTransformRecipe.java | 4 +- .../core/pack/AbstractPackManager.java | 4 +- gradle.properties | 2 +- .../mod/{ => block}/CraftEngineBlock.java | 3 +- .../mod/{ => block}/StoneBlockShape.java | 2 +- .../mod/item/CustomStreamCodec.java | 41 +++++ .../{MixinBlocks.java => BlocksMixin.java} | 4 +- .../craftengine/mod/mixin/ItemStackMixin.java | 48 ++++++ .../main/resources/mixins.craftengine.json | 3 +- 24 files changed, 433 insertions(+), 129 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/item/Trim.java rename server-mod/src/main/java/net/momirealms/craftengine/mod/{ => block}/CraftEngineBlock.java (99%) rename server-mod/src/main/java/net/momirealms/craftengine/mod/{ => block}/StoneBlockShape.java (93%) create mode 100644 server-mod/src/main/java/net/momirealms/craftengine/mod/item/CustomStreamCodec.java rename server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/{MixinBlocks.java => BlocksMixin.java} (98%) create mode 100644 server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/ItemStackMixin.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java index 9b295cc80..1d5487a1e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java @@ -118,7 +118,7 @@ public class BukkitCustomItem implements CustomItem { @Override public ItemSettings settings() { - return settings; + return this.settings; } @Override 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 1b1f1c15f..1ba0ab42f 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 @@ -89,26 +89,6 @@ public abstract class BukkitItemFactory extends ItemFactory item, String type, Object value) { - item.setComponent(type, value); - } - - @Override - protected Object getComponent(ItemWrapper item, String type) { - return item.getComponent(type); - } - - @Override - protected boolean hasComponent(ItemWrapper item, String type) { - return item.hasComponent(type); - } - - @Override - protected void removeComponent(ItemWrapper item, String type) { - item.removeComponent(type); - } - @Override protected void update(ItemWrapper item) { item.update(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory.java index 09aaacb85..f4bd8b6e8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory.java @@ -1,14 +1,18 @@ package net.momirealms.craftengine.bukkit.item.factory; +import com.google.gson.JsonElement; import com.saicone.rtag.RtagItem; import com.saicone.rtag.data.ComponentType; import com.saicone.rtag.item.ItemObject; import net.momirealms.craftengine.bukkit.item.RTagItemWrapper; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.util.EnchantmentUtils; +import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Enchantment; import net.momirealms.craftengine.core.item.ItemWrapper; +import net.momirealms.craftengine.core.item.Trim; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.Key; import org.bukkit.inventory.ItemStack; @@ -26,17 +30,59 @@ public class ComponentItemFactory extends BukkitItemFactory { super(plugin); } + @Override + protected void setComponent(ItemWrapper item, Key type, Object value) { + if (value instanceof JsonElement jsonElement) { + setJsonComponentDirectly(item, type, jsonElement); + } else { + setJavaComponentDirectly(item, type, value); + } + } + + @Override + protected void resetComponent(ItemWrapper item, Key type) { + FastNMS.INSTANCE.resetComponent(item.getLiteralObject(), KeyUtils.toResourceLocation(type)); + } + + @Override + protected Object getComponent(ItemWrapper item, Key type) { + return item.getComponent(type); + } + + @Override + protected boolean hasComponent(ItemWrapper item, Key type) { + return item.hasComponent(type); + } + + @Override + protected void removeComponent(ItemWrapper item, Key type) { + FastNMS.INSTANCE.removeComponent(item.getLiteralObject(), KeyUtils.toResourceLocation(type)); + } + + protected void setJavaComponentDirectly(ItemWrapper item, Key type, Object value) { + ComponentType.parseJava(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(item.getLiteralObject(), KeyUtils.toResourceLocation(type), it)); + } + + protected void setJsonComponentDirectly(ItemWrapper item, Key type, JsonElement value) { + ComponentType.parseJson(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(item.getLiteralObject(), KeyUtils.toResourceLocation(type), it)); + } + @Override public Object encodeJava(Key componentType, @Nullable Object component) { return ComponentType.encodeJava(componentType, component).orElse(null); } + @Override + protected JsonElement encodeJson(Key type, Object component) { + return ComponentType.encodeJson(type, component).orElse(null); + } + @Override protected void customModelData(ItemWrapper item, Integer data) { if (data == null) { - item.removeComponent(ComponentKeys.CUSTOM_MODEL_DATA); + resetComponent(item, ComponentKeys.CUSTOM_MODEL_DATA); } else { - item.setComponent(ComponentKeys.CUSTOM_MODEL_DATA, data); + setJavaComponentDirectly(item, ComponentKeys.CUSTOM_MODEL_DATA, data); } } @@ -53,9 +99,9 @@ public class ComponentItemFactory extends BukkitItemFactory { @Override protected void customName(ItemWrapper item, String json) { if (json == null) { - item.removeComponent(ComponentKeys.CUSTOM_NAME); + resetComponent(item, ComponentKeys.CUSTOM_NAME); } else { - item.setComponent(ComponentKeys.CUSTOM_NAME, json); + setJavaComponentDirectly(item, ComponentKeys.CUSTOM_NAME, json); } } @@ -73,9 +119,9 @@ public class ComponentItemFactory extends BukkitItemFactory { @Override protected void itemName(ItemWrapper item, String json) { if (json == null) { - item.removeComponent(ComponentKeys.ITEM_NAME); + resetComponent(item, ComponentKeys.ITEM_NAME); } else { - item.setComponent(ComponentKeys.ITEM_NAME, json); + setJavaComponentDirectly(item, ComponentKeys.ITEM_NAME, json); } } @@ -92,15 +138,12 @@ public class ComponentItemFactory extends BukkitItemFactory { @Override protected void skull(ItemWrapper item, String skullData) { - final Map profile = Map.of( - "properties", List.of( - Map.of( - "name", "textures", - "value", skullData - ) - ) - ); - item.setComponent("minecraft:profile", profile); + if (skullData == null) { + resetComponent(item, ComponentKeys.PROFILE); + } else { + Map profile = Map.of("properties", List.of(Map.of("name", "textures", "value", skullData))); + setJavaComponentDirectly(item, ComponentKeys.PROFILE, profile); + } } @SuppressWarnings("unchecked") @@ -118,9 +161,9 @@ public class ComponentItemFactory extends BukkitItemFactory { @Override protected void lore(ItemWrapper item, List lore) { if (lore == null || lore.isEmpty()) { - item.removeComponent(ComponentKeys.LORE); + resetComponent(item, ComponentKeys.LORE); } else { - item.setComponent(ComponentKeys.LORE, lore); + setJavaComponentDirectly(item, ComponentKeys.LORE, lore); } } @@ -132,9 +175,9 @@ public class ComponentItemFactory extends BukkitItemFactory { @Override protected void unbreakable(ItemWrapper item, boolean unbreakable) { if (unbreakable) { - item.removeComponent(ComponentKeys.UNBREAKABLE); + resetComponent(item, ComponentKeys.UNBREAKABLE); } else { - item.setComponent(ComponentKeys.UNBREAKABLE, true); + setJavaComponentDirectly(item, ComponentKeys.UNBREAKABLE, true); } } @@ -145,7 +188,11 @@ public class ComponentItemFactory extends BukkitItemFactory { @Override protected void glint(ItemWrapper item, Boolean glint) { - item.setComponent(ComponentKeys.ENCHANTMENT_GLINT_OVERRIDE, glint); + if (glint == null) { + resetComponent(item, ComponentKeys.ENCHANTMENT_GLINT_OVERRIDE); + } else { + setJavaComponentDirectly(item, ComponentKeys.ENCHANTMENT_GLINT_OVERRIDE, glint); + } } @Override @@ -161,8 +208,11 @@ public class ComponentItemFactory extends BukkitItemFactory { @Override protected void damage(ItemWrapper item, Integer damage) { - if (damage == null) damage = 0; - item.setComponent(ComponentKeys.DAMAGE, damage); + if (damage == null) { + resetComponent(item, ComponentKeys.DAMAGE); + } else { + setJavaComponentDirectly(item, ComponentKeys.DAMAGE, damage); + } } @Override @@ -179,9 +229,9 @@ public class ComponentItemFactory extends BukkitItemFactory { @Override protected void maxDamage(ItemWrapper item, Integer damage) { if (damage == null) { - item.removeComponent(ComponentKeys.MAX_DAMAGE); + resetComponent(item, ComponentKeys.MAX_DAMAGE); } else { - item.setComponent(ComponentKeys.MAX_DAMAGE, damage); + setJavaComponentDirectly(item, ComponentKeys.MAX_DAMAGE, damage); } } @@ -202,27 +252,27 @@ public class ComponentItemFactory extends BukkitItemFactory { @Override protected void enchantments(ItemWrapper item, List enchantments) { if (enchantments == null || enchantments.isEmpty()) { - item.removeComponent(ComponentKeys.ENCHANTMENTS); - return; + resetComponent(item, ComponentKeys.ENCHANTMENTS); + } else { + Map enchants = new HashMap<>(); + for (Enchantment enchantment : enchantments) { + enchants.put(enchantment.id().toString(), enchantment.level()); + } + setJavaComponentDirectly(item, ComponentKeys.ENCHANTMENTS, enchants); } - Map enchants = new HashMap<>(); - for (Enchantment enchantment : enchantments) { - enchants.put(enchantment.id().toString(), enchantment.level()); - } - item.setComponent(ComponentKeys.ENCHANTMENTS, enchants); } @Override protected void storedEnchantments(ItemWrapper item, List enchantments) { if (enchantments == null || enchantments.isEmpty()) { - item.removeComponent(ComponentKeys.STORED_ENCHANTMENTS); - return; + resetComponent(item, ComponentKeys.STORED_ENCHANTMENTS); + } else { + Map enchants = new HashMap<>(); + for (Enchantment enchantment : enchantments) { + enchants.put(enchantment.id().toString(), enchantment.level()); + } + setJavaComponentDirectly(item, ComponentKeys.STORED_ENCHANTMENTS, enchants); } - Map enchants = new HashMap<>(); - for (Enchantment enchantment : enchantments) { - enchants.put(enchantment.id().toString(), enchantment.level()); - } - item.setComponent(ComponentKeys.STORED_ENCHANTMENTS, enchants); } @Override @@ -231,7 +281,7 @@ public class ComponentItemFactory extends BukkitItemFactory { try { Map map = EnchantmentUtils.toMap(enchant); map.put(enchantment.toString(), enchantment.level()); - item.setComponent(ComponentKeys.ENCHANTMENTS, map); + setJavaComponentDirectly(item, ComponentKeys.ENCHANTMENTS, map); } catch (ReflectiveOperationException e) { plugin.logger().warn("Failed to add enchantment", e); } @@ -243,7 +293,7 @@ public class ComponentItemFactory extends BukkitItemFactory { try { Map map = EnchantmentUtils.toMap(enchant); map.put(enchantment.toString(), enchantment.level()); - item.setComponent(ComponentKeys.STORED_ENCHANTMENTS, map); + setJavaComponentDirectly(item, ComponentKeys.STORED_ENCHANTMENTS, map); } catch (ReflectiveOperationException e) { plugin.logger().warn("Failed to add stored enchantment", e); } @@ -264,18 +314,18 @@ public class ComponentItemFactory extends BukkitItemFactory { @Override protected void maxStackSize(ItemWrapper item, Integer maxStackSize) { if (maxStackSize == null) { - item.removeComponent(ComponentKeys.MAX_STACK_SIZE); + resetComponent(item, ComponentKeys.MAX_STACK_SIZE); } else { - item.setComponent(ComponentKeys.MAX_STACK_SIZE, maxStackSize); + setJavaComponentDirectly(item, ComponentKeys.MAX_STACK_SIZE, maxStackSize); } } @Override protected void repairCost(ItemWrapper item, Integer data) { if (data == null) { - item.removeComponent(ComponentKeys.REPAIR_COST); + resetComponent(item, ComponentKeys.REPAIR_COST); } else { - item.setComponent(ComponentKeys.REPAIR_COST, data); + setJavaComponentDirectly(item, ComponentKeys.REPAIR_COST, data); } } @@ -302,7 +352,6 @@ public class ComponentItemFactory extends BukkitItemFactory { @Override protected void merge(ItemWrapper item1, ItemWrapper item2) { // load previous changes on nms items - item1.load(); Object itemStack1 = item1.getLiteralObject(); Object itemStack2 = item2.getLiteralObject(); try { @@ -311,4 +360,28 @@ public class ComponentItemFactory extends BukkitItemFactory { plugin.logger().warn("Failed to merge item", e); } } + + @Override + protected void trim(ItemWrapper item, Trim trim) { + if (trim == null) { + resetComponent(item, ComponentKeys.TRIM); + } else { + setJavaComponentDirectly(item, ComponentKeys.TRIM, Map.of( + "pattern", trim.pattern(), + "material", trim.material() + )); + } + } + + @Override + protected Optional trim(ItemWrapper item) { + if (!item.hasComponent(ComponentKeys.TRIM)) return Optional.empty(); + Optional trim = ComponentType.encodeJava(ComponentKeys.TRIM, item.getComponent(ComponentKeys.TRIM)); + if (trim.isEmpty()) { + return Optional.empty(); + } + @SuppressWarnings("unchecked") + Map trimMap = (Map) trim.get(); + return Optional.of(new Trim(trimMap.get("pattern"), trimMap.get("material"))); + } } \ No newline at end of file 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 850ea9e8a..d87b5dfe0 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 @@ -33,9 +33,9 @@ public class ComponentItemFactory1_21_4 extends ComponentItemFactory { @Override protected void customModelData(ItemWrapper item, Integer data) { if (data == null) { - item.removeComponent(ComponentKeys.CUSTOM_MODEL_DATA); + resetComponent(item, ComponentKeys.CUSTOM_MODEL_DATA); } else { - item.setComponent(ComponentKeys.CUSTOM_MODEL_DATA, Map.of("floats", List.of(data.floatValue()))); + setComponent(item, ComponentKeys.CUSTOM_MODEL_DATA, Map.of("floats", List.of(data.floatValue()))); } } } 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 557420dab..66575ee7e 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 @@ -26,9 +26,9 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { @Override protected void customName(ItemWrapper item, String json) { if (json == null) { - item.removeComponent(ComponentKeys.CUSTOM_NAME); + resetComponent(item, ComponentKeys.CUSTOM_NAME); } else { - item.setComponent(ComponentKeys.CUSTOM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json))); + setJavaComponentDirectly(item, ComponentKeys.CUSTOM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json))); } } @@ -41,9 +41,9 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { @Override protected void itemName(ItemWrapper item, String json) { if (json == null) { - item.removeComponent(ComponentKeys.ITEM_NAME); + resetComponent(item, ComponentKeys.ITEM_NAME); } else { - item.setComponent(ComponentKeys.ITEM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json))); + setJavaComponentDirectly(item, ComponentKeys.ITEM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json))); } } @@ -71,13 +71,13 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { @Override protected void lore(ItemWrapper item, List lore) { if (lore == null || lore.isEmpty()) { - item.removeComponent(ComponentKeys.LORE); + resetComponent(item, ComponentKeys.LORE); } else { List loreTags = new ArrayList<>(); for (String json : lore) { loreTags.add(ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json))); } - item.setComponent(ComponentKeys.LORE, TagList.newTag(loreTags)); + setJavaComponentDirectly(item, ComponentKeys.LORE, TagList.newTag(loreTags)); } } } 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 a592e3b7c..324a799df 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; @@ -8,6 +9,7 @@ import com.saicone.rtag.tag.TagList; import net.momirealms.craftengine.bukkit.item.RTagItemWrapper; import net.momirealms.craftengine.core.item.Enchantment; import net.momirealms.craftengine.core.item.ItemWrapper; +import net.momirealms.craftengine.core.item.Trim; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.SkullUtils; @@ -26,6 +28,36 @@ public class UniversalItemFactory extends BukkitItemFactory { super(plugin); } + @Override + protected void resetComponent(ItemWrapper item, Key type) { + throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); + } + + @Override + protected JsonElement encodeJson(Key type, Object component) { + throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); + } + + @Override + protected void setComponent(ItemWrapper item, Key type, Object value) { + throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); + } + + @Override + protected Object getComponent(ItemWrapper item, Key type) { + throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); + } + + @Override + protected boolean hasComponent(ItemWrapper item, Key type) { + throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); + } + + @Override + protected void removeComponent(ItemWrapper item, Key type) { + throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); + } + @Override public Object encodeJava(Key componentType, @Nullable Object component) { throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); @@ -256,4 +288,22 @@ public class UniversalItemFactory extends BukkitItemFactory { item1.load(); TagCompound.merge(ItemObject.getCustomDataTag(item1.getLiteralObject()), ItemObject.getCustomDataTag(item2.getLiteralObject()), true, true); } + + @Override + protected void trim(ItemWrapper item, Trim trim) { + if (trim == null) { + item.remove("Trim"); + return; + } + item.set(trim.material(), "Trim", "material"); + item.set(trim.pattern(), "Trim", "pattern"); + } + + @Override + protected Optional trim(ItemWrapper item) { + String material = item.get("Trim", "material"); + String pattern = item.get("Trim", "pattern"); + if (material == null || pattern == null) return Optional.empty(); + return Optional.of(new Trim(material, pattern)); + } } \ No newline at end of file diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java index 0d5724a59..ea58f3948 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java @@ -28,7 +28,8 @@ public class TestCommand extends BukkitCommandFeature { ItemStack itemStack = new ItemStack(Material.STONE); RtagItem rtagItem = new RtagItem(itemStack); rtagItem.setComponent(ComponentKeys.CUSTOM_DATA, Map.of("test1", "1")); - rtagItem.setComponent(ComponentKeys.CUSTOM_DATA, Map.of("test2", "2")); + rtagItem.removeComponent(ComponentKeys.CUSTOM_DATA); + rtagItem.removeComponent(ComponentKeys.LORE); player.getInventory().addItem(rtagItem.load()); }); } 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 1d5ffbcbd..d45202853 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,5 +1,6 @@ package net.momirealms.craftengine.core.item; +import com.google.gson.JsonElement; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.util.Key; @@ -95,6 +96,17 @@ public class AbstractItem, I> implements Item { return this; } + @Override + public Item trim(Trim trim) { + this.factory.trim(this.item, trim); + return this; + } + + @Override + public Optional trim() { + return this.factory.trim(this.item); + } + @Override public Item customModelData(Integer data) { this.factory.customModelData(this.item, data); @@ -224,25 +236,40 @@ public class AbstractItem, I> implements Item { } @Override - public boolean hasComponent(String type) { + public boolean hasComponent(Key type) { return this.factory.hasComponent(this.item, type); } @Override - public void removeComponent(String type) { + public void removeComponent(Key type) { this.factory.removeComponent(this.item, type); } @Override - public Object getComponent(String type) { + public Object getComponent(Key type) { return this.factory.getComponent(this.item, type); } @Override - public void setComponent(String type, Object value) { + public Object getJavaTypeComponent(Key type) { + return this.factory.encodeJava(type, getComponent(type)); + } + + @Override + public JsonElement getJsonTypeComponent(Key type) { + return this.factory.encodeJson(type, getComponent(type)); + } + + @Override + public void setComponent(Key type, Object value) { this.factory.setComponent(this.item, type, value); } + @Override + public void resetComponent(Key type) { + this.factory.resetComponent(this.item, type); + } + @Override public I getItem() { return this.factory.getItem(this.item); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java b/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java index f0205d6ed..30e2be9ce 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java @@ -3,22 +3,23 @@ package net.momirealms.craftengine.core.item; import net.momirealms.craftengine.core.util.Key; public class ComponentKeys { - public static final String CUSTOM_MODEL_DATA = Key.of("minecraft", "custom_model_data").toString(); - public static final String CUSTOM_NAME = Key.of("minecraft", "custom_name").toString(); - public static final String ITEM_NAME = Key.of("minecraft", "item_name").toString(); - public static final String LORE = Key.of("minecraft", "lore").toString(); - public static final String DAMAGE = Key.of("minecraft", "damage").toString(); - public static final String MAX_DAMAGE = Key.of("minecraft", "max_damage").toString(); - public static final String ENCHANTMENT_GLINT_OVERRIDE = Key.of("minecraft", "enchantment_glint_override").toString(); - public static final String ENCHANTMENTS = Key.of("minecraft", "enchantments").toString(); - public static final String STORED_ENCHANTMENTS = Key.of("minecraft", "stored_enchantments").toString(); - public static final String UNBREAKABLE = Key.of("minecraft", "unbreakable").toString(); - public static final String MAX_STACK_SIZE = Key.of("minecraft", "max_stack_size").toString(); - public static final String EQUIPPABLE = Key.of("minecraft", "equippable").toString(); - public static final String ITEM_MODEL = Key.of("minecraft", "item_model").toString(); - public static final String TOOLTIP_STYLE = Key.of("minecraft", "tooltip_style").toString(); - public static final String JUKEBOX_PLAYABLE = Key.of("minecraft", "jukebox_playable").toString(); - public static final String TRIM = Key.of("minecraft", "trim").toString(); - public static final String REPAIR_COST = Key.of("minecraft", "repair_cost").toString(); - public static final String CUSTOM_DATA = Key.of("minecraft", "custom_data").toString(); + public static final Key CUSTOM_MODEL_DATA = Key.of("minecraft", "custom_model_data"); + public static final Key CUSTOM_NAME = Key.of("minecraft", "custom_name"); + public static final Key ITEM_NAME = Key.of("minecraft", "item_name"); + public static final Key LORE = Key.of("minecraft", "lore"); + public static final Key DAMAGE = Key.of("minecraft", "damage"); + public static final Key MAX_DAMAGE = Key.of("minecraft", "max_damage"); + public static final Key ENCHANTMENT_GLINT_OVERRIDE = Key.of("minecraft", "enchantment_glint_override"); + public static final Key ENCHANTMENTS = Key.of("minecraft", "enchantments"); + public static final Key STORED_ENCHANTMENTS = Key.of("minecraft", "stored_enchantments"); + public static final Key UNBREAKABLE = Key.of("minecraft", "unbreakable"); + public static final Key MAX_STACK_SIZE = Key.of("minecraft", "max_stack_size"); + public static final Key EQUIPPABLE = Key.of("minecraft", "equippable"); + public static final Key ITEM_MODEL = Key.of("minecraft", "item_model"); + public static final Key TOOLTIP_STYLE = Key.of("minecraft", "tooltip_style"); + public static final Key JUKEBOX_PLAYABLE = Key.of("minecraft", "jukebox_playable"); + public static final Key TRIM = Key.of("minecraft", "trim"); + public static final Key REPAIR_COST = Key.of("minecraft", "repair_cost"); + public static final Key CUSTOM_DATA = Key.of("minecraft", "custom_data"); + public static final Key PROFILE = Key.of("minecraft", "profile"); } 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 3895da0db..6ec67c438 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,5 +1,6 @@ package net.momirealms.craftengine.core.item; +import com.google.gson.JsonElement; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.util.Key; @@ -33,6 +34,10 @@ public interface Item { Item count(int amount); + Item trim(Trim trim); + + Optional trim(); + Item customModelData(Integer data); Optional customModelData(); @@ -91,13 +96,19 @@ public interface Item { boolean removeTag(Object... path); - boolean hasComponent(String type); + boolean hasComponent(Key type); - void removeComponent(String type); + void removeComponent(Key type); - Object getComponent(String type); + Object getComponent(Key type); - void setComponent(String type, Object value); + Object getJavaTypeComponent(Key type); + + JsonElement getJsonTypeComponent(Key type); + + void setComponent(Key type, Object value); + + void resetComponent(Key type); I getItem(); 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 c65a15740..ab36b86ad 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,5 +1,6 @@ package net.momirealms.craftengine.core.item; +import com.google.gson.JsonElement; import net.momirealms.craftengine.core.plugin.Plugin; import net.momirealms.craftengine.core.util.Key; import org.jetbrains.annotations.Nullable; @@ -22,6 +23,8 @@ public abstract class ItemFactory

, I> public abstract Object encodeJava(Key componentType, @Nullable Object component); + protected abstract JsonElement encodeJson(Key type, Object component); + protected abstract ItemWrapper wrapInternal(I item); protected abstract Object getTag(ItemWrapper item, Object... path); @@ -32,13 +35,15 @@ public abstract class ItemFactory

, I> protected abstract boolean removeTag(ItemWrapper item, Object... path); - protected abstract void setComponent(ItemWrapper item, String type, Object value); + protected abstract void setComponent(ItemWrapper item, Key type, Object value); - protected abstract Object getComponent(ItemWrapper item, String type); + protected abstract Object getComponent(ItemWrapper item, Key type); - protected abstract boolean hasComponent(ItemWrapper item, String type); + protected abstract boolean hasComponent(ItemWrapper item, Key type); - protected abstract void removeComponent(ItemWrapper item, String type); + protected abstract void removeComponent(ItemWrapper item, Key type); + + protected abstract void resetComponent(ItemWrapper item, Key type); protected abstract void update(ItemWrapper item); @@ -112,6 +117,10 @@ public abstract class ItemFactory

, I> protected abstract Optional repairCost(ItemWrapper item); + protected abstract void trim(ItemWrapper item, Trim trim); + + protected abstract Optional trim(ItemWrapper item); + protected abstract ItemWrapper mergeCopy(ItemWrapper item1, ItemWrapper item2); protected abstract void merge(ItemWrapper item1, ItemWrapper item2); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/Trim.java b/core/src/main/java/net/momirealms/craftengine/core/item/Trim.java new file mode 100644 index 000000000..4832e81fe --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/Trim.java @@ -0,0 +1,4 @@ +package net.momirealms.craftengine.core.item; + +public record Trim(String pattern, String material) { +} 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 2025d332f..6e3aa1069 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 @@ -1,7 +1,12 @@ package net.momirealms.craftengine.core.item.modifier; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.util.GsonHelper; +import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Pair; import java.util.ArrayList; @@ -9,16 +14,42 @@ import java.util.List; import java.util.Map; public class ComponentModifier implements ItemDataModifier { - private final List> arguments; + private final List> arguments; + private JsonObject customData = null; public ComponentModifier(Map arguments) { - List> pairs = new ArrayList<>(arguments.size()); + List> pairs = new ArrayList<>(arguments.size()); for (Map.Entry entry : arguments.entrySet()) { - pairs.add(new Pair<>(entry.getKey(), entry.getValue())); + Key key = Key.of(entry.getKey()); + if (key.equals(ComponentKeys.CUSTOM_DATA)) { + this.customData = parseJsonObjectValue(entry.getValue()); + } else { + pairs.add(new Pair<>(key, parseValue(entry.getValue()))); + } } this.arguments = pairs; } + private Object parseValue(Object value) { + if (value instanceof String string) { + if (string.startsWith("(json) ")) { + return GsonHelper.get().fromJson(string.substring("(json) ".length()), JsonElement.class); + } + } + return value; + } + + private JsonObject parseJsonObjectValue(Object value) { + if (value instanceof String string) { + if (string.startsWith("(json) ")) { + return GsonHelper.get().fromJson(string.substring("(json) ".length()), JsonObject.class); + } + } else if (value instanceof Map map) { + return (JsonObject) GsonHelper.get().toJsonTree(map, Map.class); + } + throw new UnsupportedOperationException("Invalid minecraft:custom_data value: " + value.toString()); + } + @Override public String name() { return "components"; @@ -26,15 +57,33 @@ public class ComponentModifier implements ItemDataModifier { @Override public void apply(Item item, ItemBuildContext context) { - for (Pair entry : this.arguments) { + for (Pair entry : this.arguments) { item.setComponent(entry.left(), entry.right()); } + if (this.customData != null) { + JsonObject tag = (JsonObject) item.getJsonTypeComponent(ComponentKeys.CUSTOM_DATA); + if (tag != null) { + item.setComponent(ComponentKeys.CUSTOM_DATA, GsonHelper.shallowMerge(this.customData, tag)); + } else { + item.setComponent(ComponentKeys.CUSTOM_DATA, this.customData); + } + } } @Override public void remove(Item item) { - for (Pair entry : this.arguments) { - item.removeComponent(entry.left()); + for (Pair entry : this.arguments) { + item.resetComponent(entry.left()); + } + if (this.customData != null) { + JsonObject tag = (JsonObject) item.getJsonTypeComponent(ComponentKeys.CUSTOM_DATA); + if (tag != null) { + // crude method + for (String key : this.customData.keySet()) { + tag.remove(key); + } + item.setComponent(ComponentKeys.CUSTOM_DATA, tag); + } } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/IdModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/IdModifier.java index c08187ee2..782f0a36e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/IdModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/IdModifier.java @@ -1,8 +1,12 @@ package net.momirealms.craftengine.core.item.modifier; +import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.VersionHelper; + +import java.util.Map; public class IdModifier implements ItemDataModifier { public static final String CRAFT_ENGINE_ID = "craftengine:id"; @@ -19,7 +23,11 @@ public class IdModifier implements ItemDataModifier { @Override public void apply(Item item, ItemBuildContext context) { - item.setTag(argument.toString(), CRAFT_ENGINE_ID); + if (VersionHelper.isVersionNewerThan1_20_5()) { + item.setComponent(ComponentKeys.CUSTOM_DATA, Map.of(CRAFT_ENGINE_ID, argument.toString())); + } else { + item.setTag(argument.toString(), CRAFT_ENGINE_ID); + } } @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TrimModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TrimModifier.java index fd09e17b8..89777acd2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TrimModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/TrimModifier.java @@ -3,10 +3,9 @@ package net.momirealms.craftengine.core.item.modifier; import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.Trim; import net.momirealms.craftengine.core.util.VersionHelper; -import java.util.Map; - public class TrimModifier implements ItemDataModifier { private final String material; private final String pattern; @@ -23,19 +22,18 @@ public class TrimModifier implements ItemDataModifier { @Override public void apply(Item item, ItemBuildContext context) { + item.trim(new Trim(this.material, this.pattern)); + if (VersionHelper.isVersionNewerThan1_20_5()) { - item.setComponent(ComponentKeys.TRIM, Map.of( - "pattern", this.pattern, - "material", this.material - )); + } else { - item.setTag(this.material, "Trim", "material"); - item.setTag(this.pattern, "Trim", "pattern"); + } } @Override public void remove(Item item) { + item.trim(null); if (VersionHelper.isVersionNewerThan1_20_5()) { item.removeComponent(ComponentKeys.TRIM); } else { 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 46f9e9909..309a5e41f 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 @@ -217,9 +217,9 @@ 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.toString()); + Object componentObj = item1.getComponent(component); if (componentObj != null) { - item3.setComponent(component.toString(), CraftEngine.instance().itemManager().encodeJava(component, componentObj)); + item3.setComponent(component, componentObj); } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index 24d1cda5a..07f36dfdd 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -233,7 +233,6 @@ public abstract class AbstractPackManager implements PackManager { Files.createDirectories(resourcesFolder); this.saveDefaultConfigs(); } - try (DirectoryStream paths = Files.newDirectoryStream(resourcesFolder)) { for (Path path : paths) { if (!Files.isDirectory(path)) { @@ -247,6 +246,9 @@ public abstract class AbstractPackManager implements PackManager { String author = null; if (Files.exists(metaFile) && Files.isRegularFile(metaFile)) { YamlDocument metaYML = Config.instance().loadYamlData(metaFile.toFile()); + if (!metaYML.getBoolean("enable", true)) { + continue; + } namespace = metaYML.getString("namespace", namespace); description = metaYML.getString("description"); version = metaYML.getString("version"); diff --git a/gradle.properties b/gradle.properties index e889758ae..fdadab3ea 100644 --- a/gradle.properties +++ b/gradle.properties @@ -51,7 +51,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.13 -nms_helper_version=0.57 +nms_helper_version=0.57.3 # Ignite Dependencies mixinextras_version=0.4.1 mixin_version=0.15.2+mixin.0.8.7 diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/block/CraftEngineBlock.java similarity index 99% rename from server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java rename to server-mod/src/main/java/net/momirealms/craftengine/mod/block/CraftEngineBlock.java index f7d481ee7..8b3039c7b 100644 --- a/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/block/CraftEngineBlock.java @@ -1,4 +1,4 @@ -package net.momirealms.craftengine.mod; +package net.momirealms.craftengine.mod.block; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -14,6 +14,7 @@ import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; +import net.momirealms.craftengine.mod.CraftEnginePlugin; import net.momirealms.craftengine.mod.util.NoteBlockUtils; import net.momirealms.craftengine.shared.ObjectHolder; import net.momirealms.craftengine.shared.block.*; diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/StoneBlockShape.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java similarity index 93% rename from server-mod/src/main/java/net/momirealms/craftengine/mod/StoneBlockShape.java rename to server-mod/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java index be7f4aa76..6ebc977a6 100644 --- a/server-mod/src/main/java/net/momirealms/craftengine/mod/StoneBlockShape.java +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/block/StoneBlockShape.java @@ -1,4 +1,4 @@ -package net.momirealms.craftengine.mod; +package net.momirealms.craftengine.mod.block; import net.minecraft.core.BlockPos; import net.minecraft.world.level.BlockGetter; diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/item/CustomStreamCodec.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/item/CustomStreamCodec.java new file mode 100644 index 000000000..2d1a47861 --- /dev/null +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/item/CustomStreamCodec.java @@ -0,0 +1,41 @@ +package net.momirealms.craftengine.mod.item; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; +import java.util.function.Function; + +public class CustomStreamCodec implements StreamCodec { + public static Function clientBoundDataProcessor; + public static Function serverBoundDataProcessor; + + private final StreamCodec original; + + public CustomStreamCodec(StreamCodec original) { + this.original = Objects.requireNonNull(original); + } + + @Override + public @NotNull ItemStack decode(@NotNull RegistryFriendlyByteBuf buffer) { + ItemStack itemStack = this.original.decode(buffer); + if (!itemStack.isEmpty()) { + if (serverBoundDataProcessor != null) { + itemStack = serverBoundDataProcessor.apply(itemStack); + } + } + return itemStack; + } + + @Override + public void encode(@NotNull RegistryFriendlyByteBuf buffer, @NotNull ItemStack value) { + if (!value.isEmpty()) { + if (clientBoundDataProcessor != null) { + value = clientBoundDataProcessor.apply(value); + } + } + this.original.encode(buffer, value); + } +} \ No newline at end of file diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/MixinBlocks.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/BlocksMixin.java similarity index 98% rename from server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/MixinBlocks.java rename to server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/BlocksMixin.java index ebae61b28..451ee115c 100644 --- a/server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/MixinBlocks.java +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/BlocksMixin.java @@ -11,8 +11,8 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; -import net.momirealms.craftengine.mod.CraftEngineBlock; import net.momirealms.craftengine.mod.CraftEnginePlugin; +import net.momirealms.craftengine.mod.block.CraftEngineBlock; import net.momirealms.craftengine.mod.util.NoteBlockUtils; import org.bukkit.configuration.file.YamlConfiguration; import org.spongepowered.asm.mixin.Mixin; @@ -27,7 +27,7 @@ import java.util.LinkedHashMap; import java.util.Map; @Mixin(value = Blocks.class) -public abstract class MixinBlocks { +public abstract class BlocksMixin { @Inject(method = "", at = @At("RETURN")) private static void onBlocksInit(CallbackInfo ci) { diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/ItemStackMixin.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/ItemStackMixin.java new file mode 100644 index 000000000..726e9981d --- /dev/null +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/ItemStackMixin.java @@ -0,0 +1,48 @@ +package net.momirealms.craftengine.mod.mixin; + +import net.minecraft.core.NonNullList; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.item.ItemStack; +import net.momirealms.craftengine.mod.item.CustomStreamCodec; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(ItemStack.class) +public abstract class ItemStackMixin { + @Shadow(remap = false) + @Mutable + public static StreamCodec OPTIONAL_STREAM_CODEC; + @Shadow(remap = false) + @Mutable + public static StreamCodec> OPTIONAL_LIST_STREAM_CODEC; + + private static StreamCodec ORIGINAL_OPTIONAL_STREAM_CODEC; + + @Inject( + method = "", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/item/ItemStack;OPTIONAL_STREAM_CODEC:Lnet/minecraft/network/codec/StreamCodec;", + opcode = Opcodes.PUTSTATIC, + shift = At.Shift.AFTER + ) + ) + private static void captureOriginalAfterAssignment(CallbackInfo ci) { + ORIGINAL_OPTIONAL_STREAM_CODEC = OPTIONAL_STREAM_CODEC; + } + + @Inject(method = "", at = @At("RETURN")) + private static void replaceStreamCodec(CallbackInfo ci) { + OPTIONAL_STREAM_CODEC = new CustomStreamCodec(ORIGINAL_OPTIONAL_STREAM_CODEC); + OPTIONAL_LIST_STREAM_CODEC = OPTIONAL_STREAM_CODEC.apply(ByteBufCodecs.collection(NonNullList::createWithCapacity)); + } +} diff --git a/server-mod/src/main/resources/mixins.craftengine.json b/server-mod/src/main/resources/mixins.craftengine.json index 2e9a8087a..288b6501f 100644 --- a/server-mod/src/main/resources/mixins.craftengine.json +++ b/server-mod/src/main/resources/mixins.craftengine.json @@ -6,6 +6,7 @@ "target": "@env(DEFAULT)", "compatibilityLevel": "JAVA_21", "server": [ - "MixinBlocks" + "BlocksMixin", + "ItemStackMixin" ] }