Move basic meta reading

This commit is contained in:
themode 2021-12-19 21:52:10 +01:00 committed by TheMode
parent bb5fe8cf70
commit d31b219294
2 changed files with 93 additions and 114 deletions

View File

@ -2,7 +2,10 @@ package net.minestom.server.item;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.attribute.AttributeOperation;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.attribute.AttributeSlot;
import net.minestom.server.item.attribute.ItemAttribute;
import net.minestom.server.tag.Tag;
import net.minestom.server.tag.TagWritable;
@ -165,7 +168,7 @@ public abstract class ItemMetaBuilder implements TagWritable {
@Contract("_ -> this")
public @NotNull ItemMetaBuilder canDestroy(@NotNull Set<@NotNull Block> blocks) {
this.canDestroy = new HashSet<>(blocks);
handleCollection(canPlaceOn, "CanPlaceOn", () -> NBT.List(
handleCollection(canDestroy, "CanDestroy", () -> NBT.List(
NBTType.TAG_String,
canDestroy.stream()
.map(block -> new NBTString(block.name()))
@ -259,10 +262,96 @@ public abstract class ItemMetaBuilder implements TagWritable {
public static @NotNull ItemMetaBuilder fromNBT(@NotNull ItemMetaBuilder src, @NotNull NBTCompound nbtCompound) {
ItemMetaBuilder dest = src.getSupplier().get();
dest.nbt = nbtCompound.toMutableCompound();
NBTUtils.loadDataIntoMeta(dest, nbtCompound);
appendDefaultMeta(dest, nbtCompound);
return dest;
}
private static void appendDefaultMeta(@NotNull ItemMetaBuilder metaBuilder,
@NotNull NBTCompound nbt) {
if (nbt.get("Damage") instanceof NBTInt damage) metaBuilder.damage = damage.getValue();
if (nbt.get("Unbreakable") instanceof NBTByte unbreakable) metaBuilder.unbreakable = unbreakable.asBoolean();
if (nbt.get("HideFlags") instanceof NBTInt hideFlags) metaBuilder.hideFlag = hideFlags.getValue();
if (nbt.get("display") instanceof NBTCompound display) {
if (display.get("Name") instanceof NBTString rawName) {
metaBuilder.displayName = GsonComponentSerializer.gson().deserialize(rawName.getValue());
}
if (display.get("Lore") instanceof NBTList<?> loreList &&
loreList.getSubtagType() == NBTType.TAG_String) {
for (NBTString rawLore : loreList.<NBTString>asListOf()) {
metaBuilder.lore.add(GsonComponentSerializer.gson().deserialize(rawLore.getValue()));
}
}
}
// Enchantments
if (nbt.get("Enchantments") instanceof NBTList<?> nbtEnchants &&
nbtEnchants.getSubtagType() == NBTType.TAG_Compound) {
NBTUtils.loadEnchantments(nbtEnchants.asListOf(),
(enchantment, level) -> metaBuilder.enchantmentMap.put(enchantment, level));
}
// Attributes
if (nbt.get("AttributeModifiers") instanceof NBTList<?> nbtAttributes &&
nbtAttributes.getSubtagType() == NBTType.TAG_Compound) {
for (NBTCompound attributeNBT : nbtAttributes.<NBTCompound>asListOf()) {
final UUID uuid;
{
final int[] uuidArray = attributeNBT.getIntArray("UUID").copyArray();
uuid = Utils.intArrayToUuid(uuidArray);
}
final double value = attributeNBT.getAsDouble("Amount");
final String slot = attributeNBT.containsKey("Slot") ? attributeNBT.getString("Slot") : "MAINHAND";
final String attributeName = attributeNBT.getString("AttributeName");
final int operation = attributeNBT.getAsInt("Operation");
final String name = attributeNBT.getString("Name");
final Attribute attribute = Attribute.fromKey(attributeName);
// Wrong attribute name, stop here
if (attribute == null)
break;
final AttributeOperation attributeOperation = AttributeOperation.fromId(operation);
// Wrong attribute operation, stop here
if (attributeOperation == null) {
break;
}
// Find slot, default to the main hand if the nbt tag is invalid
AttributeSlot attributeSlot;
try {
attributeSlot = AttributeSlot.valueOf(slot.toUpperCase());
} catch (IllegalArgumentException e) {
attributeSlot = AttributeSlot.MAINHAND;
}
// Add attribute
final ItemAttribute itemAttribute =
new ItemAttribute(uuid, name, attribute, attributeOperation, value, attributeSlot);
metaBuilder.attributes.add(itemAttribute);
}
}
// Custom model data
if (nbt.get("CustomModelData") instanceof NBTInt customModelData) {
metaBuilder.customModelData = customModelData.getValue();
}
// Meta specific fields
metaBuilder.read(nbt);
// CanPlaceOn
if (nbt.get("CanPlaceOn") instanceof NBTList<?> canPlaceOn &&
canPlaceOn.getSubtagType() == NBTType.TAG_String) {
for (NBTString blockNamespace : canPlaceOn.<NBTString>asListOf()) {
Block block = Block.fromNamespaceId(blockNamespace.getValue());
metaBuilder.canPlaceOn.add(block);
}
}
// CanDestroy
if (nbt.get("CanDestroy") instanceof NBTList<?> canDestroy &&
canDestroy.getSubtagType() == NBTType.TAG_String) {
for (NBTString blockNamespace : canDestroy.<NBTString>asListOf()) {
Block block = Block.fromNamespaceId(blockNamespace.getValue());
metaBuilder.canDestroy.add(block);
}
}
}
public interface Provider<T extends ItemMetaBuilder> {
}
}

View File

@ -1,20 +1,12 @@
package net.minestom.server.utils;
import net.kyori.adventure.nbt.api.BinaryTagHolder;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.util.Codec;
import net.minestom.server.adventure.MinestomAdventure;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.attribute.AttributeOperation;
import net.minestom.server.instance.block.Block;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.item.Enchantment;
import net.minestom.server.item.ItemMetaBuilder;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.item.attribute.AttributeSlot;
import net.minestom.server.item.attribute.ItemAttribute;
import net.minestom.server.utils.binary.BinaryReader;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@ -24,7 +16,8 @@ import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.List;
import java.util.Map;
// for lack of a better name
public final class NBTUtils {
@ -125,109 +118,6 @@ public final class NBTUtils {
return ItemStack.fromNBT(material, nbtCompound, count);
}
public static void loadDataIntoMeta(@NotNull ItemMetaBuilder metaBuilder, @NotNull NBTCompound nbt) {
if (nbt.get("Damage") instanceof NBTInt damage) metaBuilder.damage(damage.getValue());
if (nbt.get("Unbreakable") instanceof NBTByte unbreakable) metaBuilder.unbreakable(unbreakable.asBoolean());
if (nbt.get("HideFlags") instanceof NBTInt hideFlags) metaBuilder.hideFlag(hideFlags.getValue());
if (nbt.get("display") instanceof NBTCompound display) {
if (display.get("Name") instanceof NBTString rawName) {
final Component displayName = GsonComponentSerializer.gson().deserialize(rawName.getValue());
metaBuilder.displayName(displayName);
}
if (display.get("Lore") instanceof NBTList<?> loreList &&
loreList.getSubtagType() == NBTType.TAG_String) {
List<Component> lore = new ArrayList<>();
for (NBTString s : loreList.<NBTString>asListOf()) {
final String rawLore = s.getValue();
lore.add(GsonComponentSerializer.gson().deserialize(rawLore));
}
metaBuilder.lore(lore);
}
}
// Enchantments
if (nbt.get("Enchantments") instanceof NBTList<?> nbtEnchants &&
nbtEnchants.getSubtagType() == NBTType.TAG_Compound) {
loadEnchantments(nbtEnchants.asListOf(), metaBuilder::enchantment);
}
// Attributes
if (nbt.get("AttributeModifiers") instanceof NBTList<?> nbtAttributes &&
nbtAttributes.getSubtagType() == NBTType.TAG_Compound) {
List<ItemAttribute> attributes = new ArrayList<>();
for (NBTCompound attributeNBT : nbtAttributes.<NBTCompound>asListOf()) {
final UUID uuid;
{
final int[] uuidArray = attributeNBT.getIntArray("UUID").copyArray();
uuid = Utils.intArrayToUuid(uuidArray);
}
final double value = attributeNBT.getAsDouble("Amount");
final String slot = attributeNBT.containsKey("Slot") ? attributeNBT.getString("Slot") : "MAINHAND";
final String attributeName = attributeNBT.getString("AttributeName");
final int operation = attributeNBT.getAsInt("Operation");
final String name = attributeNBT.getString("Name");
final Attribute attribute = Attribute.fromKey(attributeName);
// Wrong attribute name, stop here
if (attribute == null)
break;
final AttributeOperation attributeOperation = AttributeOperation.fromId(operation);
// Wrong attribute operation, stop here
if (attributeOperation == null) {
break;
}
// Find slot, default to the main hand if the nbt tag is invalid
AttributeSlot attributeSlot;
try {
attributeSlot = AttributeSlot.valueOf(slot.toUpperCase());
} catch (IllegalArgumentException e) {
attributeSlot = AttributeSlot.MAINHAND;
}
// Add attribute
final ItemAttribute itemAttribute =
new ItemAttribute(uuid, name, attribute, attributeOperation, value, attributeSlot);
attributes.add(itemAttribute);
}
metaBuilder.attributes(attributes);
}
// Custom model data
if (nbt.get("CustomModelData") instanceof NBTInt customModelData) {
metaBuilder.customModelData(customModelData.getValue());
}
// Meta specific fields
metaBuilder.read(nbt);
// CanPlaceOn
{
if (nbt.containsKey("CanPlaceOn")) {
NBTList<NBTString> canPlaceOn = nbt.getList("CanPlaceOn");
Set<Block> blocks = new HashSet<>();
for (NBTString blockNamespace : canPlaceOn) {
Block block = Block.fromNamespaceId(blockNamespace.getValue());
blocks.add(block);
}
metaBuilder.canPlaceOn(blocks);
}
}
// CanDestroy
{
if (nbt.containsKey("CanDestroy")) {
NBTList<NBTString> canDestroy = nbt.getList("CanDestroy");
Set<Block> blocks = new HashSet<>();
for (NBTString blockNamespace : canDestroy) {
Block block = Block.fromNamespaceId(blockNamespace.getValue());
blocks.add(block);
}
metaBuilder.canDestroy(blocks);
}
}
}
public static void loadEnchantments(NBTList<NBTCompound> enchantments, EnchantmentSetter setter) {
for (NBTCompound enchantment : enchantments) {
final short level = enchantment.getAsShort("lvl");