9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-31 04:46:37 +00:00

重构了物品系统

This commit is contained in:
XiaoMoMi
2025-04-23 18:12:32 +08:00
parent 23d0dede51
commit 6929b4a706
32 changed files with 1078 additions and 755 deletions

View File

@@ -217,8 +217,10 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
for (Entity entity : entities) {
if (entity instanceof ItemDisplay display) {
handleBaseEntityLoadEarly(display);
} else if (COLLISION_ENTITY_CLASS.isInstance(entity)) {
handleCollisionEntityLoadOnEntitiesLoad(entity);
} else if (entity instanceof Interaction interaction) {
handleCollisionEntityLoadOnEntitiesLoad(interaction);
} else if (entity instanceof Boat boat) {
handleCollisionEntityLoadOnEntitiesLoad(boat);
} else if (entity instanceof Shulker shulker) {
// TODO 移除这一行,预计过一个月
handleCollisionEntityLoadOnEntitiesLoad(shulker);

View File

@@ -1,7 +1,6 @@
package net.momirealms.craftengine.bukkit.item;
import com.google.common.collect.ImmutableMap;
import com.saicone.rtag.RtagItem;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.util.MaterialUtils;
import net.momirealms.craftengine.core.item.*;

View File

@@ -60,7 +60,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
}
private static BukkitItemManager instance;
private final BukkitItemFactory factory;
private final BukkitItemFactory<? extends ItemWrapper<ItemStack>> factory;
private final BukkitCraftEngine plugin;
private final ItemEventListener itemEventListener;
private final DebugStickListener debugStickListener;
@@ -143,11 +143,6 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
}
}
@Override
public Object encodeJava(Key componentType, @Nullable Object component) {
return this.factory.encodeJava(componentType, component);
}
public static BukkitItemManager instance() {
return instance;
}

View File

@@ -0,0 +1,99 @@
package net.momirealms.craftengine.bukkit.item;
import com.google.gson.JsonElement;
import com.saicone.rtag.data.ComponentType;
import com.saicone.rtag.tag.TagBase;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.item.ItemWrapper;
import net.momirealms.craftengine.core.util.Key;
import org.bukkit.inventory.ItemStack;
@SuppressWarnings("UnstableApiUsage")
public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
private final ItemStack item;
public ComponentItemWrapper(final ItemStack item) {
this.item = item;
}
public ComponentItemWrapper(final ItemStack item, int count) {
this.item = item;
this.item.setAmount(count);
}
public void resetComponent(Object type) {
FastNMS.INSTANCE.resetComponent(this.getLiteralObject(), type);
}
public void setComponent(Object type, final Object value) {
if (value instanceof JsonElement jsonElement) {
setJsonComponent(type, jsonElement);
} else if (TagBase.isTag(value)) {
setNBTComponent(type, value);
} else {
setJavaComponent(type, value);
}
}
public Object getComponent(Object type) {
return FastNMS.INSTANCE.getComponent(getLiteralObject(), ensureDataComponentType(type));
}
public boolean hasComponent(Object type) {
return FastNMS.INSTANCE.hasComponent(getLiteralObject(), ensureDataComponentType(type));
}
public void setJavaComponent(Object type, Object value) {
ComponentType.parseJava(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), it));
}
public void setJsonComponent(Object type, JsonElement value) {
ComponentType.parseJson(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), it));
}
public void setNBTComponent(Object type, Object value) {
ComponentType.parseNbt(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), it));
}
private Object ensureDataComponentType(Object type) {
assert Reflections.clazz$DataComponentType != null;
if (!Reflections.clazz$DataComponentType.isInstance(type)) {
Key key = Key.of(type.toString());
return FastNMS.INSTANCE.getComponentType(key.namespace(), key.value());
}
return type;
}
@Override
public ItemWrapper<ItemStack> copyWithCount(int count) {
ItemStack copied = item.clone();
copied.setAmount(count);
return new ComponentItemWrapper(copied);
}
@Override
public ItemStack getItem() {
return this.item;
}
@Override
public ItemStack load() {
return this.item;
}
@Override
public Object getLiteralObject() {
return FastNMS.INSTANCE.field$CraftItemStack$handle(this.item);
}
@Override
public int count() {
return this.item.getAmount();
}
@Override
public void count(int amount) {
this.item.setAmount(amount);
}
}

View File

@@ -0,0 +1,35 @@
package net.momirealms.craftengine.bukkit.item;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.core.item.ComponentKeys;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.VersionHelper;
public class ComponentTypes {
public static final Object CUSTOM_MODEL_DATA = getComponentType(ComponentKeys.CUSTOM_MODEL_DATA);
public static final Object CUSTOM_NAME = getComponentType(ComponentKeys.CUSTOM_NAME);
public static final Object ITEM_NAME = getComponentType(ComponentKeys.ITEM_NAME);
public static final Object LORE = getComponentType(ComponentKeys.LORE);
public static final Object DAMAGE = getComponentType(ComponentKeys.DAMAGE);
public static final Object MAX_DAMAGE = getComponentType(ComponentKeys.MAX_DAMAGE);
public static final Object ENCHANTMENT_GLINT_OVERRIDE = getComponentType(ComponentKeys.ENCHANTMENT_GLINT_OVERRIDE);
public static final Object ENCHANTMENTS = getComponentType(ComponentKeys.ENCHANTMENTS);
public static final Object STORED_ENCHANTMENTS = getComponentType(ComponentKeys.STORED_ENCHANTMENTS);
public static final Object UNBREAKABLE = getComponentType(ComponentKeys.UNBREAKABLE);
public static final Object MAX_STACK_SIZE = getComponentType(ComponentKeys.MAX_STACK_SIZE);
public static final Object EQUIPPABLE = getComponentType(ComponentKeys.EQUIPPABLE);
public static final Object ITEM_MODEL = getComponentType(ComponentKeys.ITEM_MODEL);
public static final Object TOOLTIP_STYLE = getComponentType(ComponentKeys.TOOLTIP_STYLE);
public static final Object JUKEBOX_PLAYABLE = getComponentType(ComponentKeys.JUKEBOX_PLAYABLE);
public static final Object TRIM = getComponentType(ComponentKeys.TRIM);
public static final Object REPAIR_COST = getComponentType(ComponentKeys.REPAIR_COST);
public static final Object CUSTOM_DATA = getComponentType(ComponentKeys.CUSTOM_DATA);
public static final Object PROFILE = getComponentType(ComponentKeys.PROFILE);
private ComponentTypes() {}
private static Object getComponentType(Key key) {
if (!VersionHelper.isVersionNewerThan1_20_5()) return null;
return FastNMS.INSTANCE.getComponentType(key.namespace(), key.value());
}
}

View File

