mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-25 11:35:18 +01:00
Add remaining data backup handling
This commit is contained in:
parent
510747a7cd
commit
7b28683b6a
@ -32,30 +32,30 @@ public final class BannerPattern {
|
||||
@Override
|
||||
public BannerPattern readDirect(final ByteBuf buffer) throws Exception {
|
||||
final String assetId = Type.STRING.read(buffer);
|
||||
final String tanslationKey = Type.STRING.read(buffer);
|
||||
return new BannerPattern(assetId, tanslationKey);
|
||||
final String translationKey = Type.STRING.read(buffer);
|
||||
return new BannerPattern(assetId, translationKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDirect(final ByteBuf buffer, final BannerPattern value) throws Exception {
|
||||
Type.STRING.write(buffer, value.assetId);
|
||||
Type.STRING.write(buffer, value.tanslationKey);
|
||||
Type.STRING.write(buffer, value.translationKey);
|
||||
}
|
||||
};
|
||||
|
||||
private final String assetId;
|
||||
private final String tanslationKey;
|
||||
private final String translationKey;
|
||||
|
||||
public BannerPattern(final String assetId, final String tanslationKey) {
|
||||
public BannerPattern(final String assetId, final String translationKey) {
|
||||
this.assetId = assetId;
|
||||
this.tanslationKey = tanslationKey;
|
||||
this.translationKey = translationKey;
|
||||
}
|
||||
|
||||
public String assetId() {
|
||||
return assetId;
|
||||
}
|
||||
|
||||
public String tanslationKey() {
|
||||
return tanslationKey;
|
||||
public String translationKey() {
|
||||
return translationKey;
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import com.viaversion.viaversion.api.minecraft.GlobalPosition;
|
||||
import com.viaversion.viaversion.api.minecraft.Holder;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.Particle;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
@ -45,6 +46,7 @@ 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.AttributeModifiers;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BannerPattern;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BannerPatternLayer;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Bee;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BlockPredicate;
|
||||
@ -55,6 +57,9 @@ import com.viaversion.viaversion.api.minecraft.item.data.FilterableComponent;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FilterableString;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Fireworks;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ModifierData;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
|
||||
@ -63,6 +68,8 @@ import com.viaversion.viaversion.api.minecraft.item.data.PotionEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffectData;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.StatePropertyMatcher;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ToolProperties;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ToolRule;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Unbreakable;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
@ -498,6 +505,16 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
}
|
||||
|
||||
private void restoreFromBackupTag(final CompoundTag backupTag, final StructuredDataContainer data) {
|
||||
final CompoundTag instrument = backupTag.getCompoundTag("instrument");
|
||||
if (instrument != null) {
|
||||
restoreInstrumentFromBackup(instrument, data);
|
||||
}
|
||||
|
||||
final IntArrayTag potDecorationsTag = backupTag.getIntArrayTag("pot_decorations");
|
||||
if (potDecorationsTag != null && potDecorationsTag.getValue().length == 4) {
|
||||
data.set(StructuredDataKey.POT_DECORATIONS, new PotDecorations(potDecorationsTag.getValue()));
|
||||
}
|
||||
|
||||
final ByteTag enchantmentGlintOverride = backupTag.getByteTag("enchantment_glint_override");
|
||||
if (enchantmentGlintOverride != null) {
|
||||
data.set(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, enchantmentGlintOverride.asBoolean());
|
||||
@ -527,14 +544,128 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
data.set(StructuredDataKey.RARITY, rarity.asInt());
|
||||
}
|
||||
|
||||
final CompoundTag food = backupTag.getCompoundTag("food");
|
||||
if (food != null) {
|
||||
restoreFoodFromBackup(food, data);
|
||||
}
|
||||
|
||||
if (backupTag.contains("fire_resistant")) {
|
||||
data.set(StructuredDataKey.FIRE_RESISTANT);
|
||||
}
|
||||
|
||||
final CompoundTag tool = backupTag.getCompoundTag("tool");
|
||||
if (tool != null) {
|
||||
restoreToolFromBackup(tool, data);
|
||||
}
|
||||
|
||||
final IntTag ominousBottleAmplifier = backupTag.getIntTag("ominous_bottle_amplifier");
|
||||
if (ominousBottleAmplifier != null) {
|
||||
data.set(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER, clamp(ominousBottleAmplifier.asInt(), 0, 4));
|
||||
}
|
||||
|
||||
final ListTag<CompoundTag> bannerPatterns = backupTag.getListTag("banner_patterns", CompoundTag.class);
|
||||
if (bannerPatterns != null) {
|
||||
restoreBannerPatternsFromBackup(bannerPatterns, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreInstrumentFromBackup(final CompoundTag instrument, final StructuredDataContainer data) {
|
||||
final int useDuration = instrument.getInt("use_duration");
|
||||
final float range = instrument.getFloat("range");
|
||||
|
||||
Holder<SoundEvent> soundEvent;
|
||||
final Tag soundEventTag = instrument.get("sound_event");
|
||||
if (soundEventTag instanceof IntTag) {
|
||||
soundEvent = Holder.of(((IntTag) soundEventTag).asInt());
|
||||
} else if (soundEventTag instanceof CompoundTag) {
|
||||
final CompoundTag soundEventCompound = (CompoundTag) soundEventTag;
|
||||
final StringTag identifier = soundEventCompound.getStringTag("identifier");
|
||||
if (identifier == null) {
|
||||
return; // Nothing we can do about
|
||||
}
|
||||
soundEvent = Holder.of(new SoundEvent(
|
||||
identifier.getValue(),
|
||||
soundEventCompound.contains("fixed_range") ?
|
||||
soundEventCompound.getFloat("fixed_range") : null
|
||||
));
|
||||
} else {
|
||||
return; // Nothing we can do about
|
||||
}
|
||||
data.set(StructuredDataKey.INSTRUMENT, Holder.of(new Instrument(soundEvent, useDuration, range)));
|
||||
}
|
||||
|
||||
private void restoreFoodFromBackup(final CompoundTag food, final StructuredDataContainer data) {
|
||||
final int nutrition = food.getInt("nutrition");
|
||||
final float saturation = food.getFloat("saturation");
|
||||
final boolean canAlwaysEat = food.getBoolean("can_always_eat");
|
||||
final float eatSeconds = food.getFloat("eat_seconds");
|
||||
|
||||
final ListTag<CompoundTag> possibleEffectsTag = food.getListTag("possible_effects", CompoundTag.class);
|
||||
if (possibleEffectsTag == null) {
|
||||
return;
|
||||
}
|
||||
final List<FoodEffect> possibleEffects = new ArrayList<>();
|
||||
for (final CompoundTag effect : possibleEffectsTag) {
|
||||
final CompoundTag potionEffectTag = effect.getCompoundTag("effect");
|
||||
if (potionEffectTag == null) {
|
||||
continue; // Nothing we can do about
|
||||
}
|
||||
possibleEffects.add(new FoodEffect(
|
||||
new PotionEffect(
|
||||
potionEffectTag.getInt("effect"),
|
||||
readPotionEffectData(potionEffectTag)
|
||||
),
|
||||
effect.getFloat("probability")
|
||||
));
|
||||
}
|
||||
data.set(StructuredDataKey.FOOD, new FoodProperties(nutrition, saturation, canAlwaysEat, eatSeconds, possibleEffects.toArray(new FoodEffect[0])));
|
||||
}
|
||||
|
||||
private void restoreToolFromBackup(final CompoundTag tool, final StructuredDataContainer data) {
|
||||
final ListTag<CompoundTag> rulesTag = tool.getListTag("rules", CompoundTag.class);
|
||||
if (rulesTag == null) {
|
||||
return;
|
||||
}
|
||||
final List<ToolRule> rules = new ArrayList<>();
|
||||
for (final CompoundTag tag : rulesTag) {
|
||||
HolderSet blocks = null;
|
||||
if (tag.get("blocks") instanceof StringTag) {
|
||||
blocks = HolderSet.of(tag.getString("blocks"));
|
||||
} else {
|
||||
final IntArrayTag blockIds = tag.getIntArrayTag("blocks");
|
||||
if (blockIds != null) {
|
||||
blocks = HolderSet.of(blockIds.getValue());
|
||||
}
|
||||
}
|
||||
if (blocks == null) {
|
||||
continue; // Nothing we can do about
|
||||
}
|
||||
rules.add(new ToolRule(
|
||||
blocks,
|
||||
tag.contains("speed") ? tag.getFloat("speed") : null,
|
||||
tag.contains("correct_for_drops") ? tag.getBoolean("correct_for_drops") : null
|
||||
));
|
||||
}
|
||||
data.set(StructuredDataKey.TOOL, new ToolProperties(
|
||||
rules.toArray(new ToolRule[0]),
|
||||
tool.getFloat("default_mining_speed"),
|
||||
tool.getInt("damage_per_block")
|
||||
));
|
||||
}
|
||||
|
||||
private void restoreBannerPatternsFromBackup(final ListTag<CompoundTag> bannerPatterns, final StructuredDataContainer data) {
|
||||
final List<BannerPatternLayer> patternLayer = new ArrayList<>();
|
||||
for (final CompoundTag tag : bannerPatterns) {
|
||||
final CompoundTag patternTag = tag.getCompoundTag("pattern");
|
||||
if (patternTag == null) {
|
||||
continue; // Nothing we can do about
|
||||
}
|
||||
final String assetId = patternTag.getString("asset_id");
|
||||
final String translationKey = patternTag.getString("translation_key");
|
||||
final int dyeColor = tag.getInt("dye_color");
|
||||
patternLayer.add(new BannerPatternLayer(Holder.of(new BannerPattern(assetId, translationKey)), dyeColor));
|
||||
}
|
||||
data.set(StructuredDataKey.BANNER_PATTERNS, patternLayer.toArray(new BannerPatternLayer[0]));
|
||||
}
|
||||
|
||||
private int unmappedItemId(final String name) {
|
||||
@ -706,7 +837,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
final Tag materialTag = trimTag.get("material");
|
||||
final Holder<ArmorTrimMaterial> materialHolder;
|
||||
if (materialTag instanceof StringTag) {
|
||||
// Would technically have to be stored and retreived from registry data, but that'd mean a lot of work
|
||||
// Would technically have to be stored and retrieved from registry data, but that'd mean a lot of work
|
||||
final int id = TrimMaterials1_20_3.keyToId(((StringTag) materialTag).getValue());
|
||||
if (id == -1) {
|
||||
return;
|
||||
@ -720,7 +851,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
return;
|
||||
}
|
||||
|
||||
final int ingredientId = toMappedItemId(ingredientTag.getValue());
|
||||
final int ingredientId = StructuredDataConverter.getBackupItemId(materialCompoundTag, toMappedItemId(ingredientTag.getValue()));
|
||||
if (ingredientId == -1) {
|
||||
return;
|
||||
}
|
||||
@ -755,7 +886,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
final Tag patternTag = trimTag.get("pattern");
|
||||
final Holder<ArmorTrimPattern> patternHolder;
|
||||
if (patternTag instanceof StringTag) {
|
||||
// Would technically have to be stored and retreived from registry data, but that'd mean a lot of work
|
||||
// Would technically have to be stored and retrieved from registry data, but that'd mean a lot of work
|
||||
final int id = TrimPatterns1_20_3.keyToId(((StringTag) patternTag).getValue());
|
||||
if (id == -1) {
|
||||
return;
|
||||
@ -769,7 +900,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
return;
|
||||
}
|
||||
|
||||
final int templateItemId = toMappedItemId(templateItem);
|
||||
final int templateItemId = StructuredDataConverter.getBackupItemId(patternCompoundTag, toMappedItemId(templateItem));
|
||||
if (templateItemId == -1) {
|
||||
return;
|
||||
}
|
||||
@ -954,7 +1085,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
return null;
|
||||
}
|
||||
|
||||
final int itemId = unmappedItemId(id);
|
||||
final int itemId = StructuredDataConverter.getBackupItemId(item, unmappedItemId(id));
|
||||
if (itemId == -1) {
|
||||
return null;
|
||||
}
|
||||
|
@ -20,12 +20,14 @@ 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.IntTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.viaversion.api.minecraft.GameProfile;
|
||||
import com.viaversion.viaversion.api.minecraft.HolderSet;
|
||||
import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
@ -33,6 +35,7 @@ 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.BannerPattern;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BannerPatternLayer;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Bee;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.BlockPredicate;
|
||||
@ -40,10 +43,13 @@ import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FilterableComponent;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FilterableString;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.FoodEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffectData;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.StatePropertyMatcher;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.ToolRule;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.Protocol1_20_5To1_20_3;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Attributes1_20_5;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.BannerPatterns1_20_5;
|
||||
@ -58,6 +64,7 @@ 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.Arrays;
|
||||
import java.util.Map;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
@ -72,13 +79,13 @@ public final class StructuredDataConverter {
|
||||
static final int HIDE_DYE_COLOR = 1 << 6;
|
||||
static final int HIDE_ARMOR_TRIM = 1 << 7;
|
||||
|
||||
// Can't do nicely
|
||||
private static final String BACKUP_TAG_KEY = "VV|DataComponents";
|
||||
private static final String ITEM_TAG_KEY = "VV|id";
|
||||
|
||||
private final Map<StructuredDataKey<?>, DataConverter<?>> rewriters = new Reference2ObjectOpenHashMap<>();
|
||||
private final boolean backupInconvertibleData;
|
||||
|
||||
public StructuredDataConverter(final boolean backupInconvertibleData) {
|
||||
this.backupInconvertibleData = backupInconvertibleData;
|
||||
register(StructuredDataKey.CUSTOM_DATA, (data, tag) -> {
|
||||
// Handled manually
|
||||
});
|
||||
@ -244,9 +251,26 @@ public final class StructuredDataConverter {
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.INSTRUMENT, (data, tag) -> {
|
||||
// Can't do anything with direct values
|
||||
if (!data.hasId()) {
|
||||
// Can't do anything with direct values
|
||||
// TODO Backup
|
||||
if (backupInconvertibleData) {
|
||||
final CompoundTag backupTag = new CompoundTag();
|
||||
final Instrument instrument = data.value();
|
||||
if (instrument.soundEvent().hasId()) {
|
||||
backupTag.putInt("sound_event", instrument.soundEvent().id());
|
||||
} else {
|
||||
final CompoundTag soundEventTag = new CompoundTag();
|
||||
final SoundEvent soundEvent = instrument.soundEvent().value();
|
||||
soundEventTag.putString("identifier", soundEvent.identifier());
|
||||
if (soundEvent.fixedRange() != null) {
|
||||
soundEventTag.putFloat("fixed_range", soundEvent.fixedRange());
|
||||
}
|
||||
backupTag.put("sound_event", soundEventTag);
|
||||
}
|
||||
backupTag.putInt("use_duration", instrument.useDuration());
|
||||
backupTag.putFloat("range", instrument.range());
|
||||
getBackupTag(tag).put("instrument", backupTag);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -269,9 +293,23 @@ public final class StructuredDataConverter {
|
||||
register(StructuredDataKey.LOCK, (data, tag) -> getBlockEntityTag(tag).put("Lock", data));
|
||||
register(StructuredDataKey.NOTE_BLOCK_SOUND, (data, tag) -> getBlockEntityTag(tag).putString("note_block_sound", data));
|
||||
register(StructuredDataKey.POT_DECORATIONS, (data, tag) -> {
|
||||
IntArrayTag originalSherds = null;
|
||||
|
||||
final ListTag<StringTag> sherds = new ListTag<>(StringTag.class);
|
||||
for (final int id : data.itemIds()) {
|
||||
sherds.add(new StringTag(toItemName(id)));
|
||||
final String name = toMappedItemName(id);
|
||||
if (name.isEmpty()) {
|
||||
// Backup whole data if one of the sherds is inconvertible
|
||||
// Since we don't want to break the order of the sherds
|
||||
if (backupInconvertibleData && originalSherds == null) {
|
||||
originalSherds = new IntArrayTag(data.itemIds());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
sherds.add(new StringTag(name));
|
||||
}
|
||||
if (originalSherds != null) {
|
||||
getBackupTag(tag).put("pot_decorations", originalSherds);
|
||||
}
|
||||
getBlockEntityTag(tag).put("sherds", sherds);
|
||||
});
|
||||
@ -302,7 +340,7 @@ public final class StructuredDataConverter {
|
||||
});
|
||||
register(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putBoolean("enchantment_glint_override", data);
|
||||
getBackupTag(tag).putBoolean("enchantment_glint_override", data);
|
||||
}
|
||||
if (!data) {
|
||||
// There is no way to remove the glint without removing the enchantments
|
||||
@ -368,14 +406,32 @@ public final class StructuredDataConverter {
|
||||
tag.put("effects", effectsTag);
|
||||
});
|
||||
register(StructuredDataKey.BANNER_PATTERNS, (data, tag) -> {
|
||||
final ListTag<CompoundTag> originalPatterns = new ListTag<>(CompoundTag.class);
|
||||
if (backupInconvertibleData) {
|
||||
// Backup whole data if one of the patterns is inconvertible
|
||||
// Since we don't want to break the order of the patterns
|
||||
if (Arrays.stream(data).anyMatch(layer -> layer.pattern().isDirect())) {
|
||||
for (final BannerPatternLayer layer : data) {
|
||||
final CompoundTag layerTag = new CompoundTag();
|
||||
final CompoundTag patternTag = new CompoundTag();
|
||||
final BannerPattern pattern = layer.pattern().value();
|
||||
patternTag.putString("asset_id", pattern.assetId());
|
||||
patternTag.putString("translation_key", pattern.translationKey());
|
||||
layerTag.put("pattern", patternTag);
|
||||
layerTag.putInt("dye_color", layer.dyeColor());
|
||||
originalPatterns.add(layerTag);
|
||||
}
|
||||
getBackupTag(tag).put("banner_patterns", originalPatterns);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final ListTag<CompoundTag> patternsTag = new ListTag<>(CompoundTag.class);
|
||||
for (final BannerPatternLayer layer : data) {
|
||||
final String pattern = BannerPatterns1_20_5.fullIdToCompact(BannerPatterns1_20_5.idToKey(layer.pattern().id()));
|
||||
if (pattern == null) {
|
||||
// TODO Backup
|
||||
continue;
|
||||
}
|
||||
|
||||
final CompoundTag patternTag = new CompoundTag();
|
||||
patternTag.putString("Pattern", pattern);
|
||||
patternTag.putInt("Color", layer.dyeColor());
|
||||
@ -403,9 +459,9 @@ public final class StructuredDataConverter {
|
||||
final ArmorTrimMaterial material = data.material().value();
|
||||
materialTag.putString("asset_name", material.assetName());
|
||||
|
||||
final String ingredientName = toItemName(material.itemId());
|
||||
final String ingredientName = toMappedItemName(material.itemId());
|
||||
if (ingredientName.isEmpty()) {
|
||||
return;
|
||||
getBackupTag(materialTag).putInt(ITEM_TAG_KEY, material.itemId());
|
||||
}
|
||||
materialTag.putString("ingredient", ingredientName);
|
||||
materialTag.put("item_model_index", new FloatTag(material.itemModelIndex()));
|
||||
@ -429,9 +485,9 @@ public final class StructuredDataConverter {
|
||||
final ArmorTrimPattern pattern = data.pattern().value();
|
||||
|
||||
patternTag.putString("assetId", pattern.assetName());
|
||||
final String itemName = toItemName(pattern.itemId());
|
||||
final String itemName = toMappedItemName(pattern.itemId());
|
||||
if (itemName.isEmpty()) {
|
||||
return;
|
||||
getBackupTag(patternTag).putInt(ITEM_TAG_KEY, pattern.itemId());
|
||||
}
|
||||
patternTag.putString("templateItem", itemName);
|
||||
patternTag.put("description", pattern.description());
|
||||
@ -459,60 +515,102 @@ public final class StructuredDataConverter {
|
||||
// Hide everything we can hide
|
||||
putHideFlag(tag, 0xFF);
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putBoolean("hide_tooltip", true);
|
||||
getBackupTag(tag).putBoolean("hide_tooltip", true);
|
||||
}
|
||||
});
|
||||
|
||||
// New in 1.20.5
|
||||
register(StructuredDataKey.INTANGIBLE_PROJECTILE, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).put("intangible_projectile", data);
|
||||
getBackupTag(tag).put("intangible_projectile", data);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.MAX_STACK_SIZE, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putInt("max_stack_size", data);
|
||||
getBackupTag(tag).putInt("max_stack_size", data);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.MAX_DAMAGE, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putInt("max_damage", data);
|
||||
getBackupTag(tag).putInt("max_damage", data);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.RARITY, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putInt("rarity", data);
|
||||
getBackupTag(tag).putInt("rarity", data);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.FOOD, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
//createBackupTag(tag).; // TODO Backup
|
||||
final CompoundTag backupTag = new CompoundTag();
|
||||
backupTag.putInt("nutrition", data.nutrition());
|
||||
backupTag.putFloat("saturation_modifier", data.saturationModifier());
|
||||
backupTag.putBoolean("can_always_eat", data.canAlwaysEat());
|
||||
backupTag.putFloat("eat_seconds", data.eatSeconds());
|
||||
|
||||
final ListTag<CompoundTag> possibleEffectsTag = new ListTag<>(CompoundTag.class);
|
||||
for (final FoodEffect effect : data.possibleEffects()) {
|
||||
final CompoundTag effectTag = new CompoundTag();
|
||||
|
||||
final PotionEffect potionEffect = effect.effect();
|
||||
final CompoundTag potionEffectTag = new CompoundTag();
|
||||
potionEffectTag.putInt("effect", potionEffect.effect());
|
||||
potionEffectTag.put("effect_data", convertPotionEffectData(potionEffect.effectData()));
|
||||
|
||||
effectTag.putFloat("probability", effect.probability());
|
||||
effectTag.put("effect", potionEffectTag);
|
||||
possibleEffectsTag.add(effectTag);
|
||||
}
|
||||
backupTag.put("possible_effects", possibleEffectsTag);
|
||||
getBackupTag(tag).put("food", backupTag);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.FIRE_RESISTANT, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putBoolean("fire_resistant", true);
|
||||
getBackupTag(tag).putBoolean("fire_resistant", true);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.TOOL, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
//createBackupTag(tag).; // TODO Backup
|
||||
final CompoundTag backupTag = new CompoundTag();
|
||||
final ListTag<CompoundTag> rulesTag = new ListTag<>(CompoundTag.class);
|
||||
for (final ToolRule rule : data.rules()) {
|
||||
final CompoundTag ruleTag = new CompoundTag();
|
||||
final HolderSet set = rule.blocks();
|
||||
if (set.hasTagKey()) {
|
||||
ruleTag.putString("blocks", set.tagKey());
|
||||
} else {
|
||||
ruleTag.put("blocks", new IntArrayTag(set.ids()));
|
||||
}
|
||||
if (rule.speed() != null) {
|
||||
ruleTag.putFloat("speed", rule.speed());
|
||||
}
|
||||
if (rule.correctForDrops() != null) {
|
||||
ruleTag.putBoolean("correct_for_drops", rule.correctForDrops());
|
||||
}
|
||||
rulesTag.add(ruleTag);
|
||||
}
|
||||
backupTag.put("rules", rulesTag);
|
||||
backupTag.putFloat("default_mining_speed", data.defaultMiningSpeed());
|
||||
backupTag.putInt("damage_per_block", data.damagePerBlock());
|
||||
getBackupTag(tag).put("tool", backupTag);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putInt("ominous_bottle_amplifier", data);
|
||||
getBackupTag(tag).putInt("ominous_bottle_amplifier", data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String toItemName(final int id) {
|
||||
final int mappedId = Protocol1_20_5To1_20_3.MAPPINGS.getOldItemId(id);
|
||||
// TODO Backup
|
||||
return mappedId != -1 ? Protocol1_20_5To1_20_3.MAPPINGS.itemName(mappedId) : "";
|
||||
private int unmappedItemId(final int id) {
|
||||
return Protocol1_20_5To1_20_3.MAPPINGS.getOldItemId(id);
|
||||
}
|
||||
|
||||
// If multiple item components which previously were stored in BlockEntityTag are present, we need to merge them
|
||||
private String toMappedItemName(final int id) {
|
||||
final int mappedId = unmappedItemId(id);
|
||||
return mappedId != -1 ? Protocol1_20_5To1_20_3.MAPPINGS.itemName(mappedId) : "";
|
||||
}
|
||||
|
||||
private static CompoundTag getBlockEntityTag(final CompoundTag tag) {
|
||||
return getOrCreate(tag, "BlockEntityTag");
|
||||
@ -522,6 +620,11 @@ public final class StructuredDataConverter {
|
||||
return getOrCreate(tag, "display");
|
||||
}
|
||||
|
||||
private static CompoundTag getBackupTag(final CompoundTag tag) {
|
||||
return getOrCreate(tag, BACKUP_TAG_KEY);
|
||||
}
|
||||
|
||||
// If multiple item components which previously were stored in BlockEntityTag are present, we need to merge them
|
||||
private static CompoundTag getOrCreate(final CompoundTag tag, final String key) {
|
||||
CompoundTag subTag = tag.getCompoundTag(key);
|
||||
if (subTag == null) {
|
||||
@ -531,6 +634,22 @@ public final class StructuredDataConverter {
|
||||
return subTag;
|
||||
}
|
||||
|
||||
static @Nullable CompoundTag removeBackupTag(final CompoundTag tag) {
|
||||
final CompoundTag backupTag = tag.getCompoundTag(BACKUP_TAG_KEY);
|
||||
if (backupTag != null) {
|
||||
tag.remove(BACKUP_TAG_KEY);
|
||||
}
|
||||
return backupTag;
|
||||
}
|
||||
|
||||
static int getBackupItemId(final CompoundTag tag, final int unmappedId) {
|
||||
if (unmappedId != -1) {
|
||||
return unmappedId;
|
||||
}
|
||||
final IntTag itemIdTag = tag.getIntTag(ITEM_TAG_KEY);
|
||||
return itemIdTag != null ? itemIdTag.getTagId() : -1;
|
||||
}
|
||||
|
||||
private 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()) {
|
||||
@ -545,7 +664,12 @@ public final class StructuredDataConverter {
|
||||
predicatedListTag.add(serializeBlockPredicate(predicate, tagKey));
|
||||
} else {
|
||||
for (final int id : holders.ids()) {
|
||||
predicatedListTag.add(serializeBlockPredicate(predicate, toItemName(id)));
|
||||
final String name = toMappedItemName(id);
|
||||
if (name.isEmpty()) {
|
||||
// TODO HANDLE
|
||||
continue;
|
||||
}
|
||||
predicatedListTag.add(serializeBlockPredicate(predicate, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -583,11 +707,28 @@ public final class StructuredDataConverter {
|
||||
return explosionTag;
|
||||
}
|
||||
|
||||
private CompoundTag convertPotionEffectData(final PotionEffectData data) {
|
||||
final CompoundTag effectDataTag = new CompoundTag();
|
||||
effectDataTag.putInt("amplifier", data.amplifier());
|
||||
effectDataTag.putInt("duration", data.duration());
|
||||
effectDataTag.putBoolean("ambient", data.ambient());
|
||||
effectDataTag.putBoolean("show_particles", data.showParticles());
|
||||
effectDataTag.putBoolean("show_icon", data.showIcon());
|
||||
if (data.hiddenEffect() != null) {
|
||||
effectDataTag.put("hidden_effect", convertPotionEffectData(data.hiddenEffect()));
|
||||
}
|
||||
return effectDataTag;
|
||||
}
|
||||
|
||||
private 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 CompoundTag savedItem = new CompoundTag();
|
||||
savedItem.putString("id", toItemName(item.identifier()));
|
||||
final String name = toMappedItemName(item.identifier());
|
||||
savedItem.putString("id", name);
|
||||
if (name.isEmpty()) {
|
||||
savedItem.putInt(ITEM_TAG_KEY, item.identifier());
|
||||
}
|
||||
savedItem.putByte("Count", (byte) item.amount());
|
||||
|
||||
final CompoundTag itemTag = new CompoundTag();
|
||||
@ -649,18 +790,6 @@ public final class StructuredDataConverter {
|
||||
rewriters.put(key, converter);
|
||||
}
|
||||
|
||||
private static CompoundTag createBackupTag(final CompoundTag tag) {
|
||||
return getOrCreate(tag, BACKUP_TAG_KEY);
|
||||
}
|
||||
|
||||
static @Nullable CompoundTag removeBackupTag(final CompoundTag tag) {
|
||||
final CompoundTag backupTag = tag.getCompoundTag(BACKUP_TAG_KEY);
|
||||
if (backupTag != null) {
|
||||
tag.remove(BACKUP_TAG_KEY);
|
||||
}
|
||||
return backupTag;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface DataConverter<T> {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user