9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 20:39:10 +00:00

优化组件物品构建

This commit is contained in:
XiaoMoMi
2025-05-27 21:54:15 +08:00
parent e6564af5bd
commit fb40b49549
26 changed files with 447 additions and 264 deletions

View File

@@ -151,7 +151,7 @@ public class BukkitFontManager extends AbstractFontManager implements Listener {
EmojiComponentProcessResult replaceProcessResult = replaceComponentEmoji(itemName, plugin.adapt(player), renameText);
if (replaceProcessResult.changed()) {
Item<ItemStack> wrapped = this.plugin.itemManager().wrap(result);
wrapped.customName(AdventureHelper.componentToJson(replaceProcessResult.newText()));
wrapped.customNameJson(AdventureHelper.componentToJson(replaceProcessResult.newText()));
event.setResult(wrapped.load());
}
}

View File

@@ -1,26 +1,31 @@
package net.momirealms.craftengine.bukkit.item;
import com.google.gson.JsonElement;
import com.saicone.rtag.RtagItem;
import com.saicone.rtag.data.ComponentType;
import com.saicone.rtag.tag.TagBase;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.DynamicOps;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.item.ItemWrapper;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.sparrow.nbt.Tag;
import org.bukkit.inventory.ItemStack;
@SuppressWarnings("UnstableApiUsage")
import java.util.Optional;
public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
private final ItemStack item;
private final Object handle;
public ComponentItemWrapper(final ItemStack item) {
this.item = FastNMS.INSTANCE.ensureCraftItemStack(item);
this.handle = FastNMS.INSTANCE.field$CraftItemStack$handle(this.item);
}
public ComponentItemWrapper(final ItemStack item, int count) {
this.item = FastNMS.INSTANCE.ensureCraftItemStack(item);
this.item.setAmount(count);
this.handle = FastNMS.INSTANCE.field$CraftItemStack$handle(this.item);
}
public void removeComponent(Object type) {
@@ -34,31 +39,86 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
public void setComponent(Object type, final Object value) {
if (value instanceof JsonElement jsonElement) {
setJsonComponent(type, jsonElement);
} else if (TagBase.isTag(value)) {
} else if (Reflections.clazz$Tag.isInstance(value)) {
setNBTComponent(type, value);
} else if (value instanceof Tag tag) {
setSparrowNBTComponent(type, tag);
} else {
setJavaComponent(type, value);
}
}
public Object getComponent(Object type) {
public Object getComponentExact(Object type) {
return FastNMS.INSTANCE.getComponent(getLiteralObject(), ensureDataComponentType(type));
}
public <T> Optional<T> getJavaComponent(Object type) {
return getComponentInternal(type, Reflections.instance$JAVA_OPS);
}
public Optional<JsonElement> getJsonComponent(Object type) {
return getComponentInternal(type, Reflections.instance$JSON_OPS);
}
public Optional<Object> getNBTComponent(Object type) {
return getComponentInternal(type, Reflections.instance$NBT_OPS);
}
public Optional<Tag> getSparrowNBTComponent(Object type) {
return getComponentInternal(type, Reflections.instance$SPARROW_NBT_OPS);
}
@SuppressWarnings({"rawtypes", "unchecked"})
private <T> Optional<T> getComponentInternal(Object type, DynamicOps ops) {
Object componentType = ensureDataComponentType(type);
Codec codec = FastNMS.INSTANCE.method$DataComponentType$codec(componentType);
try {
Object componentData = FastNMS.INSTANCE.getComponent(getLiteralObject(), componentType);
if (componentData == null) return Optional.empty();
DataResult<Object> result = codec.encodeStart(ops, componentData);
return (Optional<T>) result.result();
} catch (Throwable t) {
throw new RuntimeException("Cannot read component " + type.toString(), t);
}
}
public boolean hasComponent(Object type) {
return FastNMS.INSTANCE.hasComponent(getLiteralObject(), ensureDataComponentType(type));
}
public void setComponentExact(Object type, final Object value) {
FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), value);
}
public void setJavaComponent(Object type, Object value) {
ComponentType.parseJava(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), it));
setComponentInternal(type, Reflections.instance$JAVA_OPS, value);
}
public void setJsonComponent(Object type, JsonElement value) {
ComponentType.parseJson(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), it));
setComponentInternal(type, Reflections.instance$JSON_OPS, value);
}
public void setNBTComponent(Object type, Object value) {
ComponentType.parseNbt(type, value).ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), it));
setComponentInternal(type, Reflections.instance$NBT_OPS, value);
}
public void setSparrowNBTComponent(Object type, Tag value) {
setComponentInternal(type, Reflections.instance$SPARROW_NBT_OPS, value);
}
@SuppressWarnings({"rawtypes", "unchecked"})
private void setComponentInternal(Object type, DynamicOps ops, Object value) {
Object componentType = ensureDataComponentType(type);
Codec codec = FastNMS.INSTANCE.method$DataComponentType$codec(componentType);
try {
DataResult<Object> result = codec.parse(ops, value);
if (result.isError()) {
throw new IllegalArgumentException(result.toString());
}
result.result().ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), componentType, it));
} catch (Throwable t) {
throw new RuntimeException("Cannot parse component " + type.toString(), t);
}
}
private Object ensureDataComponentType(Object type) {
@@ -89,7 +149,7 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
@Override
public Object getLiteralObject() {
return FastNMS.INSTANCE.field$CraftItemStack$handle(this.item);
return this.handle;
}
@Override

View File

@@ -1,17 +1,11 @@
package net.momirealms.craftengine.bukkit.item;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.util.AdventureHelper;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class LegacyNetworkItemHandler implements NetworkItemHandler {

View File

@@ -1,6 +1,5 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.google.gson.JsonElement;
import com.saicone.rtag.item.ItemTagStream;
import net.momirealms.craftengine.bukkit.util.ItemTags;
import net.momirealms.craftengine.bukkit.util.Reflections;
@@ -11,7 +10,6 @@ import net.momirealms.craftengine.core.item.JukeboxPlayable;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.Optional;
@@ -89,16 +87,6 @@ public abstract class BukkitItemFactory<W extends ItemWrapper<ItemStack>> extend
}
}
@Override
protected JsonElement encodeJson(Object type, Object component) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
public Object encodeJava(Object componentType, @Nullable Object component) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void resetComponent(W item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
@@ -110,7 +98,7 @@ public abstract class BukkitItemFactory<W extends ItemWrapper<ItemStack>> extend
}
@Override
protected Object getComponent(W item, Object type) {
protected Object getExactComponent(W item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}

View File

@@ -1,8 +1,6 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.google.gson.JsonElement;
import com.saicone.rtag.data.ComponentType;
import com.saicone.rtag.item.ItemObject;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
@@ -11,15 +9,14 @@ import net.momirealms.craftengine.core.item.Enchantment;
import net.momirealms.craftengine.core.item.Trim;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.sparrow.nbt.Tag;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@SuppressWarnings("UnstableApiUsage")
public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemWrapper> {
public ComponentItemFactory1_20_5(CraftEngine plugin) {
@@ -82,8 +79,23 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
}
@Override
protected Object getComponent(ComponentItemWrapper item, Object type) {
return item.getComponent(type);
protected Object getExactComponent(ComponentItemWrapper item, Object type) {
return item.getComponentExact(type);
}
@Override
protected Object getJavaComponent(ComponentItemWrapper item, Object type) {
return item.getJavaComponent(type).orElse(null);
}
@Override
protected JsonElement getJsonComponent(ComponentItemWrapper item, Object type) {
return item.getJsonComponent(type).orElse(null);
}
@Override
protected Tag getNBTComponent(ComponentItemWrapper item, Object type) {
return item.getSparrowNBTComponent(type).orElse(null);
}
@Override
@@ -96,16 +108,6 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
item.removeComponent(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) {
@@ -117,16 +119,11 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
@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));
return item.getJavaComponent(ComponentTypes.CUSTOM_MODEL_DATA);
}
@Override
protected void customName(ComponentItemWrapper item, String json) {
protected void customNameJson(ComponentItemWrapper item, String json) {
if (json == null) {
item.resetComponent(ComponentTypes.CUSTOM_NAME);
} else {
@@ -135,18 +132,12 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
}
@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)
);
protected Optional<String> customNameJson(ComponentItemWrapper item) {
return item.getJavaComponent(ComponentTypes.CUSTOM_NAME);
}
@Override
protected void itemName(ComponentItemWrapper item, String json) {
protected void itemNameJson(ComponentItemWrapper item, String json) {
if (json == null) {
item.resetComponent(ComponentTypes.ITEM_NAME);
} else {
@@ -155,14 +146,8 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
}
@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)
);
protected Optional<String> itemNameJson(ComponentItemWrapper item) {
return item.getJavaComponent(ComponentTypes.ITEM_NAME);
}
@Override
@@ -175,20 +160,13 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
}
}
@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)
);
protected Optional<List<String>> loreJson(ComponentItemWrapper item) {
return item.getJavaComponent(ComponentTypes.LORE);
}
@Override
protected void lore(ComponentItemWrapper item, List<String> lore) {
protected void loreJson(ComponentItemWrapper item, List<String> lore) {
if (lore == null || lore.isEmpty()) {
item.resetComponent(ComponentTypes.LORE);
} else {
@@ -212,7 +190,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
@Override
protected Optional<Boolean> glint(ComponentItemWrapper item) {
return Optional.ofNullable((Boolean) item.getComponent(ComponentTypes.ENCHANTMENT_GLINT_OVERRIDE));
return Optional.ofNullable((Boolean) item.getComponentExact(ComponentTypes.ENCHANTMENT_GLINT_OVERRIDE));
}
@Override
@@ -226,13 +204,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
@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)
);
return item.getJavaComponent(ComponentTypes.DAMAGE);
}
@Override
@@ -247,10 +219,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
@Override
protected Optional<Integer> dyedColor(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.DYED_COLOR)) return Optional.empty();
Object javaObj = ComponentType.encodeJava(
ComponentTypes.DYED_COLOR,
item.getComponent(ComponentTypes.DYED_COLOR)
).orElse(null);
Object javaObj = getJavaComponent(item, ComponentTypes.DYED_COLOR);
if (javaObj instanceof Integer integer) {
return Optional.of(integer);
} else if (javaObj instanceof Map<?, ?> map) {
@@ -269,14 +238,9 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
}
@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)
);
protected int maxDamage(ComponentItemWrapper item) {
Optional<Integer> damage = item.getJavaComponent(ComponentTypes.MAX_DAMAGE);
return damage.orElseGet(() -> (int) item.getItem().getType().getMaxDurability());
}
@Override
@@ -290,7 +254,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
@Override
protected Optional<Enchantment> getEnchantment(ComponentItemWrapper item, Key key) {
Object enchant = item.getComponent(ComponentTypes.ENCHANTMENTS);
Object enchant = item.getComponentExact(ComponentTypes.ENCHANTMENTS);
try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
Integer level = map.get(key.toString());
@@ -330,7 +294,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
@Override
protected void addEnchantment(ComponentItemWrapper item, Enchantment enchantment) {
Object enchant = item.getComponent(ComponentTypes.ENCHANTMENTS);
Object enchant = item.getComponentExact(ComponentTypes.ENCHANTMENTS);
try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
map.put(enchantment.id().toString(), enchantment.level());
@@ -342,7 +306,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
@Override
protected void addStoredEnchantment(ComponentItemWrapper item, Enchantment enchantment) {
Object enchant = item.getComponent(ComponentTypes.STORED_ENCHANTMENTS);
Object enchant = item.getComponentExact(ComponentTypes.STORED_ENCHANTMENTS);
try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
map.put(enchantment.id().toString(), enchantment.level());
@@ -359,9 +323,8 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
@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());
Optional<Integer> stackSize = item.getJavaComponent(ComponentTypes.MAX_STACK_SIZE);
return stackSize.orElseGet(() -> item.getItem().getType().getMaxStackSize());
}
@Override
@@ -384,8 +347,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
@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));
return item.getJavaComponent(ComponentTypes.REPAIR_COST);
}
@Override
@@ -402,8 +364,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
@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));
Optional<Object> trim = item.getJavaComponent(ComponentTypes.TRIM);
if (trim.isEmpty()) {
return Optional.empty();
}
@@ -418,7 +379,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
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());
return new ComponentItemWrapper(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(itemStack3), item2.count());
}
@Override