@@ -4,14 +4,11 @@ import com.saicone.rtag.RtagItem;
import net.momirealms.craftengine.core.item.ItemWrapper;
import org.bukkit.inventory.ItemStack;
import java.util.Map;
@SuppressWarnings("UnstableApiUsage")
public class RTagItemWrapper implements ItemWrapper<ItemStack> {
public class LegacyItemWrapper implements ItemWrapper<ItemStack> {
private final RtagItem rtagItem;
private int count;
public RTagItemWrapper(RtagItem rtagItem, int count) {
public LegacyItemWrapper(RtagItem rtagItem, int count) {
this.rtagItem = rtagItem;
this.count = count;
}
@@ -23,67 +20,43 @@ public class RTagItemWrapper implements ItemWrapper<ItemStack> {
return itemStack;
}
@Override
public boolean set(Object value, Object... path) {
return this.rtagItem.set(value, path);
}
@Override
public boolean add(Object value, Object... path) {
return this.rtagItem.add(value, path);
}
@Override
public <V> V get(Object... path) {
return this.rtagItem.get(path);
}
@Override
public void setComponent(Object path, Object value) {
this.rtagItem.setComponent(path, value);
}
@Override
public Object getComponent(Object path) {
return this.rtagItem.getComponent(path);
}
@Override
public int count() {
return this.count;
}
@Override
public void count(int amount) {
if (amount < 0) amount = 0;
this.count = amount;
}
@Override
public <V> V getExact(Object... path) {
return this.rtagItem.get(path);
}
@Override
public void removeComponent(Object path) {
this.rtagItem.removeComponent(path);
}
@Override
public boolean hasComponent(Object path) {
return this.rtagItem.hasComponent(path);
}
@Override
public boolean remove(Object... path) {
return this.rtagItem.remove(path);
}
@Override
public boolean hasTag(Object... path) {
return this.rtagItem.hasTag(path);
}
public void update() {
this.rtagItem.update();
}
@Override
public ItemStack load() {
ItemStack itemStack = this.rtagItem.load();
@@ -98,11 +71,6 @@ public class RTagItemWrapper implements ItemWrapper<ItemStack> {
@Override
public ItemWrapper<ItemStack> copyWithCount(int count) {
return new RTagItemWrapper(new RtagItem(this.rtagItem.loadCopy()), count);
}
@Override
public Map<String, Object> getData() {
return this.rtagItem.get();
return new LegacyItemWrapper(new RtagItem(this.rtagItem.loadCopy()), count);
}
}

View File

@@ -1,35 +1,40 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.saicone.rtag.RtagItem;
import net.momirealms.craftengine.bukkit.item.RTagItemWrapper;
import com.google.gson.JsonElement;
import net.momirealms.craftengine.bukkit.util.ItemTags;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.item.EquipmentData;
import net.momirealms.craftengine.core.item.ItemFactory;
import net.momirealms.craftengine.core.item.ItemWrapper;
import net.momirealms.craftengine.core.item.modifier.IdModifier;
import net.momirealms.craftengine.core.item.JukeboxPlayable;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.Optional;
public abstract class BukkitItemFactory extends ItemFactory<CraftEngine, ItemWrapper<ItemStack>, ItemStack> {
public abstract class BukkitItemFactory<W extends ItemWrapper<ItemStack>> extends ItemFactory<W, ItemStack> {
protected BukkitItemFactory(CraftEngine plugin) {
super(plugin);
}
public static BukkitItemFactory create(CraftEngine plugin) {
public static BukkitItemFactory<? extends ItemWrapper<ItemStack>> create(CraftEngine plugin) {
Objects.requireNonNull(plugin, "plugin");
switch (plugin.serverVersion()) {
case "1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4" -> {
return new UniversalItemFactory(plugin);
}
case "1.20.5", "1.20.6",
"1.21", "1.21.1", "1.21.2", "1.21.3" -> {
return new ComponentItemFactory(plugin);
case "1.20.5", "1.20.6"-> {
return new ComponentItemFactory1_20_5(plugin);
}
case "1.21", "1.21.1" -> {
return new ComponentItemFactory1_21(plugin);
}
case "1.21.2", "1.21.3" -> {
return new ComponentItemFactory1_21_2(plugin);
}
case "1.21.4" -> {
return new ComponentItemFactory1_21_4(plugin);
@@ -42,69 +47,32 @@ public abstract class BukkitItemFactory extends ItemFactory<CraftEngine, ItemWra
}
@Override
protected Key id(ItemWrapper<ItemStack> item) {
Object id = item.get(IdModifier.CRAFT_ENGINE_ID);
if (id == null) {
NamespacedKey key = item.getItem().getType().getKey();
return Key.of(key.getNamespace(), key.getKey());
}
return Key.of(id.toString());
}
@Override
protected Optional<Key> customId(ItemWrapper<ItemStack> item) {
Object id = item.get(IdModifier.CRAFT_ENGINE_ID);
if (id == null) return Optional.empty();
return Optional.of(Key.of(id.toString()));
}
@Override
protected boolean isBlockItem(ItemWrapper<ItemStack> item) {
protected boolean isBlockItem(W item) {
return item.getItem().getType().isBlock();
}
@Override
protected Key vanillaId(ItemWrapper<ItemStack> item) {
protected Key vanillaId(W item) {
return Key.of(item.getItem().getType().getKey().asString());
}
@Override
protected ItemWrapper<ItemStack> wrapInternal(ItemStack item) {
return new RTagItemWrapper(new RtagItem(item), item.getAmount());
protected Key id(W item) {
return customId(item).orElse(vanillaId(item));
}
@Override
protected void setTag(ItemWrapper<ItemStack> item, Object value, Object... path) {
item.set(value, path);
}
@Override
protected Object getTag(ItemWrapper<ItemStack> item, Object... path) {
return item.get(path);
}
@Override
protected boolean hasTag(ItemWrapper<ItemStack> item, Object... path) {
return item.hasTag(path);
}
@Override
protected boolean removeTag(ItemWrapper<ItemStack> item, Object... path) {
return item.remove(path);
}
@Override
protected ItemStack load(ItemWrapper<ItemStack> item) {
protected ItemStack load(W item) {
return item.load();
}
@Override
protected ItemStack getItem(ItemWrapper<ItemStack> item) {
protected ItemStack getItem(W item) {
return item.getItem();
}
@Override
protected boolean is(ItemWrapper<ItemStack> item, Key itemTag) {
protected boolean is(W item, Key itemTag) {
Object literalObject = item.getLiteralObject();
Object tag = ItemTags.getOrCreate(itemTag);
try {
@@ -113,4 +81,89 @@ public abstract class BukkitItemFactory extends ItemFactory<CraftEngine, ItemWra
return false;
}
}
@Override
protected JsonElement encodeJson(Object type, Object component) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
public Object encodeJava(Object componentType, @Nullable Object component) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void resetComponent(W item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void setComponent(W item, Object type, Object value) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected Object getComponent(W item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected boolean hasComponent(W item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void removeComponent(W item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected Optional<String> tooltipStyle(W item) {
throw new UnsupportedOperationException("This feature is only available on 1.21.2+");
}
@Override
protected void tooltipStyle(W item, String data) {
throw new UnsupportedOperationException("This feature is only available on 1.21.2+");
}
@Override
protected Optional<JukeboxPlayable> jukeboxSong(W item) {
throw new UnsupportedOperationException("This feature is only available on 1.21+");
}
@Override
protected void jukeboxSong(W item, JukeboxPlayable data) {
throw new UnsupportedOperationException("This feature is only available on 1.21+");
}
@Override
protected Optional<Boolean> glint(W item) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void glint(W item, Boolean glint) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected Optional<String> itemModel(W item) {
throw new UnsupportedOperationException("This feature is only available on 1.21.2+");
}
@Override
protected void itemModel(W item, String data) {
throw new UnsupportedOperationException("This feature is only available on 1.21.2+");
}
@Override
protected Optional<EquipmentData> equippable(W item) {
throw new UnsupportedOperationException("This feature is only available on 1.21.2+");
}
@Override
protected void equippable(W item, EquipmentData data) {
throw new UnsupportedOperationException("This feature is only available on 1.21.2+");
}
}

View File

@@ -1,391 +0,0 @@
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;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@SuppressWarnings("UnstableApiUsage")
public class ComponentItemFactory extends BukkitItemFactory {
public ComponentItemFactory(CraftEngine 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));
}
protected void setNBTComponentDirectly(ItemWrapper<ItemStack> item, Key type, Object value) {
ComponentType.parseNbt(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<ItemStack> item, Integer data) {
if (data == null) {
resetComponent(item, ComponentKeys.CUSTOM_MODEL_DATA);
} else {
setJavaComponentDirectly(item, ComponentKeys.CUSTOM_MODEL_DATA, data);
}
}
@Override
protected Optional<Integer> customModelData(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.CUSTOM_MODEL_DATA)) return Optional.empty();
return Optional.ofNullable(
(Integer) ComponentType.encodeJava(
ComponentKeys.CUSTOM_MODEL_DATA,
item.getComponent(ComponentKeys.CUSTOM_MODEL_DATA)
).orElse(null));
}
@Override
protected void customName(ItemWrapper<ItemStack> item, String json) {
if (json == null) {
resetComponent(item, ComponentKeys.CUSTOM_NAME);
} else {
setJavaComponentDirectly(item, ComponentKeys.CUSTOM_NAME, json);
}
}
@Override
protected Optional<String> customName(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.CUSTOM_NAME)) return Optional.empty();
return Optional.ofNullable(
(String) ComponentType.encodeJava(
ComponentKeys.CUSTOM_NAME,
item.getComponent(ComponentKeys.CUSTOM_NAME)
).orElse(null)
);
}
@Override
protected void itemName(ItemWrapper<ItemStack> item, String json) {
if (json == null) {
resetComponent(item, ComponentKeys.ITEM_NAME);
} else {
setJavaComponentDirectly(item, ComponentKeys.ITEM_NAME, json);
}
}
@Override
protected Optional<String> itemName(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.ITEM_NAME)) return Optional.empty();
return Optional.ofNullable(
(String) ComponentType.encodeJava(
ComponentKeys.ITEM_NAME,
item.getComponent(ComponentKeys.ITEM_NAME)
).orElse(null)
);
}
@Override
protected void skull(ItemWrapper<ItemStack> item, String skullData) {
if (skullData == null) {
resetComponent(item, ComponentKeys.PROFILE);
} else {
Map<String, Object> profile = Map.of("properties", List.of(Map.of("name", "textures", "value", skullData)));
setJavaComponentDirectly(item, ComponentKeys.PROFILE, profile);
}
}
@SuppressWarnings("unchecked")
@Override
protected Optional<List<String>> lore(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.LORE)) return Optional.empty();
return Optional.ofNullable(
(List<String>) ComponentType.encodeJava(
ComponentKeys.LORE,
item.getComponent(ComponentKeys.LORE)
).orElse(null)
);
}
@Override
protected void lore(ItemWrapper<ItemStack> item, List<String> lore) {
if (lore == null || lore.isEmpty()) {
resetComponent(item, ComponentKeys.LORE);
} else {
setJavaComponentDirectly(item, ComponentKeys.LORE, lore);
}
}
@Override
protected boolean unbreakable(ItemWrapper<ItemStack> item) {
return item.hasComponent(ComponentKeys.UNBREAKABLE);
}
@Override
protected void unbreakable(ItemWrapper<ItemStack> item, boolean unbreakable) {
if (unbreakable) {
resetComponent(item, ComponentKeys.UNBREAKABLE);
} else {
setJavaComponentDirectly(item, ComponentKeys.UNBREAKABLE, true);
}
}
@Override
protected Optional<Boolean> glint(ItemWrapper<ItemStack> item) {
return Optional.ofNullable((Boolean) item.getComponent(ComponentKeys.ENCHANTMENT_GLINT_OVERRIDE));
}
@Override
protected void glint(ItemWrapper<ItemStack> item, Boolean glint) {
if (glint == null) {
resetComponent(item, ComponentKeys.ENCHANTMENT_GLINT_OVERRIDE);
} else {
setJavaComponentDirectly(item, ComponentKeys.ENCHANTMENT_GLINT_OVERRIDE, glint);
}
}
@Override
protected Optional<Integer> damage(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.DAMAGE)) return Optional.empty();
return Optional.ofNullable(
(Integer) ComponentType.encodeJava(
ComponentKeys.DAMAGE,
item.getComponent(ComponentKeys.DAMAGE)
).orElse(null)
);
}
@Override
protected void damage(ItemWrapper<ItemStack> item, Integer damage) {
if (damage == null) {
resetComponent(item, ComponentKeys.DAMAGE);
} else {
setJavaComponentDirectly(item, ComponentKeys.DAMAGE, damage);
}
}
@Override
protected Optional<Integer> maxDamage(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.MAX_DAMAGE)) return Optional.of((int) item.getItem().getType().getMaxDurability());
return Optional.ofNullable(
(Integer) ComponentType.encodeJava(
ComponentKeys.MAX_DAMAGE,
item.getComponent(ComponentKeys.MAX_DAMAGE)
).orElse(null)
);
}
@Override
protected void maxDamage(ItemWrapper<ItemStack> item, Integer damage) {
if (damage == null) {
resetComponent(item, ComponentKeys.MAX_DAMAGE);
} else {
setJavaComponentDirectly(item, ComponentKeys.MAX_DAMAGE, damage);
}
}
@Override
protected Optional<Enchantment> getEnchantment(ItemWrapper<ItemStack> item, Key key) {
Object enchant = item.getComponent(ComponentKeys.ENCHANTMENTS);
try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
Integer level = map.get(key.toString());
if (level == null) return Optional.empty();
return Optional.of(new Enchantment(key, level));
} catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to get enchantment " + key, e);
return Optional.empty();
}
}
@Override
protected void enchantments(ItemWrapper<ItemStack> item, List<Enchantment> enchantments) {
if (enchantments == null || enchantments.isEmpty()) {
resetComponent(item, ComponentKeys.ENCHANTMENTS);
} else {
Map<String, Integer> enchants = new HashMap<>();
for (Enchantment enchantment : enchantments) {
enchants.put(enchantment.id().toString(), enchantment.level());
}
setJavaComponentDirectly(item, ComponentKeys.ENCHANTMENTS, enchants);
}
}
@Override
protected void storedEnchantments(ItemWrapper<ItemStack> item, List<Enchantment> enchantments) {
if (enchantments == null || enchantments.isEmpty()) {
resetComponent(item, ComponentKeys.STORED_ENCHANTMENTS);
} else {
Map<String, Integer> enchants = new HashMap<>();
for (Enchantment enchantment : enchantments) {
enchants.put(enchantment.id().toString(), enchantment.level());
}
setJavaComponentDirectly(item, ComponentKeys.STORED_ENCHANTMENTS, enchants);
}
}
@Override
protected void addEnchantment(ItemWrapper<ItemStack> item, Enchantment enchantment) {
Object enchant = item.getComponent(ComponentKeys.ENCHANTMENTS);
try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
map.put(enchantment.toString(), enchantment.level());
setJavaComponentDirectly(item, ComponentKeys.ENCHANTMENTS, map);
} catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to add enchantment", e);
}
}
@Override
protected void addStoredEnchantment(ItemWrapper<ItemStack> item, Enchantment enchantment) {
Object enchant = item.getComponent(ComponentKeys.STORED_ENCHANTMENTS);
try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
map.put(enchantment.toString(), enchantment.level());
setJavaComponentDirectly(item, ComponentKeys.STORED_ENCHANTMENTS, map);
} catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to add stored enchantment", e);
}
}
@Override
protected void itemFlags(ItemWrapper<ItemStack> item, List<String> flags) {
throw new UnsupportedOperationException("This feature is not available on 1.20.5+");
}
@Override
protected int maxStackSize(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.MAX_STACK_SIZE)) return item.getItem().getType().getMaxStackSize();
return Optional.ofNullable((Integer) ComponentType.encodeJava(ComponentKeys.MAX_STACK_SIZE, item.getComponent(ComponentKeys.MAX_STACK_SIZE)).orElse(null))
.orElse(item.getItem().getType().getMaxStackSize());
}
@Override
protected void maxStackSize(ItemWrapper<ItemStack> item, Integer maxStackSize) {
if (maxStackSize == null) {
resetComponent(item, ComponentKeys.MAX_STACK_SIZE);
} else {
setJavaComponentDirectly(item, ComponentKeys.MAX_STACK_SIZE, maxStackSize);
}
}
@Override
protected void repairCost(ItemWrapper<ItemStack> item, Integer data) {
if (data == null) {
resetComponent(item, ComponentKeys.REPAIR_COST);
} else {
setJavaComponentDirectly(item, ComponentKeys.REPAIR_COST, data);
}
}
@Override
protected Optional<Integer> repairCost(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.REPAIR_COST)) return Optional.empty();
return Optional.ofNullable((Integer) ComponentType.encodeJava(ComponentKeys.REPAIR_COST, item.getComponent(ComponentKeys.REPAIR_COST)).orElse(null));
}
@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")));
}
@Override
protected ItemWrapper<ItemStack> mergeCopy(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) {
Object itemStack1 = item1.getLiteralObject();
Object itemStack2 = item2.getLiteralObject();
try {
Object itemStack3 = FastNMS.INSTANCE.method$ItemStack$transmuteCopy(itemStack1, itemStack2);
FastNMS.INSTANCE.method$ItemStack$applyComponents(itemStack3, FastNMS.INSTANCE.method$ItemStack$getComponentsPatch(itemStack2));
return new RTagItemWrapper(new RtagItem(ItemObject.asCraftMirror(itemStack3)), item2.count());
} catch (Exception e) {
this.plugin.logger().warn("Failed to merge item", e);
}
return null;
}
@Override
protected void merge(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) {
// load previous changes on nms items
Object itemStack1 = item1.getLiteralObject();
Object itemStack2 = item2.getLiteralObject();
try {
FastNMS.INSTANCE.method$ItemStack$applyComponents(itemStack1, FastNMS.INSTANCE.method$ItemStack$getComponentsPatch(itemStack2));
} catch (Exception e) {
plugin.logger().warn("Failed to merge item", e);
}
}
}

