mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-12-23 00:47:39 +01:00
Back up 1.20.5 data components in VB for creative clients
This commit is contained in:
parent
c743c20334
commit
c2489c7a4c
@ -41,7 +41,7 @@ import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPac
|
||||
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.RecipeRewriter1_19_4;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.Protocol1_20_2To1_20;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPackets1_20_2;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.util.PotionEffects;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.util.PotionEffects1_20_2;
|
||||
import com.viaversion.viaversion.rewriter.BlockRewriter;
|
||||
import com.viaversion.viaversion.rewriter.ItemRewriter;
|
||||
import com.viaversion.viaversion.util.MathUtil;
|
||||
@ -383,7 +383,8 @@ public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter<Clientboun
|
||||
final CompoundTag effectTag = (CompoundTag) tag;
|
||||
final Tag idTag = effectTag.remove("Id");
|
||||
if (idTag instanceof NumberTag) {
|
||||
final String key = PotionEffects.idToKey(((NumberTag) idTag).asInt());
|
||||
// Empty effect removed
|
||||
final String key = PotionEffects1_20_2.idToKey(((NumberTag) idTag).asInt() - 1);
|
||||
if (key != null) {
|
||||
effectTag.put("id", new StringTag(key));
|
||||
}
|
||||
@ -414,8 +415,8 @@ public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter<Clientboun
|
||||
final CompoundTag effectTag = (CompoundTag) tag;
|
||||
final Tag idTag = effectTag.remove("id");
|
||||
if (idTag instanceof StringTag) {
|
||||
final int id = PotionEffects.keyToId(((StringTag) idTag).getValue());
|
||||
effectTag.put("Id", new IntTag(id));
|
||||
final int id = PotionEffects1_20_2.keyToId(((StringTag) idTag).getValue());
|
||||
effectTag.putInt("Id", id + 1); // Account for empty effect at id 0
|
||||
}
|
||||
|
||||
renameTag(effectTag, "amplifier", "Amplifier");
|
||||
@ -443,12 +444,12 @@ public final class BlockItemPacketRewriter1_20_2 extends ItemRewriter<Clientboun
|
||||
|
||||
final Tag primaryEffect = tag.remove("Primary");
|
||||
if (primaryEffect instanceof NumberTag && ((NumberTag) primaryEffect).asInt() != 0) {
|
||||
tag.put("primary_effect", new StringTag(PotionEffects.idToKeyOrLuck(((NumberTag) primaryEffect).asInt())));
|
||||
tag.put("primary_effect", new StringTag(PotionEffects1_20_2.idToKeyOrLuck(((NumberTag) primaryEffect).asInt() - 1)));
|
||||
}
|
||||
|
||||
final Tag secondaryEffect = tag.remove("Secondary");
|
||||
if (secondaryEffect instanceof NumberTag && ((NumberTag) secondaryEffect).asInt() != 0) {
|
||||
tag.put("secondary_effect", new StringTag(PotionEffects.idToKeyOrLuck(((NumberTag) secondaryEffect).asInt())));
|
||||
tag.put("secondary_effect", new StringTag(PotionEffects1_20_2.idToKeyOrLuck(((NumberTag) secondaryEffect).asInt() - 1)));
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
@ -22,11 +22,10 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class PotionEffects {
|
||||
public final class PotionEffects1_20_2 {
|
||||
|
||||
private static final Object2IntMap<String> KEY_TO_ID = new Object2IntOpenHashMap<>();
|
||||
private static final String[] POTION_EFFECTS = {
|
||||
"", // No effect
|
||||
"speed",
|
||||
"slowness",
|
||||
"haste",
|
||||
@ -63,18 +62,19 @@ public final class PotionEffects {
|
||||
};
|
||||
|
||||
static {
|
||||
for (int i = 1; i < POTION_EFFECTS.length; i++) {
|
||||
for (int i = 0; i < POTION_EFFECTS.length; i++) {
|
||||
final String effect = POTION_EFFECTS[i];
|
||||
KEY_TO_ID.put(effect, i);
|
||||
}
|
||||
KEY_TO_ID.defaultReturnValue(-1);
|
||||
}
|
||||
|
||||
public static @Nullable String idToKey(final int id) {
|
||||
return id >= 1 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : null;
|
||||
return id >= 0 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : null;
|
||||
}
|
||||
|
||||
public static String idToKeyOrLuck(final int id) {
|
||||
return id >= 1 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : "minecraft:luck";
|
||||
return id >= 0 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : "minecraft:luck";
|
||||
}
|
||||
|
||||
public static int keyToId(final String key) {
|
@ -19,7 +19,7 @@ package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
|
||||
|
||||
import com.viaversion.viaversion.util.KeyMappings;
|
||||
|
||||
public final class MapDecorations1_20_3 {
|
||||
public final class MapDecorations1_20_5 {
|
||||
|
||||
private static final KeyMappings MAP_DECORATIONS = new KeyMappings(
|
||||
"player",
|
||||
@ -55,7 +55,8 @@ public final class MapDecorations1_20_3 {
|
||||
"village_snowy",
|
||||
"village_taiga",
|
||||
"jungle_temple",
|
||||
"swamp_hut"
|
||||
"swamp_hut",
|
||||
"trial_chambers"
|
||||
);
|
||||
|
||||
public static String idToKey(final int index) {
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
|
||||
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class PotionEffects1_20_5 {
|
||||
|
||||
private static final Object2IntMap<String> KEY_TO_ID = new Object2IntOpenHashMap<>();
|
||||
private static final String[] POTION_EFFECTS = {
|
||||
"speed",
|
||||
"slowness",
|
||||
"haste",
|
||||
"mining_fatigue",
|
||||
"strength",
|
||||
"instant_health",
|
||||
"instant_damage",
|
||||
"jump_boost",
|
||||
"nausea",
|
||||
"regeneration",
|
||||
"resistance",
|
||||
"fire_resistance",
|
||||
"water_breathing",
|
||||
"invisibility",
|
||||
"blindness",
|
||||
"night_vision",
|
||||
"hunger",
|
||||
"weakness",
|
||||
"poison",
|
||||
"wither",
|
||||
"health_boost",
|
||||
"absorption",
|
||||
"saturation",
|
||||
"glowing",
|
||||
"levitation",
|
||||
"luck",
|
||||
"unluck",
|
||||
"slow_falling",
|
||||
"conduit_power",
|
||||
"dolphins_grace",
|
||||
"bad_omen",
|
||||
"hero_of_the_village",
|
||||
"darkness",
|
||||
"trial_omen",
|
||||
"raid_omen",
|
||||
"wind_charged",
|
||||
"weaving",
|
||||
"oozing",
|
||||
"infested"
|
||||
};
|
||||
|
||||
static {
|
||||
for (int i = 0; i < POTION_EFFECTS.length; i++) {
|
||||
final String effect = POTION_EFFECTS[i];
|
||||
KEY_TO_ID.put(effect, i);
|
||||
}
|
||||
KEY_TO_ID.defaultReturnValue(-1);
|
||||
}
|
||||
|
||||
public static @Nullable String idToKey(final int id) {
|
||||
return id >= 0 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : null;
|
||||
}
|
||||
|
||||
public static String idToKeyOrLuck(final int id) {
|
||||
return id >= 0 && id < POTION_EFFECTS.length ? Key.namespaced(POTION_EFFECTS[id]) : "minecraft:luck";
|
||||
}
|
||||
|
||||
public static int keyToId(final String key) {
|
||||
return KEY_TO_ID.getInt(Key.stripMinecraftNamespace(key));
|
||||
}
|
||||
}
|
@ -20,10 +20,9 @@ package com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data;
|
||||
import com.viaversion.viaversion.util.KeyMappings;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class Potions1_20_3 {
|
||||
public final class Potions1_20_5 {
|
||||
|
||||
private static final KeyMappings POTIONS = new KeyMappings(
|
||||
"empty",
|
||||
"water",
|
||||
"mundane",
|
||||
"thick",
|
||||
@ -65,7 +64,11 @@ public final class Potions1_20_3 {
|
||||
"long_weakness",
|
||||
"luck",
|
||||
"slow_falling",
|
||||
"long_slow_falling"
|
||||
"long_slow_falling",
|
||||
"wind_charged",
|
||||
"weaving",
|
||||
"oozing",
|
||||
"infested"
|
||||
);
|
||||
|
||||
public static @Nullable String idToKey(final int id) {
|
@ -18,6 +18,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.ByteTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||
@ -68,7 +69,6 @@ import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_3;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.util.PotionEffects;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPacket1_20_3;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPackets1_20_3;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.rewriter.RecipeRewriter1_20_3;
|
||||
@ -78,8 +78,9 @@ import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.BannerPat
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.DyeColors;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Enchantments1_20_3;
|
||||
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.MapDecorations1_20_5;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.PotionEffects1_20_5;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Potions1_20_5;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.TrimMaterials1_20_3;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.TrimPatterns1_20_3;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPacket1_20_5;
|
||||
@ -105,6 +106,7 @@ 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> {
|
||||
|
||||
public static final String[] MOB_TAGS = {"NoAI", "Silent", "NoGravity", "Glowing", "Invulnerable", "Health", "Age", "Variant", "HuntingCooldown", "BucketVariantTag"};
|
||||
private static final StructuredDataConverter DATA_CONVERTER = new StructuredDataConverter(false);
|
||||
private static final GameProfile.Property[] EMPTY_PROPERTIES = new GameProfile.Property[0];
|
||||
private static final StatePropertyMatcher[] EMPTY_PROPERTY_MATCHERS = new StatePropertyMatcher[0];
|
||||
|
||||
@ -248,10 +250,10 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
if (item == null) return null;
|
||||
|
||||
super.handleItemToServer(item);
|
||||
return toOldItem(item);
|
||||
return toOldItem(item, DATA_CONVERTER);
|
||||
}
|
||||
|
||||
public Item toOldItem(final Item item) {
|
||||
public Item toOldItem(final Item item, final StructuredDataConverter dataConverter) {
|
||||
// Start out with custom data and add the rest on top, or short-curcuit with the original item
|
||||
final StructuredDataContainer data = item.structuredData();
|
||||
data.setIdLookup(protocol, true);
|
||||
@ -264,7 +266,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
}
|
||||
|
||||
for (final StructuredData<?> structuredData : data.data().values()) {
|
||||
StructuredDataConverter.writeToTag(structuredData, tag);
|
||||
dataConverter.writeToTag(structuredData, tag);
|
||||
}
|
||||
|
||||
return dataItem;
|
||||
@ -366,7 +368,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
|
||||
final ListTag<CompoundTag> attributeModifiersTag = tag.getListTag("AttributeModifiers", CompoundTag.class);
|
||||
if (attributeModifiersTag != null) {
|
||||
updateAttributes(data, attributeModifiersTag, (hideFlagsValue & StructuredDataConverter.HIDE_ATTRIBUTES) == 0);
|
||||
updateAttributes(data, tag, attributeModifiersTag, (hideFlagsValue & StructuredDataConverter.HIDE_ATTRIBUTES) == 0);
|
||||
}
|
||||
|
||||
final CompoundTag fireworksTag = tag.getCompoundTag("Fireworks");
|
||||
@ -432,10 +434,56 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
}
|
||||
}
|
||||
|
||||
final CompoundTag backupTag = StructuredDataConverter.removeBackupTag(tag);
|
||||
if (backupTag != null) {
|
||||
// Restore original data components
|
||||
restoreFromBackupTag(backupTag, data);
|
||||
}
|
||||
|
||||
data.set(StructuredDataKey.CUSTOM_DATA, tag);
|
||||
return item;
|
||||
}
|
||||
|
||||
private void restoreFromBackupTag(final CompoundTag backupTag, final StructuredDataContainer data) {
|
||||
final ByteTag enchantmentGlintOverride = backupTag.getByteTag("enchantment_glint_override");
|
||||
if (enchantmentGlintOverride != null) {
|
||||
data.set(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, enchantmentGlintOverride.asBoolean());
|
||||
}
|
||||
|
||||
if (backupTag.contains("hide_tooltip")) {
|
||||
data.set(StructuredDataKey.HIDE_TOOLTIP);
|
||||
}
|
||||
|
||||
final Tag intangibleProjectile = backupTag.get("intangible_projectile");
|
||||
if (intangibleProjectile != null) {
|
||||
data.set(StructuredDataKey.INTANGIBLE_PROJECTILE, intangibleProjectile);
|
||||
}
|
||||
|
||||
final IntTag maxStackSize = backupTag.getIntTag("max_stack_size");
|
||||
if (maxStackSize != null) {
|
||||
data.set(StructuredDataKey.MAX_STACK_SIZE, maxStackSize.asInt());
|
||||
}
|
||||
|
||||
final IntTag maxDamage = backupTag.getIntTag("max_damage");
|
||||
if (maxDamage != null) {
|
||||
data.set(StructuredDataKey.MAX_DAMAGE, maxDamage.asInt());
|
||||
}
|
||||
|
||||
final IntTag rarity = backupTag.getIntTag("rarity");
|
||||
if (rarity != null) {
|
||||
data.set(StructuredDataKey.RARITY, rarity.asInt());
|
||||
}
|
||||
|
||||
if (backupTag.contains("fire_resistant")) {
|
||||
data.set(StructuredDataKey.FIRE_RESISTANT);
|
||||
}
|
||||
|
||||
final IntTag ominousBottleAmplifier = backupTag.getIntTag("ominous_bottle_amplifier");
|
||||
if (ominousBottleAmplifier != null) {
|
||||
data.set(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER, ominousBottleAmplifier.asInt());
|
||||
}
|
||||
}
|
||||
|
||||
private int unmappedItemId(final String name) {
|
||||
return protocol.getMappingData().itemId(name);
|
||||
}
|
||||
@ -512,28 +560,30 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
);
|
||||
}
|
||||
|
||||
private void updateAttributes(final StructuredDataContainer data, final ListTag<CompoundTag> attributeModifiersTag, final boolean showInTooltip) {
|
||||
final AttributeModifier[] modifiers = attributeModifiersTag.stream().map(modifierTag -> {
|
||||
private void updateAttributes(final StructuredDataContainer data, final CompoundTag tag, final ListTag<CompoundTag> attributeModifiersTag, final boolean showInTooltip) {
|
||||
final List<AttributeModifier> modifiers = new ArrayList<>();
|
||||
for (int i = 0; i < attributeModifiersTag.size(); i++) {
|
||||
final CompoundTag modifierTag = attributeModifiersTag.get(i);
|
||||
final String attributeName = modifierTag.getString("AttributeName");
|
||||
final String name = modifierTag.getString("Name");
|
||||
final NumberTag amountTag = modifierTag.getNumberTag("Amount");
|
||||
final IntArrayTag uuidTag = modifierTag.getIntArrayTag("UUID");
|
||||
final int slotType = modifierTag.getInt("Slot");
|
||||
if (name == null || attributeName == null || amountTag == null || uuidTag == null) {
|
||||
return null;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int operationId = modifierTag.getInt("Operation");
|
||||
if (operationId < 0 || operationId > 2) {
|
||||
return null;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int attributeId = Attributes1_20_5.keyToId(attributeName);
|
||||
if (attributeId == -1) {
|
||||
return null;
|
||||
continue;
|
||||
}
|
||||
|
||||
return new AttributeModifier(
|
||||
modifiers.add(new AttributeModifier(
|
||||
attributeId,
|
||||
new ModifierData(
|
||||
UUIDUtil.fromIntArray(uuidTag.getValue()),
|
||||
@ -542,9 +592,9 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
operationId
|
||||
),
|
||||
slotType
|
||||
);
|
||||
}).filter(Objects::nonNull).toArray(AttributeModifier[]::new);
|
||||
data.set(StructuredDataKey.ATTRIBUTE_MODIFIERS, new AttributeModifiers(modifiers, showInTooltip));
|
||||
));
|
||||
}
|
||||
data.set(StructuredDataKey.ATTRIBUTE_MODIFIERS, new AttributeModifiers(modifiers.toArray(new AttributeModifier[0]), showInTooltip));
|
||||
}
|
||||
|
||||
private PotionEffectData readPotionEffectData(final CompoundTag tag) {
|
||||
@ -566,8 +616,10 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
final String potion = tag.getString("Potion");
|
||||
Integer potionId = null;
|
||||
if (potion != null) {
|
||||
final int id = Potions1_20_3.keyToId(potion);
|
||||
potionId = id > 0 ? id - 1 : null; // Empty potion type removed
|
||||
final int id = Potions1_20_5.keyToId(potion);
|
||||
if (id != -1) {
|
||||
potionId = id;
|
||||
}
|
||||
}
|
||||
|
||||
final NumberTag customPotionColorTag = tag.getNumberTag("CustomPotionColor");
|
||||
@ -580,8 +632,8 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
return null;
|
||||
}
|
||||
|
||||
final int id = PotionEffects.keyToId(identifier) - 1;
|
||||
if (id < 0) {
|
||||
final int id = PotionEffects1_20_5.keyToId(identifier);
|
||||
if (id == -1) {
|
||||
return null;
|
||||
}
|
||||
return new PotionEffect(id, readPotionEffectData(effectTag));
|
||||
@ -723,13 +775,16 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
final SuspiciousStewEffect[] suspiciousStewEffects = new SuspiciousStewEffect[effects.size()];
|
||||
for (int i = 0; i < effects.size(); i++) {
|
||||
final CompoundTag effect = effects.get(i);
|
||||
final String effectId = effect.getString("id", "luck");
|
||||
final String effectIdString = effect.getString("id", "luck");
|
||||
final int duration = effect.getInt("duration");
|
||||
final SuspiciousStewEffect stewEffect = new SuspiciousStewEffect(
|
||||
PotionEffects.keyToId(effectId) - 1,
|
||||
duration
|
||||
);
|
||||
suspiciousStewEffects[i] = stewEffect;
|
||||
final int effectId = PotionEffects1_20_5.keyToId(effectIdString);
|
||||
if (effectId != -1) {
|
||||
final SuspiciousStewEffect stewEffect = new SuspiciousStewEffect(
|
||||
effectId,
|
||||
duration
|
||||
);
|
||||
suspiciousStewEffects[i] = stewEffect;
|
||||
}
|
||||
}
|
||||
data.set(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS, suspiciousStewEffects);
|
||||
}
|
||||
@ -941,7 +996,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
||||
final float rotation = decorationTag.getFloat("rot");
|
||||
|
||||
final CompoundTag updatedDecorationTag = new CompoundTag();
|
||||
updatedDecorationTag.putString("type", MapDecorations1_20_3.idToKey(type));
|
||||
updatedDecorationTag.putString("type", MapDecorations1_20_5.idToKey(type));
|
||||
updatedDecorationTag.putDouble("x", x);
|
||||
updatedDecorationTag.putDouble("z", z);
|
||||
updatedDecorationTag.putFloat("rotation", rotation);
|
||||
|
@ -44,14 +44,14 @@ 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.protocols.protocol1_20_2to1_20.util.PotionEffects;
|
||||
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;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Enchantments1_20_3;
|
||||
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.MapDecorations1_20_5;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.PotionEffects1_20_5;
|
||||
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Potions1_20_5;
|
||||
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;
|
||||
@ -59,8 +59,9 @@ 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;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
final class StructuredDataConverter {
|
||||
public final class StructuredDataConverter {
|
||||
|
||||
static final int HIDE_ENCHANTMENTS = 1;
|
||||
static final int HIDE_ATTRIBUTES = 1 << 1;
|
||||
@ -71,9 +72,13 @@ final class StructuredDataConverter {
|
||||
static final int HIDE_DYE_COLOR = 1 << 6;
|
||||
static final int HIDE_ARMOR_TRIM = 1 << 7;
|
||||
|
||||
private static final Map<StructuredDataKey<?>, DataConverter<?>> REWRITERS = new Reference2ObjectOpenHashMap<>();
|
||||
private static final String BACKUP_TAG_KEY = "VV|DataComponents";
|
||||
|
||||
static {
|
||||
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
|
||||
});
|
||||
@ -102,7 +107,8 @@ final class StructuredDataConverter {
|
||||
register(StructuredDataKey.STORED_ENCHANTMENTS, (data, tag) -> convertEnchantments(data, tag, true));
|
||||
register(StructuredDataKey.ATTRIBUTE_MODIFIERS, (data, tag) -> {
|
||||
final ListTag<CompoundTag> modifiers = new ListTag<>(CompoundTag.class);
|
||||
for (final AttributeModifier modifier : data.modifiers()) {
|
||||
for (int i = 0; i < data.modifiers().length; i++) {
|
||||
final AttributeModifier modifier = data.modifiers()[i];
|
||||
final String identifier = Attributes1_20_5.idToKey(modifier.attribute());
|
||||
if (identifier == null) {
|
||||
continue;
|
||||
@ -137,14 +143,14 @@ final class StructuredDataConverter {
|
||||
final ListTag<CompoundTag> decorations = new ListTag<>(CompoundTag.class);
|
||||
for (final Map.Entry<String, Tag> entry : data.entrySet()) {
|
||||
final CompoundTag decorationTag = (CompoundTag) entry.getValue();
|
||||
final int id = MapDecorations1_20_3.keyToId(decorationTag.getString("type"));
|
||||
final int id = MapDecorations1_20_5.keyToId(decorationTag.getString("type"));
|
||||
if (id == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final CompoundTag convertedDecoration = new CompoundTag();
|
||||
convertedDecoration.putString("id", entry.getKey());
|
||||
convertedDecoration.putInt("type", id);
|
||||
convertedDecoration.putInt("type", id); // Write the id even if it is a new 1.20.5 one
|
||||
convertedDecoration.putDouble("x", decorationTag.getDouble("x"));
|
||||
convertedDecoration.putDouble("z", decorationTag.getDouble("z"));
|
||||
convertedDecoration.putFloat("rot", decorationTag.getFloat("rotation"));
|
||||
@ -240,6 +246,7 @@ final class StructuredDataConverter {
|
||||
register(StructuredDataKey.INSTRUMENT, (data, tag) -> {
|
||||
if (!data.hasId()) {
|
||||
// Can't do anything with direct values
|
||||
// TODO Backup
|
||||
return;
|
||||
}
|
||||
|
||||
@ -294,11 +301,15 @@ final class StructuredDataConverter {
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putBoolean("enchantment_glint_override", data);
|
||||
}
|
||||
if (!data) {
|
||||
// There is no way to remove the glint without removing the enchantments
|
||||
// which would lead to broken data, so we just don't do anything
|
||||
return;
|
||||
}
|
||||
|
||||
// If the glint is overridden, we just add an invalid enchantment to the existing list
|
||||
ListTag<CompoundTag> enchantmentsTag = tag.getListTag("Enchantments", CompoundTag.class);
|
||||
if (enchantmentsTag == null) {
|
||||
@ -314,7 +325,7 @@ final class StructuredDataConverter {
|
||||
});
|
||||
register(StructuredDataKey.POTION_CONTENTS, (data, tag) -> {
|
||||
if (data.potion() != null) {
|
||||
final String potion = Potions1_20_3.idToKey(data.potion() + 1); // Empty potion type added
|
||||
final String potion = Potions1_20_5.idToKey(data.potion()); // Include 1.20.5 names
|
||||
if (potion != null) {
|
||||
tag.putString("Potion", potion);
|
||||
}
|
||||
@ -322,12 +333,13 @@ final class StructuredDataConverter {
|
||||
if (data.customColor() != null) {
|
||||
tag.putInt("CustomPotionColor", data.customColor());
|
||||
}
|
||||
|
||||
final ListTag<CompoundTag> customPotionEffectsTag = new ListTag<>(CompoundTag.class);
|
||||
for (final PotionEffect effect : data.customEffects()) {
|
||||
final CompoundTag effectTag = new CompoundTag();
|
||||
final String id = PotionEffects.idToKey(effect.effect() + 1); // Empty potion type added
|
||||
final String id = PotionEffects1_20_5.idToKey(effect.effect());
|
||||
if (id != null) {
|
||||
effectTag.putString("id", id);
|
||||
effectTag.putString("id", id); // Include 1.20.5 ids
|
||||
}
|
||||
|
||||
final PotionEffectData details = effect.effectData();
|
||||
@ -345,9 +357,9 @@ final class StructuredDataConverter {
|
||||
final ListTag<CompoundTag> effectsTag = new ListTag<>(CompoundTag.class);
|
||||
for (final SuspiciousStewEffect effect : data) {
|
||||
final CompoundTag effectTag = new CompoundTag();
|
||||
final String id = PotionEffects.idToKey(effect.mobEffect() + 1);
|
||||
final String id = PotionEffects1_20_5.idToKey(effect.mobEffect());
|
||||
if (id != null) {
|
||||
effectTag.putString("id", id);
|
||||
effectTag.putString("id", id); // Include 1.20.5 ids
|
||||
}
|
||||
effectTag.putInt("duration", effect.duration());
|
||||
|
||||
@ -360,8 +372,10 @@ final class StructuredDataConverter {
|
||||
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());
|
||||
@ -444,21 +458,57 @@ final class StructuredDataConverter {
|
||||
register(StructuredDataKey.HIDE_TOOLTIP, (data, tag) -> {
|
||||
// Hide everything we can hide
|
||||
putHideFlag(tag, 0xFF);
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putBoolean("hide_tooltip", true);
|
||||
}
|
||||
});
|
||||
|
||||
// Nothing to do for these
|
||||
noop(StructuredDataKey.INTANGIBLE_PROJECTILE);
|
||||
noop(StructuredDataKey.MAX_STACK_SIZE);
|
||||
noop(StructuredDataKey.MAX_DAMAGE);
|
||||
noop(StructuredDataKey.RARITY);
|
||||
noop(StructuredDataKey.FOOD);
|
||||
noop(StructuredDataKey.FIRE_RESISTANT);
|
||||
noop(StructuredDataKey.TOOL);
|
||||
noop(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER);
|
||||
// New in 1.20.5
|
||||
register(StructuredDataKey.INTANGIBLE_PROJECTILE, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).put("intangible_projectile", data);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.MAX_STACK_SIZE, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putInt("max_stack_size", data);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.MAX_DAMAGE, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putInt("max_damage", data);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.RARITY, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putInt("rarity", data);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.FOOD, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
//createBackupTag(tag).; // TODO Backup
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.FIRE_RESISTANT, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putBoolean("fire_resistant", true);
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.TOOL, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
//createBackupTag(tag).; // TODO Backup
|
||||
}
|
||||
});
|
||||
register(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER, (data, tag) -> {
|
||||
if (backupInconvertibleData) {
|
||||
createBackupTag(tag).putInt("ominous_bottle_amplifier", data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static String toItemName(final int id) {
|
||||
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) : "";
|
||||
}
|
||||
|
||||
@ -480,12 +530,13 @@ final class StructuredDataConverter {
|
||||
return subTag;
|
||||
}
|
||||
|
||||
private static void convertBlockPredicates(final CompoundTag tag, final AdventureModePredicate data, final String key, final int hideFlag) {
|
||||
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()) {
|
||||
final HolderSet holders = predicate.holderSet();
|
||||
if (holders == null) {
|
||||
// Can't do (nicely)
|
||||
// TODO Backup
|
||||
continue;
|
||||
}
|
||||
if (holders.hasTagKey()) {
|
||||
@ -504,7 +555,7 @@ final class StructuredDataConverter {
|
||||
}
|
||||
}
|
||||
|
||||
private static StringTag serializeBlockPredicate(final BlockPredicate predicate, final String identifier) {
|
||||
private StringTag serializeBlockPredicate(final BlockPredicate predicate, final String identifier) {
|
||||
final StringBuilder builder = new StringBuilder(identifier);
|
||||
if (predicate.propertyMatchers() != null) {
|
||||
for (final StatePropertyMatcher matcher : predicate.propertyMatchers()) {
|
||||
@ -521,7 +572,7 @@ final class StructuredDataConverter {
|
||||
return new StringTag(builder.toString());
|
||||
}
|
||||
|
||||
private static CompoundTag convertExplosion(final FireworkExplosion explosion) {
|
||||
private CompoundTag convertExplosion(final FireworkExplosion explosion) {
|
||||
final CompoundTag explosionTag = new CompoundTag();
|
||||
explosionTag.putInt("Type", explosion.shape());
|
||||
explosionTag.put("Colors", new IntArrayTag(explosion.colors().clone()));
|
||||
@ -531,7 +582,7 @@ final class StructuredDataConverter {
|
||||
return explosionTag;
|
||||
}
|
||||
|
||||
private static void convertItemList(final Item[] items, final CompoundTag tag, final String key) {
|
||||
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();
|
||||
@ -548,10 +599,20 @@ final class StructuredDataConverter {
|
||||
tag.put(key, itemsTag);
|
||||
}
|
||||
|
||||
private static void convertEnchantments(final Enchantments data, final CompoundTag tag, final boolean storedEnchantments) {
|
||||
private void convertEnchantments(final Enchantments data, final CompoundTag tag, final boolean storedEnchantments) {
|
||||
final ListTag<CompoundTag> enchantments = new ListTag<>(CompoundTag.class);
|
||||
final int piercingId = Enchantments1_20_3.keyToId("piercing");
|
||||
for (final Int2IntMap.Entry entry : data.enchantments().int2IntEntrySet()) {
|
||||
final String identifier = Enchantments1_20_3.idToKey(entry.getIntKey());
|
||||
int id = entry.getIntKey();
|
||||
if (id > piercingId) {
|
||||
if (id <= piercingId + 3) {
|
||||
// Density, breach, wind burst - Already backed up by VB
|
||||
continue;
|
||||
}
|
||||
id -= 3;
|
||||
}
|
||||
|
||||
final String identifier = Enchantments1_20_3.idToKey(id);
|
||||
if (identifier == null) {
|
||||
continue;
|
||||
}
|
||||
@ -568,28 +629,35 @@ final class StructuredDataConverter {
|
||||
}
|
||||
}
|
||||
|
||||
private static void putHideFlag(final CompoundTag tag, final int value) {
|
||||
private void putHideFlag(final CompoundTag tag, final int value) {
|
||||
tag.putInt("HideFlags", tag.getInt("HideFlags") | value);
|
||||
}
|
||||
|
||||
public static <T> void writeToTag(final StructuredData<T> data, final CompoundTag tag) {
|
||||
public <T> void writeToTag(final StructuredData<T> data, final CompoundTag tag) {
|
||||
if (data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
final DataConverter<T> converter = (DataConverter<T>) REWRITERS.get(data.key());
|
||||
final DataConverter<T> converter = (DataConverter<T>) rewriters.get(data.key());
|
||||
Preconditions.checkNotNull(converter, "No converter for %s found", data.key());
|
||||
converter.convert(data.value(), tag);
|
||||
}
|
||||
|
||||
private static <T> void register(final StructuredDataKey<T> key, final DataConverter<T> converter) {
|
||||
REWRITERS.put(key, converter);
|
||||
private <T> void register(final StructuredDataKey<T> key, final DataConverter<T> converter) {
|
||||
rewriters.put(key, converter);
|
||||
}
|
||||
|
||||
private static <T> void noop(final StructuredDataKey<T> key) {
|
||||
register(key, (data, tag) -> {
|
||||
});
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user