3
0
Mirror von https://github.com/ViaVersion/ViaBackwards.git synchronisiert 2024-11-19 06:20:14 +01:00

Backup inconvertible item component data for creative clients in 1.21+

Dieser Commit ist enthalten in:
FlorianMichael 2024-11-03 17:01:50 +01:00
Ursprung cfad15a9b2
Commit 6245443e57
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: C2FB87E71C425126
3 geänderte Dateien mit 396 neuen und 1 gelöschten Zeilen

Datei anzeigen

@ -17,14 +17,33 @@
*/ */
package com.viaversion.viabackwards.protocol.v1_21_2to1_21.rewriter; package com.viaversion.viabackwards.protocol.v1_21_2to1_21.rewriter;
import com.viaversion.nbt.tag.ByteTag;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.IntArrayTag;
import com.viaversion.nbt.tag.IntTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter; import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21; import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.InventoryStateIdStorage; import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.InventoryStateIdStorage;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.RecipeStorage; import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.RecipeStorage;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData; import com.viaversion.viaversion.api.data.MappingData;
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.Particle;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.data.Consumable1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.DeathProtection;
import com.viaversion.viaversion.api.minecraft.item.data.Equippable;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2;
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.UseCooldown;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
@ -38,6 +57,7 @@ import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacke
import com.viaversion.viaversion.rewriter.BlockRewriter; import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter; import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Unit;
import static com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.BlockItemPacketRewriter1_21_2.downgradeItemData; import static com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.BlockItemPacketRewriter1_21_2.downgradeItemData;
import static com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.BlockItemPacketRewriter1_21_2.updateItemData; import static com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.BlockItemPacketRewriter1_21_2.updateItemData;
@ -251,6 +271,7 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem
@Override @Override
public Item handleItemToClient(final UserConnection connection, final Item item) { public Item handleItemToClient(final UserConnection connection, final Item item) {
super.handleItemToClient(connection, item); super.handleItemToClient(connection, item);
backupInconvertibleData(item);
downgradeItemData(item); downgradeItemData(item);
return item; return item;
} }
@ -259,6 +280,299 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem
public Item handleItemToServer(final UserConnection connection, final Item item) { public Item handleItemToServer(final UserConnection connection, final Item item) {
super.handleItemToServer(connection, item); super.handleItemToServer(connection, item);
updateItemData(item); updateItemData(item);
restoreInconvertibleData(item);
return item; return item;
} }
// Backup inconvertible data and later restore to prevent data loss for creative mode clients
private void backupInconvertibleData(final Item item) {
final StructuredDataContainer data = item.dataContainer();
final Holder<Instrument1_21_2> instrument = data.get(StructuredDataKey.INSTRUMENT1_21_2);
if (instrument != null && instrument.isDirect()) {
saveTag(createCustomTag(item), instrument.value().description(), "instrument_description");
}
final HolderSet repairable = data.get(StructuredDataKey.REPAIRABLE);
if (repairable != null) {
final CompoundTag tag = new CompoundTag();
convertHolderSet(tag, repairable);
saveTag(createCustomTag(item), tag, "repairable");
}
final Integer enchantable = data.get(StructuredDataKey.ENCHANTABLE);
if (enchantable != null) {
saveTag(createCustomTag(item), new IntTag(enchantable), "enchantable");
}
final UseCooldown useCooldown = data.get(StructuredDataKey.USE_COOLDOWN);
if (useCooldown != null) {
final CompoundTag tag = new CompoundTag();
tag.putFloat("seconds", useCooldown.seconds());
if (useCooldown.cooldownGroup() != null) {
tag.putString("cooldown_group", useCooldown.cooldownGroup());
}
}
final String itemModel = data.get(StructuredDataKey.ITEM_MODEL);
if (itemModel != null) {
saveTag(createCustomTag(item), new StringTag(itemModel), "item_model");
}
final Equippable equippable = data.get(StructuredDataKey.EQUIPPABLE);
if (equippable != null) {
final CompoundTag tag = new CompoundTag();
tag.putInt("equipment_slot", equippable.equipmentSlot());
convertSoundEventHolder(tag, equippable.soundEvent());
final String model = equippable.model();
if (model != null) {
tag.putString("model", model);
}
final String cameraOverlay = equippable.cameraOverlay();
if (cameraOverlay != null) {
tag.putString("camera_overlay", cameraOverlay);
}
if (equippable.allowedEntities() != null) {
final CompoundTag allowedEntities = new CompoundTag();
convertHolderSet(allowedEntities, equippable.allowedEntities());
tag.put("allowed_entities", allowedEntities);
}
tag.putBoolean("dispensable", equippable.dispensable());
tag.putBoolean("swappable", equippable.swappable());
tag.putBoolean("damage_on_hurt", equippable.damageOnHurt());
saveTag(createCustomTag(item), tag, "equippable");
}
final Unit glider = data.get(StructuredDataKey.GLIDER);
if (glider != null) {
saveTag(createCustomTag(item), new ByteTag(true), "glider");
}
final String tooltipStyle = data.get(StructuredDataKey.TOOLTIP_STYLE);
if (tooltipStyle != null) {
saveTag(createCustomTag(item), new StringTag(tooltipStyle), "tooltip_style");
}
final DeathProtection deathProtection = data.get(StructuredDataKey.DEATH_PROTECTION);
if (deathProtection == null) {
return;
}
final ListTag<CompoundTag> tag = new ListTag<>(CompoundTag.class);
for (final Consumable1_21_2.ConsumeEffect<?> effect : deathProtection.deathEffects()) {
final CompoundTag effectTag = new CompoundTag();
convertConsumableEffect(effectTag, effect);
tag.add(effectTag);
}
saveTag(createCustomTag(item), tag, "death_protection");
}
private void convertConsumableEffect(final CompoundTag tag, Consumable1_21_2.ConsumeEffect<?> effect) {
tag.putInt("id", effect.id());
if (effect.type() == Consumable1_21_2.ApplyStatusEffects.TYPE && effect.value() instanceof Consumable1_21_2.ApplyStatusEffects value) {
tag.putString("type", "apply_effects");
final ListTag<CompoundTag> effects = new ListTag<>(CompoundTag.class);
for (final PotionEffect potionEffect : value.effects()) {
final CompoundTag effectTag = new CompoundTag();
effectTag.putInt("effect", potionEffect.effect());
convertPotionEffectData(effectTag, potionEffect.effectData());
effects.add(effectTag);
}
tag.put("effects", effects);
tag.putFloat("probability", value.probability());
} else if (effect.type() == Types.HOLDER_SET && effect.value() instanceof HolderSet set) {
tag.putString("type", "remove_effects");
if (set.hasIds()) {
tag.put("ids", new IntArrayTag(set.ids()));
} else {
tag.putString("tag", set.tagKey());
}
} else if (effect.type() == Types.EMPTY) {
tag.putString("type", "clear_all_effects");
} else if (effect.type() == Types.FLOAT) {
tag.putString("type", "teleport_randomly");
tag.putFloat("probability", (Float) effect.value());
} else if (effect.type() == Types.SOUND_EVENT && effect.value() instanceof Holder sound) {
tag.putString("type", "play_sound");
convertSoundEventHolder(tag, sound);
}
}
private void convertPotionEffectData(final CompoundTag tag, final PotionEffectData data) {
tag.putInt("amplifier", data.amplifier());
tag.putInt("duration", data.duration());
tag.putBoolean("ambient", data.ambient());
tag.putBoolean("show_particles", data.showParticles());
tag.putBoolean("show_icon", data.showIcon());
if (data.hiddenEffect() != null) {
final CompoundTag hiddenEffect = new CompoundTag();
convertPotionEffectData(hiddenEffect, data.hiddenEffect());
tag.put("hidden_effect", hiddenEffect);
}
}
private void convertSoundEventHolder(final CompoundTag tag, final Holder<SoundEvent> holder) {
if (holder.hasId()) {
tag.putInt("sound", holder.id());
} else {
final SoundEvent event = holder.value();
tag.putString("identifier", event.identifier());
if (event.fixedRange() != null) {
tag.putFloat("fixed_range", event.fixedRange());
}
}
}
private void convertHolderSet(final CompoundTag tag, final HolderSet set) {
if (set.hasIds()) {
tag.put("ids", new IntArrayTag(set.ids()));
} else {
tag.putString("tag", set.tagKey());
}
}
private Consumable1_21_2.ConsumeEffect<?> convertConsumableEffect(final CompoundTag tag) {
final int id = tag.getInt("id");
final String type = tag.getString("type");
if ("apply_effects".equals(type)) {
final ListTag<CompoundTag> effects = tag.getListTag("effects", CompoundTag.class);
final PotionEffect[] potionEffects = new PotionEffect[effects.size()];
for (int i = 0; i < effects.size(); i++) {
final CompoundTag effectTag = effects.get(i);
final int effect = effectTag.getInt("effect");
final PotionEffectData data = convertPotionEffectData(effectTag.getCompoundTag("data"));
potionEffects[i] = new PotionEffect(effect, data);
}
final float probability = tag.getFloat("probability");
return new Consumable1_21_2.ConsumeEffect<>(id, Consumable1_21_2.ApplyStatusEffects.TYPE, new Consumable1_21_2.ApplyStatusEffects(potionEffects, probability));
} else if ("remove_effects".equals(type)) {
final HolderSet set = convertHolderSet(tag);
return new Consumable1_21_2.ConsumeEffect<>(id, Types.HOLDER_SET, set);
} else if ("clear_all_effects".equals(type)) {
return new Consumable1_21_2.ConsumeEffect<>(id, Types.EMPTY, Unit.INSTANCE);
} else if ("teleport_randomly".equals(type)) {
final float probability = tag.getFloat("probability");
return new Consumable1_21_2.ConsumeEffect<>(id, Types.FLOAT, probability);
} else if ("play_sound".equals(type)) {
final Holder<SoundEvent> sound = convertSoundEventHolder(tag);
return new Consumable1_21_2.ConsumeEffect<>(id, Types.SOUND_EVENT, sound);
}
return null;
}
private PotionEffectData convertPotionEffectData(final CompoundTag tag) {
final int amplifier = tag.getInt("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");
final CompoundTag hiddenEffect = tag.getCompoundTag("hidden_effect");
return new PotionEffectData(amplifier, duration, ambient, showParticles, showIcon, hiddenEffect != null ? convertPotionEffectData(hiddenEffect) : null);
}
private Holder<SoundEvent> convertSoundEventHolder(final CompoundTag tag) {
final int soundId = tag.getInt("sound");
if (soundId != 0) {
return Holder.of(soundId);
}
final String identifier = tag.getString("identifier");
final Float fixedRange = tag.getFloat("fixed_range");
return Holder.of(new SoundEvent(identifier, fixedRange));
}
private HolderSet convertHolderSet(final CompoundTag tag) {
if (tag == null) {
return null;
}
final IntArrayTag ids = tag.getIntArrayTag("ids");
if (ids != null) {
return HolderSet.of(ids.getValue());
}
return HolderSet.of(tag.getString("tag"));
}
private void restoreInconvertibleData(final Item item) {
final StructuredDataContainer data = item.dataContainer();
final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA);
final Holder<Instrument1_21_2> instrument = data.get(StructuredDataKey.INSTRUMENT1_21_2);
if (instrument != null && customData != null) {
final Tag description = customData.remove(nbtTagName("instrument_description"));
if (description != null) {
final Instrument1_21_2 delegate = instrument.value();
data.set(StructuredDataKey.INSTRUMENT1_21_2, Holder.of(new Instrument1_21_2(delegate.soundEvent(), delegate.useDuration(), delegate.range(), description)));
}
removeCustomTag(data, customData);
}
final IntArrayTag repairableIds = customData.getIntArrayTag("repairable_ids");
final String repairableTag = customData.getString("repairable_tag");
if (repairableIds != null || repairableTag != null) {
data.set(StructuredDataKey.REPAIRABLE, repairableIds != null ? HolderSet.of(repairableIds.getValue()) : HolderSet.of(repairableTag));
removeCustomTag(data, customData);
}
final IntTag enchantable = customData.getIntTag("enchantable");
if (enchantable != null) {
data.set(StructuredDataKey.ENCHANTABLE, enchantable.asInt());
removeCustomTag(data, customData);
}
final CompoundTag useCooldown = customData.getCompoundTag("use_cooldown");
if (useCooldown != null) {
final float seconds = useCooldown.getFloat("seconds");
final String cooldownGroup = useCooldown.getString("cooldown_group");
data.set(StructuredDataKey.USE_COOLDOWN, new UseCooldown(seconds, cooldownGroup));
removeCustomTag(data, customData);
}
final String itemModel = customData.getString("item_model");
if (itemModel != null) {
data.set(StructuredDataKey.ITEM_MODEL, itemModel);
removeCustomTag(data, customData);
}
final CompoundTag equippable = customData.getCompoundTag("equippable");
if (equippable != null) {
final int equipmentSlot = equippable.getInt("equipment_slot");
final Holder<SoundEvent> soundEvent = convertSoundEventHolder(equippable);
final String model = equippable.getString("model");
final String cameraOverlay = equippable.getString("camera_overlay");
final HolderSet allowedEntities = convertHolderSet(equippable.getCompoundTag("allowed_entities"));
final boolean dispensable = equippable.getBoolean("dispensable");
final boolean swappable = equippable.getBoolean("swappable");
final boolean damageOnHurt = equippable.getBoolean("damage_on_hurt");
data.set(StructuredDataKey.EQUIPPABLE, new Equippable(equipmentSlot, soundEvent, model, cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt));
removeCustomTag(data, customData);
}
final ByteTag glider = customData.getByteTag("glider");
if (glider != null) {
data.set(StructuredDataKey.GLIDER, Unit.INSTANCE);
removeCustomTag(data, customData);
}
final String tooltipStyle = customData.getString("tooltip_style");
if (tooltipStyle != null) {
data.set(StructuredDataKey.TOOLTIP_STYLE, tooltipStyle);
removeCustomTag(data, customData);
}
final ListTag<CompoundTag> deathProtection = customData.getListTag("death_protection", CompoundTag.class);
if (deathProtection != null) {
final Consumable1_21_2.ConsumeEffect<?>[] effects = new Consumable1_21_2.ConsumeEffect[deathProtection.size()];
for (int i = 0; i < deathProtection.size(); i++) {
effects[i] = convertConsumableEffect(deathProtection.get(i));
}
data.set(StructuredDataKey.DEATH_PROTECTION, new DeathProtection(effects));
removeCustomTag(data, customData);
}
}
} }