View File

@@ -0,0 +1,410 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.google.gson.JsonElement;
import com.saicone.rtag.data.ComponentType;
import com.saicone.rtag.item.ItemObject;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.util.EnchantmentUtils;
import net.momirealms.craftengine.core.item.Enchantment;
import net.momirealms.craftengine.core.item.Trim;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@SuppressWarnings("UnstableApiUsage")
public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemWrapper> {
public ComponentItemFactory1_20_5(CraftEngine plugin) {
super(plugin);
}
@Override
protected void customId(ComponentItemWrapper item, Key id) {
FastNMS.INSTANCE.setCustomItemId(item.getLiteralObject(), id.toString());
}
@Override
protected Optional<Key> customId(ComponentItemWrapper item) {
return Optional.ofNullable(FastNMS.INSTANCE.getCustomItemId(item.getLiteralObject())).map(Key::of);
}
@Override
protected ComponentItemWrapper wrapInternal(ItemStack item) {
return new ComponentItemWrapper(item);
}
@Override
protected Object getTag(ComponentItemWrapper item, Object... path) {
throw new UnsupportedOperationException("This feature is not available on 1.20.5+");
}
@Override
protected void setTag(ComponentItemWrapper item, Object value, Object... path) {
throw new UnsupportedOperationException("This feature is not available on 1.20.5+");
}
@Override
protected boolean hasTag(ComponentItemWrapper item, Object... path) {
throw new UnsupportedOperationException("This feature is not available on 1.20.5+");
}
@Override
protected boolean removeTag(ComponentItemWrapper item, Object... path) {
throw new UnsupportedOperationException("This feature is not available on 1.20.5+");
}
@Override
protected Optional<String> tooltipStyle(ComponentItemWrapper item) {
throw new UnsupportedOperationException("This feature is not available on 1.21.2+");
}
@Override
protected void tooltipStyle(ComponentItemWrapper item, String data) {
throw new UnsupportedOperationException("This feature is not available on 1.21.2+");
}
@Override
protected void setComponent(ComponentItemWrapper item, Object type, Object value) {
item.setComponent(type, value);
}
@Override
protected void resetComponent(ComponentItemWrapper item, Object type) {
item.resetComponent(type);
}
@Override
protected Object getComponent(ComponentItemWrapper item, Object type) {
return item.getComponent(type);
}
@Override
protected boolean hasComponent(ComponentItemWrapper item, Object type) {
return item.hasComponent(type);
}
@Override
protected void removeComponent(ComponentItemWrapper item, Object type) {
item.resetComponent(type);
}
@Override
public Object encodeJava(Object componentType, @Nullable Object component) {
return ComponentType.encodeJava(componentType, component).orElse(null);
}
@Override
protected JsonElement encodeJson(Object type, Object component) {
return ComponentType.encodeJson(type, component).orElse(null);
}
@Override
protected void customModelData(ComponentItemWrapper item, Integer data) {
if (data == null) {
item.resetComponent(ComponentTypes.CUSTOM_MODEL_DATA);
} else {
item.setJavaComponent(ComponentTypes.CUSTOM_MODEL_DATA, data);
}
}
@Override
protected Optional<Integer> customModelData(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.CUSTOM_MODEL_DATA)) return Optional.empty();
return Optional.ofNullable(
(Integer) ComponentType.encodeJava(
ComponentTypes.CUSTOM_MODEL_DATA,
item.getComponent(ComponentTypes.CUSTOM_MODEL_DATA)
).orElse(null));
}
@Override
protected void customName(ComponentItemWrapper item, String json) {
if (json == null) {
item.resetComponent(ComponentTypes.CUSTOM_NAME);
} else {
item.setJavaComponent(ComponentTypes.CUSTOM_NAME, json);
}
}
@Override
protected Optional<String> customName(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.CUSTOM_NAME)) return Optional.empty();
return Optional.ofNullable(
(String) ComponentType.encodeJava(
ComponentTypes.CUSTOM_NAME,
item.getComponent(ComponentTypes.CUSTOM_NAME)
).orElse(null)
);
}
@Override
protected void itemName(ComponentItemWrapper item, String json) {
if (json == null) {
item.resetComponent(ComponentTypes.ITEM_NAME);
} else {
item.setJavaComponent(ComponentTypes.ITEM_NAME, json);
}
}
@Override
protected Optional<String> itemName(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.ITEM_NAME)) return Optional.empty();
return Optional.ofNullable(
(String) ComponentType.encodeJava(
ComponentTypes.ITEM_NAME,
item.getComponent(ComponentTypes.ITEM_NAME)
).orElse(null)
);
}
@Override
protected void skull(ComponentItemWrapper item, String skullData) {
if (skullData == null) {
item.resetComponent(ComponentTypes.PROFILE);
} else {
Map<String, Object> profile = Map.of("properties", List.of(Map.of("name", "textures", "value", skullData)));
item.setJavaComponent(ComponentTypes.PROFILE, profile);
}
}
@SuppressWarnings("unchecked")
@Override
protected Optional<List<String>> lore(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.LORE)) return Optional.empty();
return Optional.ofNullable(
(List<String>) ComponentType.encodeJava(
ComponentTypes.LORE,
item.getComponent(ComponentTypes.LORE)
).orElse(null)
);
}
@Override
protected void lore(ComponentItemWrapper item, List<String> lore) {
if (lore == null || lore.isEmpty()) {
item.resetComponent(ComponentTypes.LORE);
} else {
item.setJavaComponent(ComponentTypes.LORE, lore);
}
}
@Override
protected boolean unbreakable(ComponentItemWrapper item) {
return item.hasComponent(ComponentTypes.UNBREAKABLE);
}
@Override
protected void unbreakable(ComponentItemWrapper item, boolean unbreakable) {
if (unbreakable) {
item.resetComponent(ComponentTypes.UNBREAKABLE);
} else {
item.setJavaComponent(ComponentTypes.UNBREAKABLE, true);
}
}
@Override
protected Optional<Boolean> glint(ComponentItemWrapper item) {
return Optional.ofNullable((Boolean) item.getComponent(ComponentTypes.ENCHANTMENT_GLINT_OVERRIDE));
}
@Override
protected void glint(ComponentItemWrapper item, Boolean glint) {
if (glint == null) {
item.resetComponent(ComponentTypes.ENCHANTMENT_GLINT_OVERRIDE);
} else {
item.setJavaComponent(ComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, glint);
}
}
@Override
protected Optional<Integer> damage(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.DAMAGE)) return Optional.empty();
return Optional.ofNullable(
(Integer) ComponentType.encodeJava(
ComponentTypes.DAMAGE,
item.getComponent(ComponentTypes.DAMAGE)
).orElse(null)
);
}
@Override
protected void damage(ComponentItemWrapper item, Integer damage) {
if (damage == null) {
item.resetComponent(ComponentTypes.DAMAGE);
} else {
item.setJavaComponent(ComponentTypes.DAMAGE, damage);
}
}
@Override
protected Optional<Integer> maxDamage(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.MAX_DAMAGE)) return Optional.of((int) item.getItem().getType().getMaxDurability());
return Optional.ofNullable(
(Integer) ComponentType.encodeJava(
ComponentTypes.MAX_DAMAGE,
item.getComponent(ComponentTypes.MAX_DAMAGE)
).orElse(null)
);
}
@Override
protected void maxDamage(ComponentItemWrapper item, Integer damage) {
if (damage == null) {
item.resetComponent(ComponentTypes.MAX_DAMAGE);
} else {
item.setJavaComponent(ComponentTypes.MAX_DAMAGE, damage);
}
}
@Override
protected Optional<Enchantment> getEnchantment(ComponentItemWrapper item, Key key) {
Object enchant = item.getComponent(ComponentTypes.ENCHANTMENTS);
try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
Integer level = map.get(key.toString());
if (level == null) return Optional.empty();
return Optional.of(new Enchantment(key, level));
} catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to get enchantment " + key, e);
return Optional.empty();
}
}
@Override
protected void enchantments(ComponentItemWrapper item, List<Enchantment> enchantments) {
if (enchantments == null || enchantments.isEmpty()) {
item.resetComponent(ComponentTypes.ENCHANTMENTS);
} else {
Map<String, Integer> enchants = new HashMap<>();
for (Enchantment enchantment : enchantments) {
enchants.put(enchantment.id().toString(), enchantment.level());
}
item.setJavaComponent(ComponentTypes.ENCHANTMENTS, enchants);
}
}
@Override
protected void storedEnchantments(ComponentItemWrapper item, List<Enchantment> enchantments) {
if (enchantments == null || enchantments.isEmpty()) {
item.resetComponent(ComponentTypes.STORED_ENCHANTMENTS);
} else {
Map<String, Integer> enchants = new HashMap<>();
for (Enchantment enchantment : enchantments) {
enchants.put(enchantment.id().toString(), enchantment.level());
}
item.setJavaComponent(ComponentTypes.STORED_ENCHANTMENTS, enchants);
}
}
@Override
protected void addEnchantment(ComponentItemWrapper item, Enchantment enchantment) {
Object enchant = item.getComponent(ComponentTypes.ENCHANTMENTS);
try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
map.put(enchantment.toString(), enchantment.level());
item.setJavaComponent(ComponentTypes.ENCHANTMENTS, map);
} catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to add enchantment", e);
}
}
@Override
protected void addStoredEnchantment(ComponentItemWrapper item, Enchantment enchantment) {
Object enchant = item.getComponent(ComponentTypes.STORED_ENCHANTMENTS);
try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
map.put(enchantment.toString(), enchantment.level());
item.setJavaComponent(ComponentTypes.STORED_ENCHANTMENTS, map);
} catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to add stored enchantment", e);
}
}
@Override
protected void itemFlags(ComponentItemWrapper item, List<String> flags) {
throw new UnsupportedOperationException("This feature is not available on 1.20.5+");
}
@Override
protected int maxStackSize(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.MAX_STACK_SIZE)) return item.getItem().getType().getMaxStackSize();
return Optional.ofNullable((Integer) ComponentType.encodeJava(ComponentTypes.MAX_STACK_SIZE, item.getComponent(ComponentTypes.MAX_STACK_SIZE)).orElse(null))
.orElse(item.getItem().getType().getMaxStackSize());
}
@Override
protected void maxStackSize(ComponentItemWrapper item, Integer maxStackSize) {
if (maxStackSize == null) {
item.resetComponent(ComponentTypes.MAX_STACK_SIZE);
} else {
item.setJavaComponent(ComponentTypes.MAX_STACK_SIZE, maxStackSize);
}
}
@Override
protected void repairCost(ComponentItemWrapper item, Integer data) {
if (data == null) {
item.resetComponent(ComponentTypes.REPAIR_COST);
} else {
item.setJavaComponent(ComponentTypes.REPAIR_COST, data);
}
}
@Override
protected Optional<Integer> repairCost(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.REPAIR_COST)) return Optional.empty();
return Optional.ofNullable((Integer) ComponentType.encodeJava(ComponentTypes.REPAIR_COST, item.getComponent(ComponentTypes.REPAIR_COST)).orElse(null));
}
@Override
protected void trim(ComponentItemWrapper item, Trim trim) {
if (trim == null) {
item.resetComponent(ComponentTypes.TRIM);
} else {
item.setJavaComponent(ComponentTypes.TRIM, Map.of(
"pattern", trim.pattern(),
"material", trim.material()
));
}
}
@Override
protected Optional<Trim> trim(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.TRIM)) return Optional.empty();
Optional<Object> trim = ComponentType.encodeJava(ComponentTypes.TRIM, item.getComponent(ComponentTypes.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")));
}
@Override
protected ComponentItemWrapper mergeCopy(ComponentItemWrapper item1, ComponentItemWrapper item2) {
Object itemStack1 = item1.getLiteralObject();
Object itemStack2 = item2.getLiteralObject();
Object itemStack3 = FastNMS.INSTANCE.method$ItemStack$transmuteCopy(itemStack1, itemStack2);
FastNMS.INSTANCE.method$ItemStack$applyComponents(itemStack3, FastNMS.INSTANCE.method$ItemStack$getComponentsPatch(itemStack2));
return new ComponentItemWrapper(ItemObject.asCraftMirror(itemStack3), item2.count());
}
@Override
protected void merge(ComponentItemWrapper item1, ComponentItemWrapper item2) {
Object itemStack1 = item1.getLiteralObject();
Object itemStack2 = item2.getLiteralObject();
try {
FastNMS.INSTANCE.method$ItemStack$applyComponents(itemStack1, FastNMS.INSTANCE.method$ItemStack$getComponentsPatch(itemStack2));
} catch (Exception e) {
plugin.logger().warn("Failed to merge item", e);
}
}
}