View File

@@ -1,6 +1,5 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.saicone.rtag.data.ComponentType;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.core.item.JukeboxPlayable;
@@ -9,7 +8,6 @@ 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) {
@@ -18,14 +16,11 @@ public class ComponentItemFactory1_21 extends ComponentItemFactory1_20_5 {
@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)));
Optional<Map<String, Object>> map = item.getJavaComponent(ComponentTypes.JUKEBOX_PLAYABLE);
return map.map(song -> new JukeboxPlayable(
(String) song.get("song"),
(boolean) song.getOrDefault("show_in_tooltip", true))
);
}
@Override

View File

@@ -1,6 +1,5 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.saicone.rtag.data.ComponentType;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.core.item.EquipmentData;
@@ -8,7 +7,6 @@ import net.momirealms.craftengine.core.plugin.CraftEngine;
import java.util.Optional;
@SuppressWarnings("UnstableApiUsage")
public class ComponentItemFactory1_21_2 extends ComponentItemFactory1_21 {
public ComponentItemFactory1_21_2(CraftEngine plugin) {
@@ -26,13 +24,7 @@ public class ComponentItemFactory1_21_2 extends ComponentItemFactory1_21 {
@Override
protected Optional<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)
);
return item.getJavaComponent(ComponentTypes.TOOLTIP_STYLE);
}
@Override
@@ -46,13 +38,7 @@ public class ComponentItemFactory1_21_2 extends ComponentItemFactory1_21 {
@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)
);
return item.getJavaComponent(ComponentTypes.ITEM_MODEL);
}
@Override

