9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-23 17:09:19 +00:00

优化component实现

This commit is contained in:
XiaoMoMi
2025-04-14 02:27:57 +08:00
parent b63625ba20
commit b327ed11d5
24 changed files with 433 additions and 129 deletions

View File

@@ -118,7 +118,7 @@ public class BukkitCustomItem implements CustomItem<ItemStack> {
@Override @Override
public ItemSettings settings() { public ItemSettings settings() {
return settings; return this.settings;
} }
@Override @Override

View File

@@ -89,26 +89,6 @@ public abstract class BukkitItemFactory extends ItemFactory<CraftEngine, RTagIte
return item.remove(path); return item.remove(path);
} }
@Override
protected void setComponent(ItemWrapper<ItemStack> item, String type, Object value) {
item.setComponent(type, value);
}
@Override
protected Object getComponent(ItemWrapper<ItemStack> item, String type) {
return item.getComponent(type);
}
@Override
protected boolean hasComponent(ItemWrapper<ItemStack> item, String type) {
return item.hasComponent(type);
}
@Override
protected void removeComponent(ItemWrapper<ItemStack> item, String type) {
item.removeComponent(type);
}
@Override @Override
protected void update(ItemWrapper<ItemStack> item) { protected void update(ItemWrapper<ItemStack> item) {
item.update(); item.update();

View File

@@ -1,14 +1,18 @@
package net.momirealms.craftengine.bukkit.item.factory; package net.momirealms.craftengine.bukkit.item.factory;
import com.google.gson.JsonElement;
import com.saicone.rtag.RtagItem; import com.saicone.rtag.RtagItem;
import com.saicone.rtag.data.ComponentType; import com.saicone.rtag.data.ComponentType;
import com.saicone.rtag.item.ItemObject; import com.saicone.rtag.item.ItemObject;
import net.momirealms.craftengine.bukkit.item.RTagItemWrapper; 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.EnchantmentUtils;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.ComponentKeys;
import net.momirealms.craftengine.core.item.Enchantment; import net.momirealms.craftengine.core.item.Enchantment;
import net.momirealms.craftengine.core.item.ItemWrapper; 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.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -26,17 +30,59 @@ public class ComponentItemFactory extends BukkitItemFactory {
super(plugin); super(plugin);
} }
@Override
protected void setComponent(ItemWrapper<ItemStack> item, Key type, Object value) {
if (value instanceof JsonElement jsonElement) {
setJsonComponentDirectly(item, type, jsonElement);
} else {
setJavaComponentDirectly(item, type, value);
}
}
@Override
protected void resetComponent(ItemWrapper<ItemStack> item, Key type) {
FastNMS.INSTANCE.resetComponent(item.getLiteralObject(), KeyUtils.toResourceLocation(type));
}
@Override
protected Object getComponent(ItemWrapper<ItemStack> item, Key type) {
return item.getComponent(type);
}
@Override
protected boolean hasComponent(ItemWrapper<ItemStack> item, Key type) {
return item.hasComponent(type);
}
@Override
protected void removeComponent(ItemWrapper<ItemStack> item, Key type) {
FastNMS.INSTANCE.removeComponent(item.getLiteralObject(), KeyUtils.toResourceLocation(type));
}
protected void setJavaComponentDirectly(ItemWrapper<ItemStack> item, Key type, Object value) {
ComponentType.parseJava(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(item.getLiteralObject(), KeyUtils.toResourceLocation(type), it));
}
protected void setJsonComponentDirectly(ItemWrapper<ItemStack> item, Key type, JsonElement value) {
ComponentType.parseJson(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(item.getLiteralObject(), KeyUtils.toResourceLocation(type), it));
}
@Override @Override
public Object encodeJava(Key componentType, @Nullable Object component) { public Object encodeJava(Key componentType, @Nullable Object component) {
return ComponentType.encodeJava(componentType, component).orElse(null); return ComponentType.encodeJava(componentType, component).orElse(null);
} }
@Override
protected JsonElement encodeJson(Key type, Object component) {
return ComponentType.encodeJson(type, component).orElse(null);
}
@Override @Override
protected void customModelData(ItemWrapper<ItemStack> item, Integer data) { protected void customModelData(ItemWrapper<ItemStack> item, Integer data) {
if (data == null) { if (data == null) {
item.removeComponent(ComponentKeys.CUSTOM_MODEL_DATA); resetComponent(item, ComponentKeys.CUSTOM_MODEL_DATA);
} else { } 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 @Override
protected void customName(ItemWrapper<ItemStack> item, String json) { protected void customName(ItemWrapper<ItemStack> item, String json) {
if (json == null) { if (json == null) {
item.removeComponent(ComponentKeys.CUSTOM_NAME); resetComponent(item, ComponentKeys.CUSTOM_NAME);
} else { } else {
item.setComponent(ComponentKeys.CUSTOM_NAME, json); setJavaComponentDirectly(item, ComponentKeys.CUSTOM_NAME, json);
} }
} }
@@ -73,9 +119,9 @@ public class ComponentItemFactory extends BukkitItemFactory {
@Override @Override
protected void itemName(ItemWrapper<ItemStack> item, String json) { protected void itemName(ItemWrapper<ItemStack> item, String json) {
if (json == null) { if (json == null) {
item.removeComponent(ComponentKeys.ITEM_NAME); resetComponent(item, ComponentKeys.ITEM_NAME);
} else { } else {
item.setComponent(ComponentKeys.ITEM_NAME, json); setJavaComponentDirectly(item, ComponentKeys.ITEM_NAME, json);
} }
} }
@@ -92,15 +138,12 @@ public class ComponentItemFactory extends BukkitItemFactory {
@Override @Override
protected void skull(ItemWrapper<ItemStack> item, String skullData) { protected void skull(ItemWrapper<ItemStack> item, String skullData) {
final Map<String, Object> profile = Map.of( if (skullData == null) {
"properties", List.of( resetComponent(item, ComponentKeys.PROFILE);
Map.of( } else {
"name", "textures", Map<String, Object> profile = Map.of("properties", List.of(Map.of("name", "textures", "value", skullData)));
"value", skullData setJavaComponentDirectly(item, ComponentKeys.PROFILE, profile);
) }
)
);
item.setComponent("minecraft:profile", profile);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -118,9 +161,9 @@ public class ComponentItemFactory extends BukkitItemFactory {
@Override @Override
protected void lore(ItemWrapper<ItemStack> item, List<String> lore) { protected void lore(ItemWrapper<ItemStack> item, List<String> lore) {
if (lore == null || lore.isEmpty()) { if (lore == null || lore.isEmpty()) {
item.removeComponent(ComponentKeys.LORE); resetComponent(item, ComponentKeys.LORE);
} else { } else {
item.setComponent(ComponentKeys.LORE, lore); setJavaComponentDirectly(item, ComponentKeys.LORE, lore);
} }
} }
@@ -132,9 +175,9 @@ public class ComponentItemFactory extends BukkitItemFactory {
@Override @Override
protected void unbreakable(ItemWrapper<ItemStack> item, boolean unbreakable) { protected void unbreakable(ItemWrapper<ItemStack> item, boolean unbreakable) {
if (unbreakable) { if (unbreakable) {
item.removeComponent(ComponentKeys.UNBREAKABLE); resetComponent(item, ComponentKeys.UNBREAKABLE);
} else { } else {
item.setComponent(ComponentKeys.UNBREAKABLE, true); setJavaComponentDirectly(item, ComponentKeys.UNBREAKABLE, true);
} }
} }
@@ -145,7 +188,11 @@ public class ComponentItemFactory extends BukkitItemFactory {
@Override @Override
protected void glint(ItemWrapper<ItemStack> item, Boolean glint) { protected void glint(ItemWrapper<ItemStack> 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 @Override
@@ -161,8 +208,11 @@ public class ComponentItemFactory extends BukkitItemFactory {
@Override @Override
protected void damage(ItemWrapper<ItemStack> item, Integer damage) { protected void damage(ItemWrapper<ItemStack> item, Integer damage) {
if (damage == null) damage = 0; if (damage == null) {
item.setComponent(ComponentKeys.DAMAGE, damage); resetComponent(item, ComponentKeys.DAMAGE);
} else {
setJavaComponentDirectly(item, ComponentKeys.DAMAGE, damage);
}
} }
@Override @Override
@@ -179,9 +229,9 @@ public class ComponentItemFactory extends BukkitItemFactory {
@Override @Override
protected void maxDamage(ItemWrapper<ItemStack> item, Integer damage) { protected void maxDamage(ItemWrapper<ItemStack> item, Integer damage) {
if (damage == null) { if (damage == null) {
item.removeComponent(ComponentKeys.MAX_DAMAGE); resetComponent(item, ComponentKeys.MAX_DAMAGE);
} else { } else {
item.setComponent(ComponentKeys.MAX_DAMAGE, damage); setJavaComponentDirectly(item, ComponentKeys.MAX_DAMAGE, damage);
} }
} }
@@ -202,27 +252,27 @@ public class ComponentItemFactory extends BukkitItemFactory {
@Override @Override
protected void enchantments(ItemWrapper<ItemStack> item, List<Enchantment> enchantments) { protected void enchantments(ItemWrapper<ItemStack> item, List<Enchantment> enchantments) {
if (enchantments == null || enchantments.isEmpty()) { if (enchantments == null || enchantments.isEmpty()) {
item.removeComponent(ComponentKeys.ENCHANTMENTS); resetComponent(item, ComponentKeys.ENCHANTMENTS);
return; } else {
Map<String, Integer> enchants = new HashMap<>();
for (Enchantment enchantment : enchantments) {
enchants.put(enchantment.id().toString(), enchantment.level());
}
setJavaComponentDirectly(item, ComponentKeys.ENCHANTMENTS, enchants);
} }
Map<String, Integer> enchants = new HashMap<>();
for (Enchantment enchantment : enchantments) {
enchants.put(enchantment.id().toString(), enchantment.level());
}
item.setComponent(ComponentKeys.ENCHANTMENTS, enchants);
} }
@Override @Override
protected void storedEnchantments(ItemWrapper<ItemStack> item, List<Enchantment> enchantments) { protected void storedEnchantments(ItemWrapper<ItemStack> item, List<Enchantment> enchantments) {
if (enchantments == null || enchantments.isEmpty()) { if (enchantments == null || enchantments.isEmpty()) {
item.removeComponent(ComponentKeys.STORED_ENCHANTMENTS); resetComponent(item, ComponentKeys.STORED_ENCHANTMENTS);
return; } else {
Map<String, Integer> enchants = new HashMap<>();
for (Enchantment enchantment : enchantments) {
enchants.put(enchantment.id().toString(), enchantment.level());
}
setJavaComponentDirectly(item, ComponentKeys.STORED_ENCHANTMENTS, enchants);
} }
Map<String, Integer> enchants = new HashMap<>();
for (Enchantment enchantment : enchantments) {
enchants.put(enchantment.id().toString(), enchantment.level());
}
item.setComponent(ComponentKeys.STORED_ENCHANTMENTS, enchants);
} }
@Override @Override
@@ -231,7 +281,7 @@ public class ComponentItemFactory extends BukkitItemFactory {
try { try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant); Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
map.put(enchantment.toString(), enchantment.level()); map.put(enchantment.toString(), enchantment.level());
item.setComponent(ComponentKeys.ENCHANTMENTS, map); setJavaComponentDirectly(item, ComponentKeys.ENCHANTMENTS, map);
} catch (ReflectiveOperationException e) { } catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to add enchantment", e); plugin.logger().warn("Failed to add enchantment", e);
} }
@@ -243,7 +293,7 @@ public class ComponentItemFactory extends BukkitItemFactory {
try { try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant); Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
map.put(enchantment.toString(), enchantment.level()); map.put(enchantment.toString(), enchantment.level());
item.setComponent(ComponentKeys.STORED_ENCHANTMENTS, map); setJavaComponentDirectly(item, ComponentKeys.STORED_ENCHANTMENTS, map);
} catch (ReflectiveOperationException e) { } catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to add stored enchantment", e); plugin.logger().warn("Failed to add stored enchantment", e);
} }
@@ -264,18 +314,18 @@ public class ComponentItemFactory extends BukkitItemFactory {
@Override @Override
protected void maxStackSize(ItemWrapper<ItemStack> item, Integer maxStackSize) { protected void maxStackSize(ItemWrapper<ItemStack> item, Integer maxStackSize) {
if (maxStackSize == null) { if (maxStackSize == null) {
item.removeComponent(ComponentKeys.MAX_STACK_SIZE); resetComponent(item, ComponentKeys.MAX_STACK_SIZE);
} else { } else {
item.setComponent(ComponentKeys.MAX_STACK_SIZE, maxStackSize); setJavaComponentDirectly(item, ComponentKeys.MAX_STACK_SIZE, maxStackSize);
} }
} }
@Override @Override
protected void repairCost(ItemWrapper<ItemStack> item, Integer data) { protected void repairCost(ItemWrapper<ItemStack> item, Integer data) {
if (data == null) { if (data == null) {
item.removeComponent(ComponentKeys.REPAIR_COST); resetComponent(item, ComponentKeys.REPAIR_COST);
} else { } else {
item.setComponent(ComponentKeys.REPAIR_COST, data); setJavaComponentDirectly(item, ComponentKeys.REPAIR_COST, data);
} }
} }
@@ -302,7 +352,6 @@ public class ComponentItemFactory extends BukkitItemFactory {
@Override @Override
protected void merge(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) { protected void merge(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) {
// load previous changes on nms items // load previous changes on nms items
item1.load();
Object itemStack1 = item1.getLiteralObject(); Object itemStack1 = item1.getLiteralObject();
Object itemStack2 = item2.getLiteralObject(); Object itemStack2 = item2.getLiteralObject();
try { try {
@@ -311,4 +360,28 @@ public class ComponentItemFactory extends BukkitItemFactory {
plugin.logger().warn("Failed to merge item", e); plugin.logger().warn("Failed to merge item", e);
} }
} }
@Override
protected void trim(ItemWrapper<ItemStack> 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> trim(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.TRIM)) return Optional.empty();
Optional<Object> trim = ComponentType.encodeJava(ComponentKeys.TRIM, item.getComponent(ComponentKeys.TRIM));
if (trim.isEmpty()) {
return Optional.empty();
}
@SuppressWarnings("unchecked")
Map<String, String> trimMap = (Map<String, String>) trim.get();
return Optional.of(new Trim(trimMap.get("pattern"), trimMap.get("material")));
}
} }

View File

@@ -33,9 +33,9 @@ public class ComponentItemFactory1_21_4 extends ComponentItemFactory {
@Override @Override
protected void customModelData(ItemWrapper<ItemStack> item, Integer data) { protected void customModelData(ItemWrapper<ItemStack> item, Integer data) {
if (data == null) { if (data == null) {
item.removeComponent(ComponentKeys.CUSTOM_MODEL_DATA); resetComponent(item, ComponentKeys.CUSTOM_MODEL_DATA);
} else { } 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())));
} }
} }
} }

View File

@@ -26,9 +26,9 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 {
@Override @Override
protected void customName(ItemWrapper<ItemStack> item, String json) { protected void customName(ItemWrapper<ItemStack> item, String json) {
if (json == null) { if (json == null) {
item.removeComponent(ComponentKeys.CUSTOM_NAME); resetComponent(item, ComponentKeys.CUSTOM_NAME);
} else { } 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 @Override
protected void itemName(ItemWrapper<ItemStack> item, String json) { protected void itemName(ItemWrapper<ItemStack> item, String json) {
if (json == null) { if (json == null) {
item.removeComponent(ComponentKeys.ITEM_NAME); resetComponent(item, ComponentKeys.ITEM_NAME);
} else { } 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 @Override
protected void lore(ItemWrapper<ItemStack> item, List<String> lore) { protected void lore(ItemWrapper<ItemStack> item, List<String> lore) {
if (lore == null || lore.isEmpty()) { if (lore == null || lore.isEmpty()) {
item.removeComponent(ComponentKeys.LORE); resetComponent(item, ComponentKeys.LORE);
} else { } else {
List<Object> loreTags = new ArrayList<>(); List<Object> loreTags = new ArrayList<>();
for (String json : lore) { for (String json : lore) {
loreTags.add(ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json))); loreTags.add(ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json)));
} }
item.setComponent(ComponentKeys.LORE, TagList.newTag(loreTags)); setJavaComponentDirectly(item, ComponentKeys.LORE, TagList.newTag(loreTags));
} }
} }
} }

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.bukkit.item.factory; package net.momirealms.craftengine.bukkit.item.factory;
import com.google.gson.JsonElement;
import com.saicone.rtag.RtagItem; import com.saicone.rtag.RtagItem;
import com.saicone.rtag.item.ItemObject; import com.saicone.rtag.item.ItemObject;
import com.saicone.rtag.tag.TagBase; 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.bukkit.item.RTagItemWrapper;
import net.momirealms.craftengine.core.item.Enchantment; import net.momirealms.craftengine.core.item.Enchantment;
import net.momirealms.craftengine.core.item.ItemWrapper; 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.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.SkullUtils; import net.momirealms.craftengine.core.util.SkullUtils;
@@ -26,6 +28,36 @@ public class UniversalItemFactory extends BukkitItemFactory {
super(plugin); super(plugin);
} }
@Override
protected void resetComponent(ItemWrapper<ItemStack> 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<ItemStack> item, Key type, Object value) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected Object getComponent(ItemWrapper<ItemStack> item, Key type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected boolean hasComponent(ItemWrapper<ItemStack> item, Key type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void removeComponent(ItemWrapper<ItemStack> item, Key type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override @Override
public Object encodeJava(Key componentType, @Nullable Object component) { public Object encodeJava(Key componentType, @Nullable Object component) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+"); throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
@@ -256,4 +288,22 @@ public class UniversalItemFactory extends BukkitItemFactory {
item1.load(); item1.load();
TagCompound.merge(ItemObject.getCustomDataTag(item1.getLiteralObject()), ItemObject.getCustomDataTag(item2.getLiteralObject()), true, true); TagCompound.merge(ItemObject.getCustomDataTag(item1.getLiteralObject()), ItemObject.getCustomDataTag(item2.getLiteralObject()), true, true);
} }
@Override
protected void trim(ItemWrapper<ItemStack> 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> trim(ItemWrapper<ItemStack> 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));
}
} }

View File

@@ -28,7 +28,8 @@ public class TestCommand extends BukkitCommandFeature<CommandSender> {
ItemStack itemStack = new ItemStack(Material.STONE); ItemStack itemStack = new ItemStack(Material.STONE);
RtagItem rtagItem = new RtagItem(itemStack); RtagItem rtagItem = new RtagItem(itemStack);
rtagItem.setComponent(ComponentKeys.CUSTOM_DATA, Map.of("test1", "1")); 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()); player.getInventory().addItem(rtagItem.load());
}); });
} }

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.core.item; package net.momirealms.craftengine.core.item;
import com.google.gson.JsonElement;
import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;
@@ -95,6 +96,17 @@ public class AbstractItem<W extends ItemWrapper<I>, I> implements Item<I> {
return this; return this;
} }
@Override
public Item<I> trim(Trim trim) {
this.factory.trim(this.item, trim);
return this;
}
@Override
public Optional<Trim> trim() {
return this.factory.trim(this.item);
}
@Override @Override
public Item<I> customModelData(Integer data) { public Item<I> customModelData(Integer data) {
this.factory.customModelData(this.item, data); this.factory.customModelData(this.item, data);
@@ -224,25 +236,40 @@ public class AbstractItem<W extends ItemWrapper<I>, I> implements Item<I> {
} }
@Override @Override
public boolean hasComponent(String type) { public boolean hasComponent(Key type) {
return this.factory.hasComponent(this.item, type); return this.factory.hasComponent(this.item, type);
} }
@Override @Override
public void removeComponent(String type) { public void removeComponent(Key type) {
this.factory.removeComponent(this.item, type); this.factory.removeComponent(this.item, type);
} }
@Override @Override
public Object getComponent(String type) { public Object getComponent(Key type) {
return this.factory.getComponent(this.item, type); return this.factory.getComponent(this.item, type);
} }
@Override @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); this.factory.setComponent(this.item, type, value);
} }
@Override
public void resetComponent(Key type) {
this.factory.resetComponent(this.item, type);
}
@Override @Override
public I getItem() { public I getItem() {
return this.factory.getItem(this.item); return this.factory.getItem(this.item);

View File

@@ -3,22 +3,23 @@ package net.momirealms.craftengine.core.item;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;
public class ComponentKeys { public class ComponentKeys {
public static final String CUSTOM_MODEL_DATA = Key.of("minecraft", "custom_model_data").toString(); public static final Key CUSTOM_MODEL_DATA = Key.of("minecraft", "custom_model_data");
public static final String CUSTOM_NAME = Key.of("minecraft", "custom_name").toString(); public static final Key CUSTOM_NAME = Key.of("minecraft", "custom_name");
public static final String ITEM_NAME = Key.of("minecraft", "item_name").toString(); public static final Key ITEM_NAME = Key.of("minecraft", "item_name");
public static final String LORE = Key.of("minecraft", "lore").toString(); public static final Key LORE = Key.of("minecraft", "lore");
public static final String DAMAGE = Key.of("minecraft", "damage").toString(); public static final Key DAMAGE = Key.of("minecraft", "damage");
public static final String MAX_DAMAGE = Key.of("minecraft", "max_damage").toString(); public static final Key MAX_DAMAGE = Key.of("minecraft", "max_damage");
public static final String ENCHANTMENT_GLINT_OVERRIDE = Key.of("minecraft", "enchantment_glint_override").toString(); public static final Key ENCHANTMENT_GLINT_OVERRIDE = Key.of("minecraft", "enchantment_glint_override");
public static final String ENCHANTMENTS = Key.of("minecraft", "enchantments").toString(); public static final Key ENCHANTMENTS = Key.of("minecraft", "enchantments");
public static final String STORED_ENCHANTMENTS = Key.of("minecraft", "stored_enchantments").toString(); public static final Key STORED_ENCHANTMENTS = Key.of("minecraft", "stored_enchantments");
public static final String UNBREAKABLE = Key.of("minecraft", "unbreakable").toString(); public static final Key UNBREAKABLE = Key.of("minecraft", "unbreakable");
public static final String MAX_STACK_SIZE = Key.of("minecraft", "max_stack_size").toString(); public static final Key MAX_STACK_SIZE = Key.of("minecraft", "max_stack_size");
public static final String EQUIPPABLE = Key.of("minecraft", "equippable").toString(); public static final Key EQUIPPABLE = Key.of("minecraft", "equippable");
public static final String ITEM_MODEL = Key.of("minecraft", "item_model").toString(); public static final Key ITEM_MODEL = Key.of("minecraft", "item_model");
public static final String TOOLTIP_STYLE = Key.of("minecraft", "tooltip_style").toString(); public static final Key TOOLTIP_STYLE = Key.of("minecraft", "tooltip_style");
public static final String JUKEBOX_PLAYABLE = Key.of("minecraft", "jukebox_playable").toString(); public static final Key JUKEBOX_PLAYABLE = Key.of("minecraft", "jukebox_playable");
public static final String TRIM = Key.of("minecraft", "trim").toString(); public static final Key TRIM = Key.of("minecraft", "trim");
public static final String REPAIR_COST = Key.of("minecraft", "repair_cost").toString(); public static final Key REPAIR_COST = Key.of("minecraft", "repair_cost");
public static final String CUSTOM_DATA = Key.of("minecraft", "custom_data").toString(); public static final Key CUSTOM_DATA = Key.of("minecraft", "custom_data");
public static final Key PROFILE = Key.of("minecraft", "profile");
} }

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.core.item; package net.momirealms.craftengine.core.item;
import com.google.gson.JsonElement;
import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;
@@ -33,6 +34,10 @@ public interface Item<I> {
Item<I> count(int amount); Item<I> count(int amount);
Item<I> trim(Trim trim);
Optional<Trim> trim();
Item<I> customModelData(Integer data); Item<I> customModelData(Integer data);
Optional<Integer> customModelData(); Optional<Integer> customModelData();
@@ -91,13 +96,19 @@ public interface Item<I> {
boolean removeTag(Object... path); 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(); I getItem();

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.core.item; package net.momirealms.craftengine.core.item;
import com.google.gson.JsonElement;
import net.momirealms.craftengine.core.plugin.Plugin; import net.momirealms.craftengine.core.plugin.Plugin;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -22,6 +23,8 @@ public abstract class ItemFactory<P extends Plugin, W extends ItemWrapper<I>, I>
public abstract Object encodeJava(Key componentType, @Nullable Object component); public abstract Object encodeJava(Key componentType, @Nullable Object component);
protected abstract JsonElement encodeJson(Key type, Object component);
protected abstract ItemWrapper<I> wrapInternal(I item); protected abstract ItemWrapper<I> wrapInternal(I item);
protected abstract Object getTag(ItemWrapper<I> item, Object... path); protected abstract Object getTag(ItemWrapper<I> item, Object... path);
@@ -32,13 +35,15 @@ public abstract class ItemFactory<P extends Plugin, W extends ItemWrapper<I>, I>
protected abstract boolean removeTag(ItemWrapper<I> item, Object... path); protected abstract boolean removeTag(ItemWrapper<I> item, Object... path);
protected abstract void setComponent(ItemWrapper<I> item, String type, Object value); protected abstract void setComponent(ItemWrapper<I> item, Key type, Object value);
protected abstract Object getComponent(ItemWrapper<I> item, String type); protected abstract Object getComponent(ItemWrapper<I> item, Key type);
protected abstract boolean hasComponent(ItemWrapper<I> item, String type); protected abstract boolean hasComponent(ItemWrapper<I> item, Key type);
protected abstract void removeComponent(ItemWrapper<I> item, String type); protected abstract void removeComponent(ItemWrapper<I> item, Key type);
protected abstract void resetComponent(ItemWrapper<I> item, Key type);
protected abstract void update(ItemWrapper<I> item); protected abstract void update(ItemWrapper<I> item);
@@ -112,6 +117,10 @@ public abstract class ItemFactory<P extends Plugin, W extends ItemWrapper<I>, I>
protected abstract Optional<Integer> repairCost(ItemWrapper<I> item); protected abstract Optional<Integer> repairCost(ItemWrapper<I> item);
protected abstract void trim(ItemWrapper<I> item, Trim trim);
protected abstract Optional<Trim> trim(ItemWrapper<I> item);
protected abstract ItemWrapper<I> mergeCopy(ItemWrapper<I> item1, ItemWrapper<I> item2); protected abstract ItemWrapper<I> mergeCopy(ItemWrapper<I> item1, ItemWrapper<I> item2);
protected abstract void merge(ItemWrapper<I> item1, ItemWrapper<I> item2); protected abstract void merge(ItemWrapper<I> item1, ItemWrapper<I> item2);

View File

@@ -0,0 +1,4 @@
package net.momirealms.craftengine.core.item;
public record Trim(String pattern, String material) {
}

View File

@@ -1,7 +1,12 @@
package net.momirealms.craftengine.core.item.modifier; 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.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext; 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 net.momirealms.craftengine.core.util.Pair;
import java.util.ArrayList; import java.util.ArrayList;
@@ -9,16 +14,42 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public class ComponentModifier<I> implements ItemDataModifier<I> { public class ComponentModifier<I> implements ItemDataModifier<I> {
private final List<Pair<String, Object>> arguments; private final List<Pair<Key, Object>> arguments;
private JsonObject customData = null;
public ComponentModifier(Map<String, Object> arguments) { public ComponentModifier(Map<String, Object> arguments) {
List<Pair<String, Object>> pairs = new ArrayList<>(arguments.size()); List<Pair<Key, Object>> pairs = new ArrayList<>(arguments.size());
for (Map.Entry<String, Object> entry : arguments.entrySet()) { for (Map.Entry<String, Object> 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; 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 @Override
public String name() { public String name() {
return "components"; return "components";
@@ -26,15 +57,33 @@ public class ComponentModifier<I> implements ItemDataModifier<I> {
@Override @Override
public void apply(Item<I> item, ItemBuildContext context) { public void apply(Item<I> item, ItemBuildContext context) {
for (Pair<String, Object> entry : this.arguments) { for (Pair<Key, Object> entry : this.arguments) {
item.setComponent(entry.left(), entry.right()); 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 @Override
public void remove(Item<I> item) { public void remove(Item<I> item) {
for (Pair<String, Object> entry : this.arguments) { for (Pair<Key, Object> entry : this.arguments) {
item.removeComponent(entry.left()); 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);
}
} }
} }
} }

View File

@@ -1,8 +1,12 @@
package net.momirealms.craftengine.core.item.modifier; 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.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.VersionHelper;
import java.util.Map;
public class IdModifier<I> implements ItemDataModifier<I> { public class IdModifier<I> implements ItemDataModifier<I> {
public static final String CRAFT_ENGINE_ID = "craftengine:id"; public static final String CRAFT_ENGINE_ID = "craftengine:id";
@@ -19,7 +23,11 @@ public class IdModifier<I> implements ItemDataModifier<I> {
@Override @Override
public void apply(Item<I> item, ItemBuildContext context) { public void apply(Item<I> 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 @Override

View File

@@ -3,10 +3,9 @@ package net.momirealms.craftengine.core.item.modifier;
import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.ComponentKeys;
import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.item.Trim;
import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.util.VersionHelper;
import java.util.Map;
public class TrimModifier<I> implements ItemDataModifier<I> { public class TrimModifier<I> implements ItemDataModifier<I> {
private final String material; private final String material;
private final String pattern; private final String pattern;
@@ -23,19 +22,18 @@ public class TrimModifier<I> implements ItemDataModifier<I> {
@Override @Override
public void apply(Item<I> item, ItemBuildContext context) { public void apply(Item<I> item, ItemBuildContext context) {
item.trim(new Trim(this.material, this.pattern));
if (VersionHelper.isVersionNewerThan1_20_5()) { if (VersionHelper.isVersionNewerThan1_20_5()) {
item.setComponent(ComponentKeys.TRIM, Map.of(
"pattern", this.pattern,
"material", this.material
));
} else { } else {
item.setTag(this.material, "Trim", "material");
item.setTag(this.pattern, "Trim", "pattern");
} }
} }
@Override @Override
public void remove(Item<I> item) { public void remove(Item<I> item) {
item.trim(null);
if (VersionHelper.isVersionNewerThan1_20_5()) { if (VersionHelper.isVersionNewerThan1_20_5()) {
item.removeComponent(ComponentKeys.TRIM); item.removeComponent(ComponentKeys.TRIM);
} else { } else {

View File

@@ -217,9 +217,9 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
@Override @Override
public void accept(Item<?> item1, Item<?> item2, Item<?> item3) { public void accept(Item<?> item1, Item<?> item2, Item<?> item3) {
for (Key component : this.components) { for (Key component : this.components) {
Object componentObj = item1.getComponent(component.toString()); Object componentObj = item1.getComponent(component);
if (componentObj != null) { if (componentObj != null) {
item3.setComponent(component.toString(), CraftEngine.instance().itemManager().encodeJava(component, componentObj)); item3.setComponent(component, componentObj);
} }
} }
} }

View File

@@ -233,7 +233,6 @@ public abstract class AbstractPackManager implements PackManager {
Files.createDirectories(resourcesFolder); Files.createDirectories(resourcesFolder);
this.saveDefaultConfigs(); this.saveDefaultConfigs();
} }
try (DirectoryStream<Path> paths = Files.newDirectoryStream(resourcesFolder)) { try (DirectoryStream<Path> paths = Files.newDirectoryStream(resourcesFolder)) {
for (Path path : paths) { for (Path path : paths) {
if (!Files.isDirectory(path)) { if (!Files.isDirectory(path)) {
@@ -247,6 +246,9 @@ public abstract class AbstractPackManager implements PackManager {
String author = null; String author = null;
if (Files.exists(metaFile) && Files.isRegularFile(metaFile)) { if (Files.exists(metaFile) && Files.isRegularFile(metaFile)) {
YamlDocument metaYML = Config.instance().loadYamlData(metaFile.toFile()); YamlDocument metaYML = Config.instance().loadYamlData(metaFile.toFile());
if (!metaYML.getBoolean("enable", true)) {
continue;
}
namespace = metaYML.getString("namespace", namespace); namespace = metaYML.getString("namespace", namespace);
description = metaYML.getString("description"); description = metaYML.getString("description");
version = metaYML.getString("version"); version = metaYML.getString("version");

View File

@@ -51,7 +51,7 @@ byte_buddy_version=1.17.5
ahocorasick_version=0.6.3 ahocorasick_version=0.6.3
snake_yaml_version=2.4 snake_yaml_version=2.4
anti_grief_version=0.13 anti_grief_version=0.13
nms_helper_version=0.57 nms_helper_version=0.57.3
# Ignite Dependencies # Ignite Dependencies
mixinextras_version=0.4.1 mixinextras_version=0.4.1
mixin_version=0.15.2+mixin.0.8.7 mixin_version=0.15.2+mixin.0.8.7

View File

@@ -1,4 +1,4 @@
package net.momirealms.craftengine.mod; package net.momirealms.craftengine.mod.block;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; 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.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import net.momirealms.craftengine.mod.CraftEnginePlugin;
import net.momirealms.craftengine.mod.util.NoteBlockUtils; import net.momirealms.craftengine.mod.util.NoteBlockUtils;
import net.momirealms.craftengine.shared.ObjectHolder; import net.momirealms.craftengine.shared.ObjectHolder;
import net.momirealms.craftengine.shared.block.*; import net.momirealms.craftengine.shared.block.*;

View File

@@ -1,4 +1,4 @@
package net.momirealms.craftengine.mod; package net.momirealms.craftengine.mod.block;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;

View File

@@ -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<RegistryFriendlyByteBuf, ItemStack> {
public static Function<ItemStack, ItemStack> clientBoundDataProcessor;
public static Function<ItemStack, ItemStack> serverBoundDataProcessor;
private final StreamCodec<RegistryFriendlyByteBuf, ItemStack> original;
public CustomStreamCodec(StreamCodec<RegistryFriendlyByteBuf, ItemStack> 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);
}
}

View File

@@ -11,8 +11,8 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState; 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.CraftEnginePlugin;
import net.momirealms.craftengine.mod.block.CraftEngineBlock;
import net.momirealms.craftengine.mod.util.NoteBlockUtils; import net.momirealms.craftengine.mod.util.NoteBlockUtils;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@@ -27,7 +27,7 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@Mixin(value = Blocks.class) @Mixin(value = Blocks.class)
public abstract class MixinBlocks { public abstract class BlocksMixin {
@Inject(method = "<clinit>", at = @At("RETURN")) @Inject(method = "<clinit>", at = @At("RETURN"))
private static void onBlocksInit(CallbackInfo ci) { private static void onBlocksInit(CallbackInfo ci) {

View File

@@ -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<RegistryFriendlyByteBuf, ItemStack> OPTIONAL_STREAM_CODEC;
@Shadow(remap = false)
@Mutable
public static StreamCodec<RegistryFriendlyByteBuf, List<ItemStack>> OPTIONAL_LIST_STREAM_CODEC;
private static StreamCodec<RegistryFriendlyByteBuf, ItemStack> ORIGINAL_OPTIONAL_STREAM_CODEC;
@Inject(
method = "<clinit>",
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 = "<clinit>", 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));
}
}

View File

@@ -6,6 +6,7 @@
"target": "@env(DEFAULT)", "target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_21", "compatibilityLevel": "JAVA_21",
"server": [ "server": [
"MixinBlocks" "BlocksMixin",
"ItemStackMixin"
] ]
} }