View File

@@ -0,0 +1,38 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.saicone.rtag.data.ComponentType;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.core.item.JukeboxPlayable;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import java.util.Map;
import java.util.Optional;
@SuppressWarnings("UnstableApiUsage")
public class ComponentItemFactory1_21 extends ComponentItemFactory1_20_5 {
public ComponentItemFactory1_21(CraftEngine plugin) {
super(plugin);
}
@Override
protected Optional<JukeboxPlayable> jukeboxSong(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.JUKEBOX_PLAYABLE)) return Optional.empty();
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) ComponentType.encodeJava(
ComponentTypes.JUKEBOX_PLAYABLE,
item.getComponent(ComponentTypes.JUKEBOX_PLAYABLE)
).orElse(null);
if (map == null) return Optional.empty();
return Optional.of(new JukeboxPlayable((String) map.get("song"), (boolean) map.getOrDefault("show_in_tooltip", true)));
}
@Override
protected void jukeboxSong(ComponentItemWrapper item, JukeboxPlayable data) {
item.setJavaComponent(ComponentTypes.JUKEBOX_PLAYABLE, Map.of(
"song", data.song(),
"show_in_tooltip", true
));
}
}

View File

@@ -0,0 +1,71 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.saicone.rtag.data.ComponentType;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.core.item.EquipmentData;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import java.util.Optional;
@SuppressWarnings("UnstableApiUsage")
public class ComponentItemFactory1_21_2 extends ComponentItemFactory1_21 {
public ComponentItemFactory1_21_2(CraftEngine plugin) {
super(plugin);
}
@Override
protected void tooltipStyle(ComponentItemWrapper item, String data) {
if (data == null) {
item.resetComponent(ComponentTypes.TOOLTIP_STYLE);
} else {
item.setJavaComponent(ComponentTypes.TOOLTIP_STYLE, data);
}
}
@Override
protected Optional<String> tooltipStyle(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.TOOLTIP_STYLE)) return Optional.empty();
return Optional.ofNullable(
(String) ComponentType.encodeJava(
ComponentTypes.TOOLTIP_STYLE,
item.getComponent(ComponentTypes.TOOLTIP_STYLE)
).orElse(null)
);
}
@Override
protected void itemModel(ComponentItemWrapper item, String data) {
if (data == null) {
item.resetComponent(ComponentTypes.ITEM_MODEL);
} else {
item.setJavaComponent(ComponentTypes.ITEM_MODEL, data);
}
}
@Override
protected Optional<String> itemModel(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.ITEM_MODEL)) return Optional.empty();
return Optional.ofNullable(
(String) ComponentType.encodeJava(
ComponentTypes.ITEM_MODEL,
item.getComponent(ComponentTypes.ITEM_MODEL)
).orElse(null)
);
}
@Override
protected void equippable(ComponentItemWrapper item, EquipmentData data) {
if (data == null) {
item.resetComponent(ComponentTypes.EQUIPPABLE);
} else {
item.setJavaComponent(ComponentTypes.EQUIPPABLE, data.toMap());
}
}
@Override
protected Optional<EquipmentData> equippable(ComponentItemWrapper item) {
throw new UnsupportedOperationException("Not implemented yet.");
}
}

