More structured data handling

This commit is contained in:
FlorianMichael 2024-03-14 17:19:16 +01:00 committed by Nassim Jahnke
parent 936dcafc11
commit 57a589924d
No known key found for this signature in database
GPG Key ID: EF6771C01F6EF02F
2 changed files with 158 additions and 33 deletions

View File

@ -20,6 +20,7 @@ package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.rewriter;
import com.github.steveice10.opennbt.stringified.SNBT;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.NumberTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
@ -96,6 +97,8 @@ import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.logging.Level;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<ClientboundPacket1_20_3, ServerboundPacket1_20_5, Protocol1_20_5To1_20_3> {
@ -418,7 +421,15 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
data.set(StructuredDataKey.CAN_BREAK, updateBlockPredicates(canDestroyTag, (hideFlagsValue & StructuredDataConverter.HIDE_CAN_DESTROY) == 0));
}
// TODO MAP_POST_PROCESSING
final IntTag mapScaleDirectionTag = tag.getIntTag("map_scale_direction");
if (mapScaleDirectionTag != null) {
data.set(StructuredDataKey.MAP_POST_PROCESSING, 1); // Scale
} else {
final NumberTag mapToLockTag = tag.getNumberTag("map_to_lock");
if (mapToLockTag != null) {
data.set(StructuredDataKey.MAP_POST_PROCESSING, 0); // Lock
}
}
data.set(StructuredDataKey.CUSTOM_DATA, tag);
return item;
@ -526,6 +537,21 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
data.set(StructuredDataKey.ATTRIBUTE_MODIFIERS, new AttributeModifiers(modifiers, showInTooltip));
}
private PotionEffectData readPotionEffectData(final CompoundTag tag) {
final byte amplifier = tag.getByte("amplifier");
final int duration = tag.getInt("duration");
final boolean ambient = tag.getBoolean("ambient");
final boolean showParticles = tag.getBoolean("show_particles");
final boolean showIcon = tag.getBoolean("show_icon");
PotionEffectData hiddenEffect = null;
final CompoundTag hiddenEffectTag = tag.getCompoundTag("hidden_effect");
if (hiddenEffectTag != null) {
hiddenEffect = readPotionEffectData(hiddenEffectTag);
}
return new PotionEffectData(amplifier, duration, ambient, showParticles, showIcon, hiddenEffect);
}
private void updatePotionTags(final StructuredDataContainer data, final CompoundTag tag) {
final String potion = tag.getString("Potion");
Integer potionId = null;
@ -548,21 +574,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
if (id < 0) {
return null;
}
final byte amplifier = effectTag.getByte("amplifier");
final int duration = effectTag.getInt("duration");
final boolean ambient = effectTag.getBoolean("ambient");
final boolean showParticles = effectTag.getBoolean("show_particles");
final boolean showIcon = effectTag.getBoolean("show_icon");
final PotionEffectData effectData = new PotionEffectData(
amplifier,
duration,
ambient,
showParticles,
showIcon,
null //TODO
);
return new PotionEffect(id, effectData);
return new PotionEffect(id, readPotionEffectData(effectTag));
}).filter(Objects::nonNull).toArray(PotionEffect[]::new);
}
@ -585,13 +597,41 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
}
materialHolder = Holder.of(id);
} else if (materialTag instanceof CompoundTag) {
/*final CompoundTag materialCompoundTag = (CompoundTag) materialTag;
final CompoundTag materialCompoundTag = (CompoundTag) materialTag;
final StringTag assetNameTag = materialCompoundTag.getStringTag("asset_name");
final StringTag ingredientTag = materialCompoundTag.getStringTag("ingredient");
if (assetNameTag == null || ingredientTag == null) {
return;
}
final int ingredientId = toItemId(ingredientTag.getValue());
if (ingredientId == -1) {
return;
}
final NumberTag itemModelIndexTag = materialCompoundTag.getNumberTag("item_model_index");
final CompoundTag overrideArmorMaterialsTag = materialCompoundTag.get("override_armor_materials");
final Tag descriptionTag = materialCompoundTag.get("description");*/
return; // TODO
final Tag descriptionTag = materialCompoundTag.get("description");
final Int2ObjectMap<String> overrideArmorMaterials = new Int2ObjectOpenHashMap<>();
if (overrideArmorMaterialsTag != null) {
for (final Map.Entry<String, Tag> entry : overrideArmorMaterialsTag.entrySet()) {
if (!(entry.getValue() instanceof StringTag)) {
continue;
}
try {
final int id = Integer.parseInt(entry.getKey());
overrideArmorMaterials.put(id, ((StringTag) entry.getValue()).getValue());
} catch (NumberFormatException ignored) {
}
}
}
materialHolder = Holder.of(new ArmorTrimMaterial(
assetNameTag.getValue(),
ingredientId,
itemModelIndexTag != null ? itemModelIndexTag.asFloat() : 0,
overrideArmorMaterials,
descriptionTag
));
} else return;
final Tag patternTag = trimTag.get("pattern");
@ -603,7 +643,24 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
}
patternHolder = Holder.of(id);
} else if (patternTag instanceof CompoundTag) {
return; // TODO
final CompoundTag patternCompoundTag = (CompoundTag) patternTag;
final String assetId = patternCompoundTag.getString("assetId");
final String templateItem = patternCompoundTag.getString("templateItem");
if (assetId == null || templateItem == null) {
return;
}
final int templateItemId = toItemId(templateItem);
if (templateItemId == -1) {
return;
}
final Tag descriptionTag = patternCompoundTag.get("description");
final boolean decal = patternCompoundTag.getBoolean("decal");
patternHolder = Holder.of(new ArmorTrimPattern(
assetId,
templateItemId,
descriptionTag,
decal
));
} else return;
data.set(StructuredDataKey.TRIM, new ArmorTrim(materialHolder, patternHolder, showInTooltip));
@ -756,8 +813,8 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
data.set(dataKey, items);
}
private int toItemId(final String id) {
final int unmappedId = protocol.getMappingData().itemId(id);
private int toItemId(final String name) {
final int unmappedId = protocol.getMappingData().itemId(name);
return unmappedId != -1 ? protocol.getMappingData().getNewItemId(unmappedId) : -1;
}
@ -999,7 +1056,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
}
}
// TODO Beehive needed?
updateItemList(data, tag, "Items", StructuredDataKey.CONTAINER);
}
private void updateSkullOwnerTag(final CompoundTag tag, final CompoundTag skullOwnerTag) {

View File

@ -18,6 +18,7 @@
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.rewriter;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.FloatTag;
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
@ -28,6 +29,8 @@ import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate;
import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrimMaterial;
import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrimPattern;
import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifier;
import com.viaversion.viaversion.api.minecraft.item.data.BannerPatternLayer;
import com.viaversion.viaversion.api.minecraft.item.data.Bee;
@ -48,9 +51,11 @@ import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Enchantme
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Instruments1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.MapDecorations1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Potions1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.TrimMaterials1_20_3;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.UUIDUtil;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import java.util.Map;
@ -336,16 +341,79 @@ final class StructuredDataConverter {
patternsTag.add(patternTag);
}
});
register(StructuredDataKey.CONTAINER, (data, tag) -> convertItemList(data, tag, "Items"));
register(StructuredDataKey.CAN_PLACE_ON, (data, tag) -> convertBlockPredicates(tag, data, "CanPlaceOn", HIDE_CAN_PLACE_ON));
register(StructuredDataKey.CAN_BREAK, (data, tag) -> convertBlockPredicates(tag, data, "CanDestroy", HIDE_CAN_DESTROY));
register(StructuredDataKey.MAP_POST_PROCESSING, (data, tag) -> {
if (data == null) {
return;
}
if (data == 0) { // Lock
tag.putBoolean("map_to_lock", true);
} else if (data == 1) { // Scale
tag.putInt("map_scale_direction", 1);
}
});
register(StructuredDataKey.TRIM, (data, tag) -> {
final CompoundTag trimTag = getOrCreateTag(tag, "Trim");
if (data.material().isDirect()) {
final CompoundTag materialTag = getOrCreateTag(trimTag, "material");
final ArmorTrimMaterial material = data.material().value();
materialTag.putString("asset_name", material.assetName());
final String ingredientName = toItemName(material.itemId());
if (ingredientName.isEmpty()) {
return;
}
materialTag.putString("ingredient", ingredientName);
materialTag.put("item_model_index", new FloatTag(material.itemModelIndex()));
final CompoundTag overrideArmorMaterials = new CompoundTag();
if (!material.overrideArmorMaterials().isEmpty()) {
for (final Int2ObjectMap.Entry<String> entry : material.overrideArmorMaterials().int2ObjectEntrySet()) {
overrideArmorMaterials.put(Integer.toString(entry.getIntKey()), new StringTag(entry.getValue()));
}
materialTag.put("override_armor_materials", overrideArmorMaterials);
}
} else {
final String oldKey = TrimMaterials1_20_3.idToKey(data.material().id());
if (oldKey != null) {
trimTag.putString("material", oldKey);
}
}
if (data.pattern().isDirect()) {
final CompoundTag patternTag = getOrCreateTag(trimTag, "pattern");
final ArmorTrimPattern pattern = data.pattern().value();
patternTag.putString("assetId", pattern.assetName());
final String itemName = toItemName(pattern.itemId());
if (itemName.isEmpty()) {
return;
}
patternTag.putString("templateItem", itemName);
patternTag.put("description", pattern.description());
patternTag.putBoolean("decal", pattern.decal());
} else {
final String oldKey = TrimMaterials1_20_3.idToKey(data.pattern().id());
if (oldKey != null) {
trimTag.putString("pattern", oldKey);
}
}
if (!data.showInTooltip()) {
putHideFlag(tag, HIDE_ARMOR_TRIM);
}
});
//TODO
// StructuredDataKey<ArmorTrim> TRIM
// StructuredDataKey<BlockStateProperties> BLOCK_STATE
// StructuredDataKey<Item[]> CONTAINER
// StructuredDataKey<Unit> INTANGIBLE_PROJECTILE
}
private static String toItemName(final int id) {
final int mappedId = Protocol1_20_5To1_20_3.MAPPINGS.getOldItemId(id);
return mappedId != -1 ? Protocol1_20_5To1_20_3.MAPPINGS.itemName(mappedId) : "";
}
private static void convertBlockPredicates(final CompoundTag tag, final AdventureModePredicate data, final String key, final int hideFlag) {
final ListTag<StringTag> predicatedListTag = new ListTag<>(StringTag.class);
for (final BlockPredicate predicate : data.predicates()) {
@ -359,9 +427,7 @@ final class StructuredDataConverter {
predicatedListTag.add(serializeBlockPredicate(predicate, tagKey));
} else {
for (final int id : holders.ids()) {
final int oldId = Protocol1_20_5To1_20_3.MAPPINGS.getOldItemId(id);
final String identifier = Protocol1_20_5To1_20_3.MAPPINGS.itemName(oldId);
predicatedListTag.add(serializeBlockPredicate(predicate, identifier));
predicatedListTag.add(serializeBlockPredicate(predicate, toItemName(id)));
}
}
}
@ -390,10 +456,14 @@ final class StructuredDataConverter {
}
private static CompoundTag getBlockEntityTag(final CompoundTag tag) {
CompoundTag subTag = tag.getCompoundTag("BlockEntityTag");
return getOrCreateTag(tag, "BlockEntityTag");
}
private static CompoundTag getOrCreateTag(final CompoundTag tag, final String name) {
CompoundTag subTag = tag.getCompoundTag(name);
if (subTag == null) {
subTag = new CompoundTag();
tag.put("BlockEntityTag", subTag);
tag.put(name, subTag);
}
return subTag;
}
@ -420,10 +490,8 @@ final class StructuredDataConverter {
private static void convertItemList(final Item[] items, final CompoundTag tag, final String key) {
final ListTag<CompoundTag> itemsTag = new ListTag<>(CompoundTag.class);
for (final Item item : items) {
final int oldId = Protocol1_20_5To1_20_3.MAPPINGS.getOldItemId(item.identifier());
final CompoundTag savedItem = new CompoundTag();
savedItem.putString("id", Protocol1_20_5To1_20_3.MAPPINGS.itemName(oldId));
savedItem.putString("id", toItemName(item.identifier()));
savedItem.putByte("Count", (byte) item.amount());
final CompoundTag itemTag = new CompoundTag();