Datei anzeigen

@ -29,10 +29,13 @@ import com.viaversion.viabackwards.protocol.v1_21to1_20_5.storage.EnchantmentsPa
import com.viaversion.viabackwards.protocol.v1_21to1_20_5.storage.OpenScreenStorage; import com.viaversion.viabackwards.protocol.v1_21to1_20_5.storage.OpenScreenStorage;
import com.viaversion.viabackwards.protocol.v1_21to1_20_5.storage.PlayerRotationStorage; import com.viaversion.viabackwards.protocol.v1_21to1_20_5.storage.PlayerRotationStorage;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer; import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments; import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.api.minecraft.item.data.JukeboxPlayable;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5; import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
@ -49,6 +52,7 @@ import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacke
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21; import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.rewriter.BlockRewriter; import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.IdRewriteFunction; import com.viaversion.viaversion.rewriter.IdRewriteFunction;
import com.viaversion.viaversion.util.Either;
import com.viaversion.viaversion.util.SerializerVersion; import com.viaversion.viaversion.util.SerializerVersion;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -188,6 +192,7 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe
// Order is important // Order is important
super.handleItemToClient(connection, item); super.handleItemToClient(connection, item);
backupInconvertibleData(item);
downgradeItemData(item); downgradeItemData(item);
if (data.has(StructuredDataKey.RARITY)) { if (data.has(StructuredDataKey.RARITY)) {
@ -222,6 +227,7 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe
// Order is important // Order is important
super.handleItemToServer(connection, item); super.handleItemToServer(connection, item);
updateItemData(item); updateItemData(item);
restoreInconvertibleData(item);
final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA); final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA);
if (customData == null) { if (customData == null) {
@ -264,6 +270,81 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe
} }
} }
private void backupInconvertibleData(final Item item) {
final StructuredDataContainer data = item.dataContainer();
final JukeboxPlayable jukeboxPlayable = data.get(StructuredDataKey.JUKEBOX_PLAYABLE);
if (jukeboxPlayable == null) {
return;
}
final CompoundTag tag = new CompoundTag();
if (jukeboxPlayable.song().isLeft()) {
final Holder<JukeboxPlayable.JukeboxSong> song = jukeboxPlayable.song().left();
if (song.hasId()) {
tag.putInt("song_id", song.id());
} else {
final JukeboxPlayable.JukeboxSong songData = song.value();
final Holder<SoundEvent> soundEvent = songData.soundEvent();
if (soundEvent.hasId()) {
tag.putInt("sound", soundEvent.id());
} else {
final SoundEvent event = soundEvent.value();
tag.putString("identifier", event.identifier());
if (event.fixedRange() != null) {
tag.putFloat("fixed_range", event.fixedRange());
}
}
tag.put("description", songData.description());
tag.putFloat("length_in_seconds", songData.lengthInSeconds());
tag.putInt("comparator_output", songData.comparatorOutput());
}
} else {
tag.putString("song_identifier", jukeboxPlayable.song().right());
}
tag.putBoolean("show_in_tooltip", jukeboxPlayable.showInTooltip());
saveTag(createCustomTag(item), tag, "jukebox_playable");
}
private void restoreInconvertibleData(final Item item) {
final StructuredDataContainer data = item.dataContainer();
final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA);
if (customData == null) {
return;
}
final CompoundTag tag = customData.removeUnchecked("jukebox_playable");
if (tag == null) {
return;
}
final Either<Holder<JukeboxPlayable.JukeboxSong>, String> song;
if (tag.contains("song_identifier")) {
song = Either.right(tag.getString("song_identifier"));
} else {
final Holder<JukeboxPlayable.JukeboxSong> songData;
if (tag.contains("song_id")) {
songData = Holder.of(tag.getInt("song_id"));
} else {
final Holder<SoundEvent> soundEvent;
if (tag.contains("sound")) {
soundEvent = Holder.of(tag.getInt("sound"));
} else {
final String identifier = tag.getString("identifier");
final Float fixedRange = tag.contains("fixed_range") ? tag.getFloat("fixed_range") : null;
soundEvent = Holder.of(new SoundEvent(identifier, fixedRange));
}
final Tag description = tag.get("description");
final float lengthInSeconds = tag.getFloat("length_in_seconds");
final int comparatorOutput = tag.getInt("comparator_output");
songData = Holder.of(new JukeboxPlayable.JukeboxSong(soundEvent, description, lengthInSeconds, comparatorOutput));
}
song = Either.left(songData);
}
final JukeboxPlayable jukeboxPlayable = new JukeboxPlayable(song, tag.getBoolean("show_in_tooltip"));
data.set(StructuredDataKey.JUKEBOX_PLAYABLE, jukeboxPlayable);
removeCustomTag(data, customData);
}
private record PendingIdChange(int id, int mappedId, int level) { private record PendingIdChange(int id, int mappedId, int level) {
} }
} }

Datei anzeigen

@ -1,4 +1,4 @@
projectVersion=5.1.1 projectVersion=5.1.2-SNAPSHOT
# Smile emoji # Smile emoji
mcVersions=1.21.3,1.21.2,1.21.1,1.21,1.20.6,1.20.5,1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10 mcVersions=1.21.3,1.21.2,1.21.1,1.21,1.20.6,1.20.5,1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10