View File

@@ -1,26 +1,25 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.saicone.rtag.data.ComponentType;
import net.momirealms.craftengine.core.item.ComponentKeys;
import net.momirealms.craftengine.core.item.ItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@SuppressWarnings("UnstableApiUsage")
public class ComponentItemFactory1_21_4 extends ComponentItemFactory {
public class ComponentItemFactory1_21_4 extends ComponentItemFactory1_21_2 {
public ComponentItemFactory1_21_4(CraftEngine plugin) {
super(plugin);
}
@Override
protected Optional<Integer> customModelData(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.CUSTOM_MODEL_DATA)) return Optional.empty();
Optional<Object> optional = ComponentType.encodeJava(ComponentKeys.CUSTOM_MODEL_DATA, item.getComponent(ComponentKeys.CUSTOM_MODEL_DATA));
protected Optional<Integer> customModelData(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.CUSTOM_MODEL_DATA)) return Optional.empty();
Optional<Object> optional = ComponentType.encodeJava(ComponentTypes.CUSTOM_MODEL_DATA, item.getComponent(ComponentTypes.CUSTOM_MODEL_DATA));
if (optional.isEmpty()) return Optional.empty();
@SuppressWarnings("unchecked")
Map<String, Object> data = (Map<String, Object>) optional.get();
@@ -31,11 +30,11 @@ public class ComponentItemFactory1_21_4 extends ComponentItemFactory {
}
@Override
protected void customModelData(ItemWrapper<ItemStack> item, Integer data) {
protected void customModelData(ComponentItemWrapper item, Integer data) {
if (data == null) {
resetComponent(item, ComponentKeys.CUSTOM_MODEL_DATA);
item.resetComponent(ComponentTypes.CUSTOM_MODEL_DATA);
} else {
setComponent(item, ComponentKeys.CUSTOM_MODEL_DATA, Map.of("floats", List.of(data.floatValue())));
item.setJavaComponent(ComponentTypes.CUSTOM_MODEL_DATA, Map.of("floats", List.of(data.floatValue())));
}
}
}