View File

@@ -1,6 +1,5 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.saicone.rtag.data.ComponentType;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.core.plugin.CraftEngine;
@@ -9,7 +8,6 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
@SuppressWarnings("UnstableApiUsage")
public class ComponentItemFactory1_21_4 extends ComponentItemFactory1_21_2 {
public ComponentItemFactory1_21_4(CraftEngine plugin) {
@@ -18,8 +16,7 @@ public class ComponentItemFactory1_21_4 extends ComponentItemFactory1_21_2 {
@Override
protected Optional<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));
Optional<Object> optional = item.getJavaComponent(ComponentTypes.CUSTOM_MODEL_DATA);
if (optional.isEmpty()) return Optional.empty();
@SuppressWarnings("unchecked")
Map<String, Object> data = (Map<String, Object>) optional.get();

View File

@@ -3,14 +3,16 @@ package net.momirealms.craftengine.bukkit.item.factory;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.saicone.rtag.data.ComponentType;
import com.saicone.rtag.tag.TagList;
import com.saicone.rtag.util.ChatComponent;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.bukkit.util.ComponentUtils;
import net.momirealms.craftengine.core.item.JukeboxPlayable;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.AdventureHelper;
import net.momirealms.craftengine.core.util.GsonHelper;
import net.momirealms.sparrow.nbt.ListTag;
import net.momirealms.sparrow.nbt.Tag;
import net.momirealms.sparrow.nbt.serializer.NBTComponentSerializer;
import java.util.ArrayList;
import java.util.List;
@@ -24,60 +26,91 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 {
}
@Override
protected void customName(ComponentItemWrapper item, String json) {
protected void customNameJson(ComponentItemWrapper item, String json) {
if (json == null) {
item.resetComponent(ComponentTypes.CUSTOM_NAME);
} else {
item.setNBTComponent(ComponentTypes.CUSTOM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json)));
item.setSparrowNBTComponent(ComponentTypes.CUSTOM_NAME, NBTComponentSerializer.nbt().serialize(AdventureHelper.jsonToComponent(json)));
}
}
@Override
protected Optional<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));
protected Optional<String> customNameJson(ComponentItemWrapper item) {
return item.getJsonComponent(ComponentTypes.CUSTOM_NAME).map(it -> GsonHelper.get().toJson(it));
}
@Override
protected void itemName(ComponentItemWrapper item, String json) {
protected void customNameComponent(ComponentItemWrapper item, Component component) {
if (component == null) {
item.resetComponent(ComponentTypes.CUSTOM_NAME);
} else {
item.setSparrowNBTComponent(ComponentTypes.CUSTOM_NAME, NBTComponentSerializer.nbt().serialize(component));
}
}
@Override
protected Optional<Component> customNameComponent(ComponentItemWrapper item) {
return customNameJson(item).map(AdventureHelper::jsonToComponent);
}
@Override
protected void itemNameJson(ComponentItemWrapper item, String json) {
if (json == null) {
item.resetComponent(ComponentTypes.ITEM_NAME);
} else {
item.setNBTComponent(ComponentTypes.ITEM_NAME, ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json)));
item.setSparrowNBTComponent(ComponentTypes.ITEM_NAME, NBTComponentSerializer.nbt().serialize(AdventureHelper.jsonToComponent(json)));
}
}
@Override
protected Optional<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));
protected void itemNameComponent(ComponentItemWrapper item, Component component) {
if (component == null) {
item.resetComponent(ComponentTypes.ITEM_NAME);
} else {
item.setSparrowNBTComponent(ComponentTypes.ITEM_NAME, NBTComponentSerializer.nbt().serialize(component));
}
}
@Override
protected Optional<List<String>> lore(ComponentItemWrapper item) {
protected Optional<String> itemNameJson(ComponentItemWrapper item) {
return item.getJsonComponent(ComponentTypes.ITEM_NAME).map(it -> GsonHelper.get().toJson(it));
}
@Override
protected Optional<List<String>> loreJson(ComponentItemWrapper item) {
if (!item.hasComponent(ComponentTypes.LORE)) return Optional.empty();
return ComponentType.encodeJson(
ComponentTypes.LORE,
item.getComponent(ComponentTypes.LORE)
).map(list -> {
List<String> lore = new ArrayList<>();
for (JsonElement jsonElement : (JsonArray) list) {
lore.add(GsonHelper.get().toJson(jsonElement));
}
return lore;
});
Optional<JsonElement> json = item.getJsonComponent(ComponentTypes.LORE);
if (json.isEmpty()) return Optional.empty();
List<String> lore = new ArrayList<>();
for (JsonElement jsonElement : (JsonArray) json.get()) {
lore.add(GsonHelper.get().toJson(jsonElement));
}
return Optional.of(lore);
}
@Override
protected void lore(ComponentItemWrapper item, List<String> lore) {
protected void loreComponent(ComponentItemWrapper item, List<Component> lore) {
if (lore == null || lore.isEmpty()) {
item.resetComponent(ComponentTypes.LORE);
} else {
List<Object> loreTags = new ArrayList<>();
for (String json : lore) {
loreTags.add(ChatComponent.toTag(ComponentUtils.jsonToMinecraft(json)));
List<Tag> loreTags = new ArrayList<>();
for (Component component : lore) {
loreTags.add(NBTComponentSerializer.nbt().serialize(component));
}
item.setNBTComponent(ComponentTypes.LORE, TagList.newTag(loreTags));
item.setSparrowNBTComponent(ComponentTypes.LORE, new ListTag(loreTags));
}
}
@Override
protected void loreJson(ComponentItemWrapper item, List<String> lore) {
if (lore == null || lore.isEmpty()) {
item.resetComponent(ComponentTypes.LORE);
} else {
List<Tag> loreTags = new ArrayList<>();
for (String json : lore) {
loreTags.add(NBTComponentSerializer.nbt().serialize(AdventureHelper.jsonToComponent(json)));
}
item.setSparrowNBTComponent(ComponentTypes.LORE, new ListTag(loreTags));
}
}
@@ -86,7 +119,7 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 {
if (!item.hasComponent(ComponentTypes.JUKEBOX_PLAYABLE)) return Optional.empty();
String song = (String) ComponentType.encodeJava(
ComponentTypes.JUKEBOX_PLAYABLE,
item.getComponent(ComponentTypes.JUKEBOX_PLAYABLE)).orElse(null);
item.getComponentExact(ComponentTypes.JUKEBOX_PLAYABLE)).orElse(null);
if (song == null) return Optional.empty();
return Optional.of(new JukeboxPlayable(song, true));
}

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.google.gson.JsonElement;
import com.saicone.rtag.RtagItem;
import com.saicone.rtag.item.ItemObject;
import com.saicone.rtag.tag.TagBase;
@@ -12,6 +13,7 @@ import net.momirealms.craftengine.core.item.modifier.IdModifier;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.SkullUtils;
import net.momirealms.sparrow.nbt.Tag;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.inventory.ItemFlag;
@@ -31,6 +33,21 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
return new LegacyItemWrapper(new RtagItem(item), item.getAmount());
}
@Override
protected Object getJavaComponent(LegacyItemWrapper item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected JsonElement getJsonComponent(LegacyItemWrapper item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected Tag getNBTComponent(LegacyItemWrapper item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void setTag(LegacyItemWrapper item, Object value, Object... path) {
item.set(value, path);
@@ -64,7 +81,7 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
}
@Override
protected void customName(LegacyItemWrapper item, String json) {
protected void customNameJson(LegacyItemWrapper item, String json) {
if (json != null) {
item.set(json, "display", "Name");
} else {
@@ -73,19 +90,19 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
}
@Override
protected Optional<String> customName(LegacyItemWrapper item) {
protected Optional<String> customNameJson(LegacyItemWrapper item) {
if (!item.hasTag("display", "Name")) return Optional.empty();
return Optional.of(item.get("display", "Name"));
}
@Override
protected void itemName(LegacyItemWrapper item, String json) {
customName(item, json);
protected void itemNameJson(LegacyItemWrapper item, String json) {
customNameJson(item, json);
}
@Override
protected Optional<String> itemName(LegacyItemWrapper item) {
return customName(item);
protected Optional<String> itemNameJson(LegacyItemWrapper item) {
return customNameJson(item);
}
@Override
@@ -117,13 +134,13 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
}
@Override
protected Optional<List<String>> lore(LegacyItemWrapper item) {
protected Optional<List<String>> loreJson(LegacyItemWrapper item) {
if (!item.hasTag("display", "Lore")) return Optional.empty();
return Optional.of(item.get("display", "Lore"));
}
@Override
protected void lore(LegacyItemWrapper item, List<String> lore) {
protected void loreJson(LegacyItemWrapper item, List<String> lore) {
if (lore == null || lore.isEmpty()) {
item.remove("display", "Lore");
} else {
@@ -168,8 +185,8 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
}
@Override
protected Optional<Integer> maxDamage(LegacyItemWrapper item) {
return Optional.of((int) item.getItem().getType().getMaxDurability());
protected int maxDamage(LegacyItemWrapper item) {
return item.getItem().getType().getMaxDurability();
}
@Override

View File

@@ -512,7 +512,7 @@ public class RecipeEventListener implements Listener {
Item<ItemStack> wrappedFirst = BukkitItemManager.instance().wrap(first.clone());
int maxDamage = wrappedFirst.maxDamage().orElse(0);
int maxDamage = wrappedFirst.maxDamage();
int damage = wrappedFirst.damage().orElse(0);
// not a repairable item
if (damage == 0 || maxDamage == 0) return;
@@ -577,8 +577,8 @@ public class RecipeEventListener implements Listener {
if (renameText != null && !renameText.isBlank()) {
try {
if (!renameText.equals(Reflections.method$Component$getString.invoke(ComponentUtils.jsonToMinecraft(wrappedFirst.hoverName().orElse(AdventureHelper.EMPTY_COMPONENT))))) {
wrappedFirst.customName(AdventureHelper.componentToJson(Component.text(renameText)));
if (!renameText.equals(Reflections.method$Component$getString.invoke(ComponentUtils.jsonToMinecraft(wrappedFirst.hoverNameJson().orElse(AdventureHelper.EMPTY_COMPONENT))))) {
wrappedFirst.customNameJson(AdventureHelper.componentToJson(Component.text(renameText)));
repairCost += 1;
} else if (repairCost == 0) {
hasResult = false;
@@ -588,10 +588,10 @@ public class RecipeEventListener implements Listener {
}
} else if (VersionHelper.isOrAbove1_20_5() && wrappedFirst.hasComponent(ComponentTypes.CUSTOM_NAME)) {
repairCost += 1;
wrappedFirst.customName(null);
wrappedFirst.customNameJson(null);
} else if (!VersionHelper.isOrAbove1_20_5() && wrappedFirst.hasTag("display", "Name")) {
repairCost += 1;
wrappedFirst.customName(null);
wrappedFirst.customNameJson(null);
}
int finalCost = repairCost + repairPenalty;
@@ -665,7 +665,7 @@ public class RecipeEventListener implements Listener {
}
if (renameText != null && !renameText.isBlank()) {
try {
if (!renameText.equals(Reflections.method$Component$getString.invoke(ComponentUtils.jsonToMinecraft(wrappedFirst.hoverName().orElse(AdventureHelper.EMPTY_COMPONENT))))) {
if (!renameText.equals(Reflections.method$Component$getString.invoke(ComponentUtils.jsonToMinecraft(wrappedFirst.hoverNameJson().orElse(AdventureHelper.EMPTY_COMPONENT))))) {
event.setResult(null);
}
} catch (Exception e) {
@@ -721,7 +721,7 @@ public class RecipeEventListener implements Listener {
}
int totalDamage = right.damage().orElse(0) + left.damage().orElse(0);
int totalMaxDamage = left.maxDamage().get() + right.maxDamage().get();
int totalMaxDamage = left.maxDamage() + right.maxDamage();
// should be impossible, but take care
if (totalDamage >= totalMaxDamage) {
inventory.setResult(null);
@@ -750,7 +750,7 @@ public class RecipeEventListener implements Listener {
Item<ItemStack> newItem = customItem.buildItem(ItemBuildContext.of(plugin.adapt(player)));
int remainingDurability = totalMaxDamage - totalDamage;
int newItemDamage = Math.max(0, newItem.maxDamage().get() - remainingDurability);
int newItemDamage = Math.max(0, newItem.maxDamage() - remainingDurability);
newItem.damage(newItemDamage);
inventory.setResult(newItem.load());
} else if (Reflections.clazz$ArmorDyeRecipe.isInstance(mcRecipe)) {

View File

@@ -1,7 +1,6 @@
package net.momirealms.craftengine.bukkit.plugin.network.id;
import net.momirealms.craftengine.bukkit.plugin.network.PacketIds;
import net.momirealms.craftengine.bukkit.util.Reflections;
public class PacketIds1_20_5 implements PacketIds {

View File

@@ -3,6 +3,8 @@ package net.momirealms.craftengine.bukkit.util;
import com.google.common.collect.ImmutableList;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.JsonOps;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
@@ -14,6 +16,8 @@ import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.core.util.ReflectionUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.sparrow.nbt.Tag;
import net.momirealms.sparrow.nbt.codec.NBTOps;
import org.bukkit.NamespacedKey;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
@@ -6855,4 +6859,53 @@ public class Reflections {
"network.protocol.game.ServerboundContainerClickPacket"
)
);
public static final Class<?> clazz$RegistryOps = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"resources.RegistryOps",
"resources.RegistryOps"
)
);
public static final Class<?> clazz$JavaOps = requireNonNull(
ReflectionUtils.getClazz("com.mojang.serialization.JavaOps")
);
public static final Class<?> clazz$NbtOps = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"nbt.DynamicOpsNBT",
"nbt.NbtOps"
)
);
public static final Method method$RegistryOps$create = requireNonNull(
ReflectionUtils.getStaticMethod(
clazz$RegistryOps, clazz$RegistryOps, DynamicOps.class, clazz$HolderLookup$Provider
)
);
public static final DynamicOps<Object> instance$NBT_OPS;
public static final DynamicOps<Tag> instance$SPARROW_NBT_OPS;
public static final DynamicOps<Object> instance$JAVA_OPS;
public static final DynamicOps<JsonElement> instance$JSON_OPS;
static {
try {
Object nbtOps = ReflectionUtils.getDeclaredField(clazz$NbtOps, clazz$NbtOps, 0).get(null);
instance$NBT_OPS = (DynamicOps<Object>) method$RegistryOps$create.invoke(null, nbtOps, instance$MinecraftRegistry);
Object javaOps = ReflectionUtils.getDeclaredField(clazz$JavaOps, clazz$JavaOps, 0).get(null);
instance$JAVA_OPS = (DynamicOps<Object>) method$RegistryOps$create.invoke(null, javaOps, instance$MinecraftRegistry);
instance$JSON_OPS = (DynamicOps<JsonElement>) method$RegistryOps$create.invoke(null, JsonOps.INSTANCE, instance$MinecraftRegistry);
instance$SPARROW_NBT_OPS = (DynamicOps<Tag>) method$RegistryOps$create.invoke(null, NBTOps.INSTANCE, instance$MinecraftRegistry);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
public static final Class<?> clazz$Tag = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"nbt.NBTBase",
"nbt.Tag"
)
);
}