View File

@@ -5,12 +5,12 @@ import com.google.gson.JsonElement;
import com.saicone.rtag.data.ComponentType;
import com.saicone.rtag.tag.TagList;
import com.saicone.rtag.util.ChatComponent;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.bukkit.util.ComponentUtils;
import net.momirealms.craftengine.core.item.ComponentKeys;
import net.momirealms.craftengine.core.item.ItemWrapper;
import net.momirealms.craftengine.core.item.JukeboxPlayable;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.GsonHelper;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
@@ -24,41 +24,41 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 {
}
@Override
protected void customName(ItemWrapper<ItemStack> item, String json) {
protected void customName(ComponentItemWrapper item, String json) {
if (json == null) {
resetComponent(item, ComponentKeys.CUSTOM_NAME);
item.resetComponent(ComponentTypes.CUSTOM_NAME);
} else {
setNBTComponentDirectly(item, ComponentKeys.CUSTOM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json)));
item.setNBTComponent(ComponentTypes.CUSTOM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json)));
}
}
@Override
protected Optional<String> customName(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.CUSTOM_NAME)) return Optional.empty();
return ComponentType.encodeJson(ComponentKeys.CUSTOM_NAME, item.getComponent(ComponentKeys.CUSTOM_NAME)).map(jsonElement -> GsonHelper.get().toJson(jsonElement));
protected Optional<String> customName(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.CUSTOM_NAME)) return Optional.empty();
return ComponentType.encodeJson(ComponentTypes.CUSTOM_NAME, item.getComponent(ComponentTypes.CUSTOM_NAME)).map(jsonElement -> GsonHelper.get().toJson(jsonElement));
}
@Override
protected void itemName(ItemWrapper<ItemStack> item, String json) {
protected void itemName(ComponentItemWrapper item, String json) {
if (json == null) {
resetComponent(item, ComponentKeys.ITEM_NAME);
item.resetComponent(ComponentTypes.ITEM_NAME);
} else {
setNBTComponentDirectly(item, ComponentKeys.ITEM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json)));
item.setNBTComponent(ComponentTypes.ITEM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json)));
}
}
@Override
protected Optional<String> itemName(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.ITEM_NAME)) return Optional.empty();
return ComponentType.encodeJson(ComponentKeys.ITEM_NAME, item.getComponent(ComponentKeys.ITEM_NAME)).map(jsonElement -> GsonHelper.get().toJson(jsonElement));
protected Optional<String> itemName(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.ITEM_NAME)) return Optional.empty();
return ComponentType.encodeJson(ComponentTypes.ITEM_NAME, item.getComponent(ComponentTypes.ITEM_NAME)).map(jsonElement -> GsonHelper.get().toJson(jsonElement));
}
@Override
protected Optional<List<String>> lore(ItemWrapper<ItemStack> item) {
if (!item.hasComponent(ComponentKeys.LORE)) return Optional.empty();
protected Optional<List<String>> lore(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.LORE)) return Optional.empty();
return ComponentType.encodeJson(
ComponentKeys.LORE,
item.getComponent(ComponentKeys.LORE)
ComponentTypes.LORE,
item.getComponent(ComponentTypes.LORE)
).map(list -> {
List<String> lore = new ArrayList<>();
for (JsonElement jsonElement : (JsonArray) list) {
@@ -69,15 +69,30 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 {
}
@Override
protected void lore(ItemWrapper<ItemStack> item, List<String> lore) {
protected void lore(ComponentItemWrapper item, List<String> lore) {
if (lore == null || lore.isEmpty()) {
resetComponent(item, ComponentKeys.LORE);
item.resetComponent(ComponentTypes.LORE);
} else {
List<Object> loreTags = new ArrayList<>();
for (String json : lore) {
loreTags.add(ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json)));
}
setNBTComponentDirectly(item, ComponentKeys.LORE, TagList.newTag(loreTags));
item.setNBTComponent(ComponentTypes.LORE, TagList.newTag(loreTags));
}
}
@Override
protected Optional<JukeboxPlayable> jukeboxSong(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.JUKEBOX_PLAYABLE)) return Optional.empty();
String song = (String) ComponentType.encodeJava(
ComponentTypes.JUKEBOX_PLAYABLE,
item.getComponent(ComponentTypes.JUKEBOX_PLAYABLE)).orElse(null);
if (song == null) return Optional.empty();
return Optional.of(new JukeboxPlayable(song, true));
}
@Override
protected void jukeboxSong(ComponentItemWrapper item, JukeboxPlayable data) {
item.setJavaComponent(ComponentTypes.JUKEBOX_PLAYABLE, data.song());
}
}

View File

@@ -1,15 +1,14 @@
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;
import com.saicone.rtag.tag.TagCompound;
import com.saicone.rtag.tag.TagList;
import net.momirealms.craftengine.bukkit.item.RTagItemWrapper;
import net.momirealms.craftengine.bukkit.item.LegacyItemWrapper;
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.item.modifier.IdModifier;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.SkullUtils;
@@ -17,54 +16,55 @@ import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class UniversalItemFactory extends BukkitItemFactory {
public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
public UniversalItemFactory(CraftEngine plugin) {
super(plugin);
}
@Override
protected void resetComponent(ItemWrapper<ItemStack> item, Key type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
protected LegacyItemWrapper wrapInternal(ItemStack item) {
return new LegacyItemWrapper(new RtagItem(item), item.getAmount());
}
@Override
protected JsonElement encodeJson(Key type, Object component) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
protected void setTag(LegacyItemWrapper item, Object value, Object... path) {
item.set(value, path);
}
@Override
protected void setComponent(ItemWrapper<ItemStack> item, Key type, Object value) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
protected Object getTag(LegacyItemWrapper item, Object... path) {
return item.get(path);
}
@Override
protected Object getComponent(ItemWrapper<ItemStack> item, Key type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
protected boolean hasTag(LegacyItemWrapper item, Object... path) {
return item.hasTag(path);
}
@Override
protected boolean hasComponent(ItemWrapper<ItemStack> item, Key type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
protected boolean removeTag(LegacyItemWrapper item, Object... path) {
return item.remove(path);
}
@Override
protected void removeComponent(ItemWrapper<ItemStack> item, Key type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
protected Optional<Key> customId(LegacyItemWrapper item) {
Object id = item.get(IdModifier.CRAFT_ENGINE_ID);
if (id == null) return Optional.empty();
return Optional.of(Key.of(id.toString()));
}
@Override
public Object encodeJava(Key componentType, @Nullable Object component) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
protected void customId(LegacyItemWrapper item, Key id) {
item.set(id.toString(), IdModifier.CRAFT_ENGINE_ID);
}
@Override
protected void customName(ItemWrapper<ItemStack> item, String json) {
protected void customName(LegacyItemWrapper item, String json) {
if (json != null) {
item.set(json, "display", "Name");
} else {
@@ -73,23 +73,23 @@ public class UniversalItemFactory extends BukkitItemFactory {
}
@Override
protected Optional<String> customName(ItemWrapper<ItemStack> item) {
protected Optional<String> customName(LegacyItemWrapper item) {
if (!item.hasTag("display", "Name")) return Optional.empty();
return Optional.of(item.get("display", "Name"));
}
@Override
protected void itemName(ItemWrapper<ItemStack> item, String json) {
protected void itemName(LegacyItemWrapper item, String json) {
customName(item, json);
}
@Override
protected Optional<String> itemName(ItemWrapper<ItemStack> item) {
protected Optional<String> itemName(LegacyItemWrapper item) {
return customName(item);
}
@Override
protected void customModelData(ItemWrapper<ItemStack> item, Integer data) {
protected void customModelData(LegacyItemWrapper item, Integer data) {
if (data == null) {
item.remove("CustomModelData");
} else {
@@ -98,13 +98,13 @@ public class UniversalItemFactory extends BukkitItemFactory {
}
@Override
protected Optional<Integer> customModelData(ItemWrapper<ItemStack> item) {
protected Optional<Integer> customModelData(LegacyItemWrapper item) {
if (!item.hasTag("CustomModelData")) return Optional.empty();
return Optional.of(item.get("CustomModelData"));
}
@Override
protected void skull(ItemWrapper<ItemStack> item, String skullData) {
protected void skull(LegacyItemWrapper item, String skullData) {
if (skullData == null) {
item.remove("SkullOwner");
} else {
@@ -117,13 +117,13 @@ public class UniversalItemFactory extends BukkitItemFactory {
}
@Override
protected Optional<List<String>> lore(ItemWrapper<ItemStack> item) {
protected Optional<List<String>> lore(LegacyItemWrapper item) {
if (!item.hasTag("display", "Lore")) return Optional.empty();
return Optional.of(item.get("display", "Lore"));
}
@Override
protected void lore(ItemWrapper<ItemStack> item, List<String> lore) {
protected void lore(LegacyItemWrapper item, List<String> lore) {
if (lore == null || lore.isEmpty()) {
item.remove("display", "Lore");
} else {
@@ -132,48 +132,38 @@ public class UniversalItemFactory extends BukkitItemFactory {
}
@Override
protected boolean unbreakable(ItemWrapper<ItemStack> item) {
protected boolean unbreakable(LegacyItemWrapper item) {
return Optional.ofNullable((Boolean) item.get("Unbreakable")).orElse(false);
}
@Override
protected void unbreakable(ItemWrapper<ItemStack> item, boolean unbreakable) {
protected void unbreakable(LegacyItemWrapper item, boolean unbreakable) {
item.set(unbreakable, "Unbreakable");
}
@Override
protected Optional<Boolean> glint(ItemWrapper<ItemStack> item) {
return Optional.of(false);
}
@Override
protected void glint(ItemWrapper<ItemStack> item, Boolean glint) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected Optional<Integer> damage(ItemWrapper<ItemStack> item) {
protected Optional<Integer> damage(LegacyItemWrapper item) {
if (!item.hasTag("Damage")) return Optional.empty();
return Optional.of(item.get("Damage"));
}
@Override
protected void damage(ItemWrapper<ItemStack> item, Integer damage) {
protected void damage(LegacyItemWrapper item, Integer damage) {
item.set(damage, "Damage");
}
@Override
protected Optional<Integer> maxDamage(ItemWrapper<ItemStack> item) {
protected Optional<Integer> maxDamage(LegacyItemWrapper item) {
return Optional.of((int) item.getItem().getType().getMaxDurability());
}
@Override
protected void maxDamage(ItemWrapper<ItemStack> item, Integer damage) {
protected void maxDamage(LegacyItemWrapper item, Integer damage) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void enchantments(ItemWrapper<ItemStack> item, List<Enchantment> enchantments) {
protected void enchantments(LegacyItemWrapper item, List<Enchantment> enchantments) {
if (enchantments == null || enchantments.isEmpty()) {
item.remove("Enchantments");
return;
@@ -186,7 +176,7 @@ public class UniversalItemFactory extends BukkitItemFactory {
}
@Override
protected void storedEnchantments(ItemWrapper<ItemStack> item, List<Enchantment> enchantments) {
protected void storedEnchantments(LegacyItemWrapper item, List<Enchantment> enchantments) {
if (enchantments == null || enchantments.isEmpty()) {
item.remove("StoredEnchantments");
return;
@@ -199,7 +189,7 @@ public class UniversalItemFactory extends BukkitItemFactory {
}
@Override
protected void addEnchantment(ItemWrapper<ItemStack> item, Enchantment enchantment) {
protected void addEnchantment(LegacyItemWrapper item, Enchantment enchantment) {
Object enchantments = item.getExact("Enchantments");
if (enchantments != null) {
for (Object enchant : TagList.getValue(enchantments)) {
@@ -215,7 +205,7 @@ public class UniversalItemFactory extends BukkitItemFactory {
}
@Override
protected void addStoredEnchantment(ItemWrapper<ItemStack> item, Enchantment enchantment) {
protected void addStoredEnchantment(LegacyItemWrapper item, Enchantment enchantment) {
Object enchantments = item.getExact("StoredEnchantments");
if (enchantments != null) {
for (Object enchant : TagList.getValue(enchantments)) {
@@ -232,14 +222,14 @@ public class UniversalItemFactory extends BukkitItemFactory {
@SuppressWarnings("deprecation")
@Override
protected Optional<Enchantment> getEnchantment(ItemWrapper<ItemStack> item, Key key) {
protected Optional<Enchantment> getEnchantment(LegacyItemWrapper item, Key key) {
int level = item.getItem().getEnchantmentLevel(Objects.requireNonNull(Registry.ENCHANTMENT.get(new NamespacedKey(key.namespace(), key.value()))));
if (level <= 0) return Optional.empty();
return Optional.of(new Enchantment(key, level));
}
@Override
protected void itemFlags(ItemWrapper<ItemStack> item, List<String> flags) {
protected void itemFlags(LegacyItemWrapper item, List<String> flags) {
if (flags == null || flags.isEmpty()) {
item.remove("HideFlags");
return;
@@ -253,44 +243,28 @@ public class UniversalItemFactory extends BukkitItemFactory {
}
@Override
protected int maxStackSize(ItemWrapper<ItemStack> item) {
protected int maxStackSize(LegacyItemWrapper item) {
return item.getItem().getType().getMaxStackSize();
}
@Override
protected void maxStackSize(ItemWrapper<ItemStack> item, Integer maxStackSize) {
protected void maxStackSize(LegacyItemWrapper item, Integer maxStackSize) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void repairCost(ItemWrapper<ItemStack> item, Integer data) {
protected void repairCost(LegacyItemWrapper item, Integer data) {
item.set(data, "RepairCost");
}
@Override
protected Optional<Integer> repairCost(ItemWrapper<ItemStack> item) {
protected Optional<Integer> repairCost(LegacyItemWrapper item) {
if (!item.hasTag("RepairCost")) return Optional.empty();
return Optional.of(item.get("RepairCost"));
}
@Override
protected ItemWrapper<ItemStack> mergeCopy(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) {
Object itemStack = ItemObject.copy(item2.getLiteralObject());
ItemObject.setCustomDataTag(itemStack, TagCompound.clone(ItemObject.getCustomDataTag(item1.getLiteralObject())));
// one more step than vanilla
TagCompound.merge(ItemObject.getCustomDataTag(itemStack), ItemObject.getCustomDataTag(item2.getLiteralObject()), true, true);
return new RTagItemWrapper(new RtagItem(ItemObject.asCraftMirror(itemStack)), item2.count());
}
@Override
protected void merge(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) {
// load previous changes on nms items
item1.load();
TagCompound.merge(ItemObject.getCustomDataTag(item1.getLiteralObject()), ItemObject.getCustomDataTag(item2.getLiteralObject()), true, true);
}
@Override
protected void trim(ItemWrapper<ItemStack> item, Trim trim) {
protected void trim(LegacyItemWrapper item, Trim trim) {
if (trim == null) {
item.remove("Trim");
return;
@@ -300,10 +274,28 @@ public class UniversalItemFactory extends BukkitItemFactory {
}
@Override
protected Optional<Trim> trim(ItemWrapper<ItemStack> item) {
protected Optional<Trim> trim(LegacyItemWrapper 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));
}
@Override
protected LegacyItemWrapper mergeCopy(LegacyItemWrapper item1, LegacyItemWrapper item2) {
Object itemStack = ItemObject.copy(item2.getLiteralObject());
ItemObject.setCustomDataTag(itemStack, TagCompound.clone(ItemObject.getCustomDataTag(item1.getLiteralObject())));
// one more step than vanilla
TagCompound.merge(ItemObject.getCustomDataTag(itemStack), ItemObject.getCustomDataTag(item2.getLiteralObject()), true, true);
return new LegacyItemWrapper(new RtagItem(ItemObject.asCraftMirror(itemStack)), item2.count());
}
@Override
protected void merge(LegacyItemWrapper item1, LegacyItemWrapper item2) {
// load previous changes on nms items
item1.load();
TagCompound.merge(ItemObject.getCustomDataTag(item1.getLiteralObject()), ItemObject.getCustomDataTag(item2.getLiteralObject()), true, true);
// update wrapped item
item1.update();
}
}

View File

@@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.item.recipe;
import com.destroystokyo.paper.event.inventory.PrepareResultEvent;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.injector.BukkitInjector;
@@ -587,7 +588,7 @@ public class RecipeEventListener implements Listener {
} catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to get hover name", e);
}
} else if (VersionHelper.isVersionNewerThan1_20_5() && wrappedFirst.hasComponent(ComponentKeys.CUSTOM_NAME)) {
} else if (VersionHelper.isVersionNewerThan1_20_5() && wrappedFirst.hasComponent(ComponentTypes.CUSTOM_NAME)) {
repairCost += 1;
wrappedFirst.customName(null);
} else if (!VersionHelper.isVersionNewerThan1_20_5() && wrappedFirst.hasTag("display", "Name")) {

View File

@@ -6515,4 +6515,10 @@ public class Reflections {
? ReflectionUtils.getConstructor(clazz$ServerboundResourcePackPacket, UUID.class, clazz$ServerboundResourcePackPacket$Action)
: ReflectionUtils.getConstructor(clazz$ServerboundResourcePackPacket, clazz$ServerboundResourcePackPacket$Action)
);
public static final Class<?> clazz$DataComponentType = ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass(
"core.component.DataComponentType"
)
);
}