WIP 24w33a

This commit is contained in:
Nassim Jahnke 2024-08-15 20:00:29 +02:00
parent 7a3ef1e0b7
commit 033741d292
No known key found for this signature in database
GPG Key ID: EF6771C01F6EF02F
30 changed files with 1321 additions and 105 deletions

View File

@ -26,6 +26,7 @@ import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.minecraft.GameProfile;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.HolderSet;
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.ArmorTrim;
@ -40,7 +41,8 @@ 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.FoodProperties;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.JukeboxPlayable;
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
@ -53,6 +55,7 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
import com.viaversion.viaversion.api.type.types.version.Types1_21;
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
import com.viaversion.viaversion.util.Unit;
public record StructuredDataKey<T>(String identifier, Type<T> type) {
@ -82,6 +85,8 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<FoodProperties> FOOD1_21 = new StructuredDataKey<>("food", FoodProperties.TYPE1_21);
public static final StructuredDataKey<Unit> FIRE_RESISTANT = new StructuredDataKey<>("fire_resistant", Types.EMPTY);
public static final StructuredDataKey<ToolProperties> TOOL = new StructuredDataKey<>("tool", ToolProperties.TYPE);
public static final StructuredDataKey<Integer> ENCHANTABLE = new StructuredDataKey<>("enchantable", Types.VAR_INT);
public static final StructuredDataKey<HolderSet> REPAIRABLE = new StructuredDataKey<>("repairable", Types.HOLDER_SET);
public static final StructuredDataKey<Enchantments> STORED_ENCHANTMENTS = new StructuredDataKey<>("stored_enchantments", Enchantments.TYPE);
public static final StructuredDataKey<DyedColor> DYED_COLOR = new StructuredDataKey<>("dyed_color", DyedColor.TYPE);
public static final StructuredDataKey<Integer> MAP_COLOR = new StructuredDataKey<>("map_color", Types.INT);
@ -90,8 +95,10 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Integer> MAP_POST_PROCESSING = new StructuredDataKey<>("map_post_processing", Types.VAR_INT);
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_20_5 = new StructuredDataKey<>("charged_projectiles", Types1_20_5.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_21 = new StructuredDataKey<>("charged_projectiles", Types1_21.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> CHARGED_PROJECTILES1_21_2 = new StructuredDataKey<>("charged_projectiles", Types1_21_2.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_20_5 = new StructuredDataKey<>("bundle_contents", Types1_20_5.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_21 = new StructuredDataKey<>("bundle_contents", Types1_21.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> BUNDLE_CONTENTS1_21_2 = new StructuredDataKey<>("bundle_contents", Types1_21_2.ITEM_ARRAY);
public static final StructuredDataKey<PotionContents> POTION_CONTENTS = new StructuredDataKey<>("potion_contents", PotionContents.TYPE);
public static final StructuredDataKey<SuspiciousStewEffect[]> SUSPICIOUS_STEW_EFFECTS = new StructuredDataKey<>("suspicious_stew_effects", SuspiciousStewEffect.ARRAY_TYPE);
public static final StructuredDataKey<FilterableString[]> WRITABLE_BOOK_CONTENT = new StructuredDataKey<>("writable_book_content", FilterableString.ARRAY_TYPE);
@ -101,7 +108,8 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<CompoundTag> ENTITY_DATA = new StructuredDataKey<>("entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<CompoundTag> BUCKET_ENTITY_DATA = new StructuredDataKey<>("bucket_entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<CompoundTag> BLOCK_ENTITY_DATA = new StructuredDataKey<>("block_entity_data", Types.COMPOUND_TAG);
public static final StructuredDataKey<Holder<Instrument>> INSTRUMENT = new StructuredDataKey<>("instrument", Instrument.TYPE);
public static final StructuredDataKey<Holder<Instrument1_20_5>> INSTRUMENT1_20_5 = new StructuredDataKey<>("instrument", Instrument1_20_5.TYPE);
public static final StructuredDataKey<Holder<Instrument1_21_2>> INSTRUMENT1_21_2 = new StructuredDataKey<>("instrument", Instrument1_21_2.TYPE);
public static final StructuredDataKey<Integer> OMINOUS_BOTTLE_AMPLIFIER = new StructuredDataKey<>("ominous_bottle_amplifier", Types.VAR_INT);
public static final StructuredDataKey<JukeboxPlayable> JUKEBOX_PLAYABLE = new StructuredDataKey<>("jukebox_playable", JukeboxPlayable.TYPE);
public static final StructuredDataKey<Tag> RECIPES = new StructuredDataKey<>("recipes", Types.TAG);
@ -115,6 +123,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<PotDecorations> POT_DECORATIONS = new StructuredDataKey<>("pot_decorations", PotDecorations.TYPE);
public static final StructuredDataKey<Item[]> CONTAINER1_20_5 = new StructuredDataKey<>("container", Types1_20_5.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> CONTAINER1_21 = new StructuredDataKey<>("container", Types1_21.ITEM_ARRAY);
public static final StructuredDataKey<Item[]> CONTAINER1_21_2 = new StructuredDataKey<>("container", Types1_21_2.ITEM_ARRAY);
public static final StructuredDataKey<BlockStateProperties> BLOCK_STATE = new StructuredDataKey<>("block_state", BlockStateProperties.TYPE);
public static final StructuredDataKey<Bee[]> BEES = new StructuredDataKey<>("bees", Bee.ARRAY_TYPE);
public static final StructuredDataKey<Tag> LOCK = new StructuredDataKey<>("lock", Types.TAG);

View File

@ -29,19 +29,19 @@ import com.viaversion.viaversion.api.type.types.misc.HolderType;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
public record Instrument(Holder<SoundEvent> soundEvent, int useDuration, float range) {
public record Instrument1_20_5(Holder<SoundEvent> soundEvent, int useDuration, float range) {
public static final HolderType<Instrument> TYPE = new HolderType<>() {
public static final HolderType<Instrument1_20_5> TYPE = new HolderType<>() {
@Override
public Instrument readDirect(final ByteBuf buffer) {
public Instrument1_20_5 readDirect(final ByteBuf buffer) {
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
final int useDuration = Types.VAR_INT.readPrimitive(buffer);
final float range = buffer.readFloat();
return new Instrument(soundEvent, useDuration, range);
return new Instrument1_20_5(soundEvent, useDuration, range);
}
@Override
public void writeDirect(final ByteBuf buffer, final Instrument value) {
public void writeDirect(final ByteBuf buffer, final Instrument1_20_5 value) {
Types.SOUND_EVENT.write(buffer, value.soundEvent());
Types.VAR_INT.writePrimitive(buffer, value.useDuration());
buffer.writeFloat(value.range());

View File

@ -0,0 +1,54 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.HolderType;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public record Instrument1_21_2(Holder<SoundEvent> soundEvent, float useDuration, float range, @Nullable Tag description) {
public static final HolderType<Instrument1_21_2> TYPE = new HolderType<>() {
@Override
public Instrument1_21_2 readDirect(final ByteBuf buffer) {
final Holder<SoundEvent> soundEvent = Types.SOUND_EVENT.read(buffer);
final float useDuration = Types.FLOAT.readPrimitive(buffer);
final float range = buffer.readFloat();
final Tag description = Types.TAG.read(buffer);
return new Instrument1_21_2(soundEvent, useDuration, range, description);
}
@Override
public void writeDirect(final ByteBuf buffer, final Instrument1_21_2 value) {
Types.SOUND_EVENT.write(buffer, value.soundEvent());
Types.FLOAT.writePrimitive(buffer, value.useDuration());
buffer.writeFloat(value.range());
Types.TAG.write(buffer, value.description());
}
};
}

View File

@ -43,7 +43,8 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
private static final List<ProtocolVersion> VERSION_LIST = new ArrayList<>();
public static final ProtocolVersion v1_7_2 = register(4, "1.7.2-1.7.5", new SubVersionRange("1.7", 2, 5));
@Deprecated(forRemoval=true) public static final ProtocolVersion v1_7_1 = v1_7_2;
@Deprecated(forRemoval = true)
public static final ProtocolVersion v1_7_1 = v1_7_2;
public static final ProtocolVersion v1_7_6 = register(5, "1.7.6-1.7.10", new SubVersionRange("1.7", 6, 10));
public static final ProtocolVersion v1_8 = register(47, "1.8.x", new SubVersionRange("1.8", 0, 9));
public static final ProtocolVersion v1_9 = register(107, "1.9");
@ -85,6 +86,7 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
public static final ProtocolVersion v1_20_3 = register(765, "1.20.3-1.20.4", new SubVersionRange("1.20", 3, 4));
public static final ProtocolVersion v1_20_5 = register(766, "1.20.5-1.20.6", new SubVersionRange("1.20", 5, 6));
public static final ProtocolVersion v1_21 = register(767, "1.21-1.21.1", new SubVersionRange("1.21", 0, 1));
public static final ProtocolVersion v1_21_2 = register(768, 205, "1.21.2");
public static final ProtocolVersion unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null);
public static ProtocolVersion register(int version, String name) {

View File

@ -0,0 +1,56 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataListType;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataType;
import com.viaversion.viaversion.api.type.types.item.ItemCostType1_20_5;
import com.viaversion.viaversion.api.type.types.item.ItemType1_20_5;
import com.viaversion.viaversion.api.type.types.item.StructuredDataType;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import java.util.List;
// Most of these are only safe to use after protocol loading
public final class Types1_21_2 {
public static final StructuredDataType STRUCTURED_DATA = new StructuredDataType();
public static final Type<StructuredData<?>[]> STRUCTURED_DATA_ARRAY = new ArrayType<>(STRUCTURED_DATA);
public static final ItemType1_20_5 ITEM = new ItemType1_20_5(STRUCTURED_DATA);
public static final Type<Item> OPTIONAL_ITEM = ITEM.new OptionalItemType(); // Optional as in boolean prefixed, not via the amount
public static final Type<Item[]> ITEM_ARRAY = new ArrayType<>(ITEM);
public static final Type<Item> ITEM_COST = new ItemCostType1_20_5(STRUCTURED_DATA_ARRAY);
public static final Type<Item> OPTIONAL_ITEM_COST = new ItemCostType1_20_5.OptionalItemCostType(ITEM_COST);
public static final ParticleType PARTICLE = new ParticleType();
public static final ArrayType<Particle> PARTICLES = new ArrayType<>(PARTICLE);
public static final EntityDataTypes1_21 ENTITY_DATA_TYPES = new EntityDataTypes1_21(PARTICLE, PARTICLES);
public static final Type<EntityData> ENTITY_DATA = new EntityDataType(ENTITY_DATA_TYPES);
public static final Type<List<EntityData>> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA);
}

View File

@ -76,6 +76,7 @@ import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.Protocol1_20_2To1_20_
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.Protocol1_20_3To1_20_5;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21;
import com.viaversion.viaversion.protocols.v1_20to1_20_2.Protocol1_20To1_20_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.Protocol1_9_1To1_9_3;
import com.viaversion.viaversion.protocols.v1_9_3to1_10.Protocol1_9_3To1_10;
@ -192,6 +193,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
registerProtocol(new Protocol1_20_3To1_20_5(), ProtocolVersion.v1_20_5, ProtocolVersion.v1_20_3);
registerProtocol(new Protocol1_20_5To1_21(), ProtocolVersion.v1_21, ProtocolVersion.v1_20_5);
registerProtocol(new Protocol1_21To1_21_2(), ProtocolVersion.v1_21_2, ProtocolVersion.v1_21);
}
@Override

View File

@ -19,11 +19,11 @@ package com.viaversion.viaversion.protocols.template;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
import com.viaversion.viaversion.api.type.types.version.Types1_21;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.RecipeRewriter1_21_2;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
@ -59,19 +59,19 @@ final class BlockItemPacketRewriter1_99 extends StructuredItemRewriter<Clientbou
// Other places using item ids are: Entity data, tags, statistics, effect
// registerOpenWindow(ClientboundPackets1_21.OPEN_WINDOW); - If a new container type was added
registerCooldown(ClientboundPackets1_21.COOLDOWN);
registerSetContent1_17_1(ClientboundPackets1_21.CONTAINER_SET_CONTENT);
registerSetSlot1_17_1(ClientboundPackets1_21.CONTAINER_SET_SLOT);
registerSetContent1_21_2(ClientboundPackets1_21.CONTAINER_SET_CONTENT);
registerSetSlot1_21_2(ClientboundPackets1_21.CONTAINER_SET_SLOT);
registerAdvancements1_20_3(ClientboundPackets1_21.UPDATE_ADVANCEMENTS);
registerSetEquipment(ClientboundPackets1_21.SET_EQUIPMENT);
registerContainerClick1_17_1(ServerboundPackets1_20_5.CONTAINER_CLICK);
registerContainerClick1_21_2(ServerboundPackets1_20_5.CONTAINER_CLICK);
registerMerchantOffers1_20_5(ClientboundPackets1_21.MERCHANT_OFFERS);
registerSetCreativeModeSlot(ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT);
registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES);
registerExplosion(ClientboundPackets1_21.EXPLODE); // Rewrites the included sound and particles
registerExplosion1_21_2(ClientboundPackets1_21.EXPLODE); // Rewrites the included sound and particles
new RecipeRewriter1_20_3<>(protocol).register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES);
new RecipeRewriter1_21_2<>(protocol).register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES);
// OR do this if serialization of recipes changed and override the relevant method
// Add new serializers to RecipeRewriter, or extend the last one for changes
// new RecipeRewriter1_20_3<ClientboundPacket1_21>(this) {}.register1_20_5(ClientboundPackets1_21.DECLARE_RECIPES);
// new RecipeRewriter1_21_2<ClientboundPacket1_21>(this) {}.register1_20_5(ClientboundPackets1_21.DECLARE_RECIPES);
}
}

View File

@ -353,7 +353,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
registerClientbound(ClientboundPackets1_12_1.PLACE_GHOST_RECIPE, new PacketHandlers() {
@Override
public void register() {
map(Types.BYTE);
map(Types.UNSIGNED_BYTE);
handler(wrapper -> wrapper.write(Types.STRING, "viaversion:legacy/" + wrapper.read(Types.VAR_INT)));
}
});
@ -594,7 +594,7 @@ public class Protocol1_12_2To1_13 extends AbstractProtocol<ClientboundPackets1_1
registerServerbound(ServerboundPackets1_13.PLACE_RECIPE, new PacketHandlers() {
@Override
public void register() {
map(Types.BYTE); // Window id
map(Types.UNSIGNED_BYTE); // Window id
handler(wrapper -> {
String s = wrapper.read(Types.STRING);

View File

@ -50,8 +50,7 @@ public class RecipeRewriter1_19_3<C extends ClientboundPacketType> extends Recip
wrapper.passthrough(Types.STRING); // Group
wrapper.passthrough(Types.VAR_INT); // Crafting book category
handleIngredients(wrapper);
final Item result = rewrite(wrapper.user(), wrapper.read(itemType()));
wrapper.write(mappedItemType(), result);
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType())));
}
@Override

View File

@ -64,4 +64,4 @@ public class RecipeRewriter1_20_3<C extends ClientboundPacketType> extends Recip
protected Type<Item[]> mappedItemArrayType() {
return protocol.getItemRewriter().mappedItemArrayType();
}
}
}

View File

@ -275,7 +275,7 @@ public final class Protocol1_20_3To1_20_5 extends AbstractProtocol<ClientboundPa
.add(StructuredDataKey.CHARGED_PROJECTILES1_20_5).add(StructuredDataKey.BUNDLE_CONTENTS1_20_5).add(StructuredDataKey.POTION_CONTENTS)
.add(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS).add(StructuredDataKey.WRITABLE_BOOK_CONTENT).add(StructuredDataKey.WRITTEN_BOOK_CONTENT)
.add(StructuredDataKey.TRIM).add(StructuredDataKey.DEBUG_STICK_STATE).add(StructuredDataKey.ENTITY_DATA)
.add(StructuredDataKey.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT)
.add(StructuredDataKey.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT1_20_5)
.add(StructuredDataKey.RECIPES).add(StructuredDataKey.LODESTONE_TRACKER).add(StructuredDataKey.FIREWORK_EXPLOSION)
.add(StructuredDataKey.FIREWORKS).add(StructuredDataKey.PROFILE).add(StructuredDataKey.NOTE_BLOCK_SOUND)
.add(StructuredDataKey.BANNER_PATTERNS).add(StructuredDataKey.BASE_COLOR).add(StructuredDataKey.POT_DECORATIONS)

View File

@ -18,8 +18,9 @@
package com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPacket1_21_2;
public enum ServerboundConfigurationPackets1_20_5 implements ServerboundPacket1_20_5 {
public enum ServerboundConfigurationPackets1_20_5 implements ServerboundPacket1_20_5, ServerboundPacket1_21_2 {
CLIENT_INFORMATION, // 0x00
COOKIE_RESPONSE, // 0x01

View File

@ -62,7 +62,7 @@ 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.Instrument1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
@ -536,7 +536,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
if (instrument != null) {
final int id = Instruments1_20_3.keyToId(instrument);
if (id != -1) {
data.set(StructuredDataKey.INSTRUMENT, Holder.of(id));
data.set(StructuredDataKey.INSTRUMENT1_20_5, Holder.of(id));
}
}
@ -727,7 +727,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
soundEvent = Holder.of(instrument.getInt("sound_event"));
}
data.set(StructuredDataKey.INSTRUMENT, Holder.of(new Instrument(soundEvent, useDuration, range)));
data.set(StructuredDataKey.INSTRUMENT1_20_5, Holder.of(new Instrument1_20_5(soundEvent, useDuration, range)));
}
private void restoreFoodFromBackup(final CompoundTag food, final StructuredDataContainer data) {

View File

@ -57,7 +57,7 @@ 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.Instrument1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
@ -153,7 +153,7 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
register(StructuredDataKey.ENTITY_DATA, this::convertEntityData);
register(StructuredDataKey.BUCKET_ENTITY_DATA, this::convertBucketEntityData);
register(StructuredDataKey.BLOCK_ENTITY_DATA, this::convertBlockEntityData);
register(StructuredDataKey.INSTRUMENT, this::convertInstrument);
register(StructuredDataKey.INSTRUMENT1_20_5, this::convertInstrument);
register(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER, this::convertOminousBottleAmplifier);
register(StructuredDataKey.RECIPES, this::convertRecipes);
register(StructuredDataKey.LODESTONE_TRACKER, this::convertLodestoneTracker);
@ -745,12 +745,12 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
return convertNbtWithId(value);
}
protected Tag convertInstrument(final Holder<Instrument> value) {
protected Tag convertInstrument(final Holder<Instrument1_20_5> value) {
if (value.hasId()) {
return new StringTag(Instruments1_20_3.idToKey(value.id()));
}
final Instrument instrument = value.value();
final Instrument1_20_5 instrument = value.value();
final CompoundTag tag = new CompoundTag();
final Holder<SoundEvent> sound = instrument.soundEvent();
if (sound.hasId()) {

View File

@ -45,7 +45,7 @@ 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.Instrument1_20_5;
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;
@ -278,12 +278,12 @@ public final class StructuredDataConverter {
}
profileTag.put("Properties", propertiesTag);
});
register(StructuredDataKey.INSTRUMENT, (data, tag) -> {
register(StructuredDataKey.INSTRUMENT1_20_5, (data, tag) -> {
// Can't do anything with direct values
if (!data.hasId()) {
if (backupInconvertibleData) {
final CompoundTag backupTag = new CompoundTag();
final Instrument instrument = data.value();
final Instrument1_20_5 instrument = data.value();
if (instrument.soundEvent().hasId()) {
backupTag.putInt("sound_event", instrument.soundEvent().id());
} else {

View File

@ -204,7 +204,7 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
.add(StructuredDataKey.CHARGED_PROJECTILES1_21).add(StructuredDataKey.BUNDLE_CONTENTS1_21).add(StructuredDataKey.POTION_CONTENTS)
.add(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS).add(StructuredDataKey.WRITABLE_BOOK_CONTENT).add(StructuredDataKey.WRITTEN_BOOK_CONTENT)
.add(StructuredDataKey.TRIM).add(StructuredDataKey.DEBUG_STICK_STATE).add(StructuredDataKey.ENTITY_DATA)
.add(StructuredDataKey.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT)
.add(StructuredDataKey.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT1_20_5)
.add(StructuredDataKey.RECIPES).add(StructuredDataKey.LODESTONE_TRACKER).add(StructuredDataKey.FIREWORK_EXPLOSION)
.add(StructuredDataKey.FIREWORKS).add(StructuredDataKey.PROFILE).add(StructuredDataKey.NOTE_BLOCK_SOUND)
.add(StructuredDataKey.BANNER_PATTERNS).add(StructuredDataKey.BASE_COLOR).add(StructuredDataKey.POT_DECORATIONS)

View File

@ -18,8 +18,9 @@
package com.viaversion.viaversion.protocols.v1_20_5to1_21.packet;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2;
public enum ClientboundConfigurationPackets1_21 implements ClientboundPacket1_21 {
public enum ClientboundConfigurationPackets1_21 implements ClientboundPacket1_21, ClientboundPacket1_21_2 {
COOKIE_REQUEST, // 0x00
CUSTOM_PAYLOAD, // 0x01

View File

@ -0,0 +1,184 @@
/*
* 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.v1_21to1_21_2;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.misc.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_21;
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundConfigurationPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPacket1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPacket1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.BlockItemPacketRewriter1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.EntityPacketRewriter1_21_2;
import com.viaversion.viaversion.rewriter.AttributeRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
public final class Protocol1_21To1_21_2 extends AbstractProtocol<ClientboundPacket1_21, ClientboundPacket1_21_2, ServerboundPacket1_20_5, ServerboundPacket1_21_2> {
public static final MappingData MAPPINGS = new MappingDataBase("1.21", "1.21.2");
private final EntityPacketRewriter1_21_2 entityRewriter = new EntityPacketRewriter1_21_2(this);
private final BlockItemPacketRewriter1_21_2 itemRewriter = new BlockItemPacketRewriter1_21_2(this);
private final TagRewriter<ClientboundPacket1_21> tagRewriter = new TagRewriter<>(this);
public Protocol1_21To1_21_2() {
super(ClientboundPacket1_21.class, ClientboundPacket1_21_2.class, ServerboundPacket1_20_5.class, ServerboundPacket1_21_2.class);
}
@Override
protected void registerPackets() {
super.registerPackets();
// TODO Container ids
// TODO Ingredient now holder set???
tagRewriter.registerGeneric(ClientboundPackets1_21.UPDATE_TAGS);
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21.UPDATE_TAGS);
final SoundRewriter<ClientboundPacket1_21> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21.SOUND_ENTITY);
new StatisticsRewriter<>(this).register(ClientboundPackets1_21.AWARD_STATS);
new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21.UPDATE_ATTRIBUTES);
// Uncomment if an existing type changed serialization format. Mappings for argument type keys can also be defined in mapping files
/*new CommandRewriter1_19_4<>(this) {
@Override
public void handleArgument(final PacketWrapper wrapper, final String argumentType) {
if (argumentType.equals("minecraft:abc")) {
// New argument
wrapper.write(Types.INT, 0);
} else {
super.handleArgument(wrapper, argumentType);
}
}
}.registerDeclareCommands1_19(ClientboundPackets1_21.COMMANDS);*/
registerServerbound(ServerboundPackets1_21_2.CLIENT_INFORMATION, this::clientInformation);
registerServerbound(ServerboundConfigurationPackets1_20_5.CLIENT_INFORMATION, this::clientInformation);
cancelServerbound(ServerboundPackets1_21_2.BUNDLE_ITEM_SELECTED);
cancelServerbound(ServerboundPackets1_21_2.CLIENT_TICK_END);
}
private void clientInformation(final PacketWrapper wrapper) {
wrapper.passthrough(Types.STRING); // Locale
wrapper.passthrough(Types.BYTE); // View distance
wrapper.passthrough(Types.VAR_INT); // Chat visibility
wrapper.passthrough(Types.BOOLEAN); // Chat colors
wrapper.passthrough(Types.BYTE); // Skin parts
wrapper.passthrough(Types.VAR_INT); // Main hand
wrapper.passthrough(Types.BOOLEAN); // Text filtering enabled
wrapper.passthrough(Types.BOOLEAN); // Allow listing
wrapper.read(Types.VAR_INT);
}
@Override
protected void onMappingDataLoaded() {
Types1_21_2.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("block_marker", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.item(Types1_21_2.ITEM))
.reader("vibration", ParticleType.Readers.VIBRATION1_20_3)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);
Types1_21_2.STRUCTURED_DATA.filler(this)
.add(StructuredDataKey.CUSTOM_DATA).add(StructuredDataKey.MAX_STACK_SIZE).add(StructuredDataKey.MAX_DAMAGE)
.add(StructuredDataKey.DAMAGE).add(StructuredDataKey.UNBREAKABLE).add(StructuredDataKey.RARITY)
.add(StructuredDataKey.HIDE_TOOLTIP).add(StructuredDataKey.FIRE_RESISTANT)
.add(StructuredDataKey.CUSTOM_NAME).add(StructuredDataKey.LORE).add(StructuredDataKey.ENCHANTMENTS)
.add(StructuredDataKey.CAN_PLACE_ON).add(StructuredDataKey.CAN_BREAK)
.add(StructuredDataKey.CUSTOM_MODEL_DATA).add(StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP).add(StructuredDataKey.REPAIR_COST)
.add(StructuredDataKey.CREATIVE_SLOT_LOCK).add(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE).add(StructuredDataKey.INTANGIBLE_PROJECTILE)
.add(StructuredDataKey.STORED_ENCHANTMENTS).add(StructuredDataKey.DYED_COLOR).add(StructuredDataKey.MAP_COLOR)
.add(StructuredDataKey.MAP_ID).add(StructuredDataKey.MAP_DECORATIONS).add(StructuredDataKey.MAP_POST_PROCESSING)
.add(StructuredDataKey.CHARGED_PROJECTILES1_21_2).add(StructuredDataKey.BUNDLE_CONTENTS1_21_2).add(StructuredDataKey.POTION_CONTENTS)
.add(StructuredDataKey.SUSPICIOUS_STEW_EFFECTS).add(StructuredDataKey.WRITABLE_BOOK_CONTENT).add(StructuredDataKey.WRITTEN_BOOK_CONTENT)
.add(StructuredDataKey.TRIM).add(StructuredDataKey.DEBUG_STICK_STATE).add(StructuredDataKey.ENTITY_DATA)
.add(StructuredDataKey.BUCKET_ENTITY_DATA).add(StructuredDataKey.BLOCK_ENTITY_DATA).add(StructuredDataKey.INSTRUMENT1_21_2)
.add(StructuredDataKey.RECIPES).add(StructuredDataKey.LODESTONE_TRACKER).add(StructuredDataKey.FIREWORK_EXPLOSION)
.add(StructuredDataKey.FIREWORKS).add(StructuredDataKey.PROFILE).add(StructuredDataKey.NOTE_BLOCK_SOUND)
.add(StructuredDataKey.BANNER_PATTERNS).add(StructuredDataKey.BASE_COLOR).add(StructuredDataKey.POT_DECORATIONS)
.add(StructuredDataKey.CONTAINER1_21_2).add(StructuredDataKey.BLOCK_STATE).add(StructuredDataKey.BEES)
.add(StructuredDataKey.LOCK).add(StructuredDataKey.CONTAINER_LOOT).add(StructuredDataKey.TOOL)
.add(StructuredDataKey.ITEM_NAME).add(StructuredDataKey.OMINOUS_BOTTLE_AMPLIFIER)
.add(StructuredDataKey.FOOD1_21).add(StructuredDataKey.JUKEBOX_PLAYABLE).add(StructuredDataKey.ATTRIBUTE_MODIFIERS1_21)
.add(StructuredDataKey.REPAIRABLE).add(StructuredDataKey.ENCHANTABLE);
super.onMappingDataLoaded();
}
@Override
public void init(final UserConnection connection) {
addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_20_5.PLAYER));
}
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
@Override
public EntityPacketRewriter1_21_2 getEntityRewriter() {
return entityRewriter;
}
@Override
public BlockItemPacketRewriter1_21_2 getItemRewriter() {
return itemRewriter;
}
@Override
public TagRewriter<ClientboundPacket1_21> getTagRewriter() {
return tagRewriter;
}
@Override
protected PacketTypesProvider<ClientboundPacket1_21, ClientboundPacket1_21_2, ServerboundPacket1_20_5, ServerboundPacket1_21_2> createPacketTypesProvider() {
return new SimplePacketTypesProvider<>(
packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21.class, ClientboundConfigurationPackets1_21.class),
packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_21_2.class, ClientboundConfigurationPackets1_21.class),
packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class),
packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_21_2.class, ServerboundConfigurationPackets1_20_5.class)
);
}
}

View File

@ -0,0 +1,23 @@
/*
* 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.v1_21to1_21_2.packet;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
public interface ClientboundPacket1_21_2 extends ClientboundPacketType {
}

View File

@ -0,0 +1,159 @@
/*
* 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.v1_21to1_21_2.packet;
public enum ClientboundPackets1_21_2 implements ClientboundPacket1_21_2 {
BUNDLE_DELIMITER, // 0x00
ADD_ENTITY, // 0x01
ADD_EXPERIENCE_ORB, // 0x02
ANIMATE, // 0x03
AWARD_STATS, // 0x04
BLOCK_CHANGED_ACK, // 0x05
BLOCK_DESTRUCTION, // 0x06
BLOCK_ENTITY_DATA, // 0x07
BLOCK_EVENT, // 0x08
BLOCK_UPDATE, // 0x09
BOSS_EVENT, // 0x0A
CHANGE_DIFFICULTY, // 0x0B
CHUNK_BATCH_FINISHED, // 0x0C
CHUNK_BATCH_START, // 0x0D
CHUNKS_BIOMES, // 0x0E
CLEAR_TITLES, // 0x0F
COMMAND_SUGGESTIONS, // 0x10
COMMANDS, // 0x11
CONTAINER_CLOSE, // 0x12
CONTAINER_SET_CONTENT, // 0x13
CONTAINER_SET_DATA, // 0x14
CONTAINER_SET_SLOT, // 0x15
COOKIE_REQUEST, // 0x16
COOLDOWN, // 0x17
CUSTOM_CHAT_COMPLETIONS, // 0x18
CUSTOM_PAYLOAD, // 0x19
DAMAGE_EVENT, // 0x1A
DEBUG_SAMPLE, // 0x1B
DELETE_CHAT, // 0x1C
DISCONNECT, // 0x1D
DISGUISED_CHAT, // 0x1E
ENTITY_EVENT, // 0x1F
EXPLODE, // 0x20
FORGET_LEVEL_CHUNK, // 0x21
GAME_EVENT, // 0x22
HORSE_SCREEN_OPEN, // 0x23
HURT_ANIMATION, // 0x24
INITIALIZE_BORDER, // 0x25
KEEP_ALIVE, // 0x26
LEVEL_CHUNK_WITH_LIGHT, // 0x27
LEVEL_EVENT, // 0x28
LEVEL_PARTICLES, // 0x29
LIGHT_UPDATE, // 0x2A
LOGIN, // 0x2B
MAP_ITEM_DATA, // 0x2C
MERCHANT_OFFERS, // 0x2D
MOVE_ENTITY_POS, // 0x2E
MOVE_ENTITY_POS_ROT, // 0x2F
MOVE_MINECART_ALONG_TRACK, // 0x30
MOVE_ENTITY_ROT, // 0x31
MOVE_VEHICLE, // 0x32
OPEN_BOOK, // 0x33
OPEN_SCREEN, // 0x34
OPEN_SIGN_EDITOR, // 0x35
PING, // 0x36
PONG_RESPONSE, // 0x37
PLACE_GHOST_RECIPE, // 0x38
PLAYER_ABILITIES, // 0x39
PLAYER_CHAT, // 0x3A
PLAYER_COMBAT_END, // 0x3B
PLAYER_COMBAT_ENTER, // 0x3C
PLAYER_COMBAT_KILL, // 0x3D
PLAYER_INFO_REMOVE, // 0x3E
PLAYER_INFO_UPDATE, // 0x3F
PLAYER_LOOK_AT, // 0x40
PLAYER_POSITION, // 0x41
RECIPE, // 0x42
REMOVE_ENTITIES, // 0x43
REMOVE_MOB_EFFECT, // 0x44
RESET_SCORE, // 0x45
RESOURCE_PACK_POP, // 0x46
RESOURCE_PACK_PUSH, // 0x47
RESPAWN, // 0x48
ROTATE_HEAD, // 0x49
SECTION_BLOCKS_UPDATE, // 0x4A
SELECT_ADVANCEMENTS_TAB, // 0x4B
SERVER_DATA, // 0x4C
SET_ACTION_BAR_TEXT, // 0x4D
SET_BORDER_CENTER, // 0x4E
SET_BORDER_LERP_SIZE, // 0x4F
SET_BORDER_SIZE, // 0x50
SET_BORDER_WARNING_DELAY, // 0x51
SET_BORDER_WARNING_DISTANCE, // 0x52
SET_CAMERA, // 0x53
SET_CHUNK_CACHE_CENTER, // 0x54
SET_CHUNK_CACHE_RADIUS, // 0x55
SET_CURSOR_ITEM, // 0x56
SET_DEFAULT_SPAWN_POSITION, // 0x57
SET_DISPLAY_OBJECTIVE, // 0x58
SET_ENTITY_DATA, // 0x59
SET_ENTITY_LINK, // 0x5A
SET_ENTITY_MOTION, // 0x5B
SET_EQUIPMENT, // 0x5C
SET_EXPERIENCE, // 0x5D
SET_HEALTH, // 0x5E
SET_HELD_SLOT, // 0x5F
SET_OBJECTIVE, // 0x60
SET_PASSENGERS, // 0x61
SET_PLAYER_INVENTORY, // 0x62
SET_PLAYER_TEAM, // 0x63
SET_SCORE, // 0x64
SET_SIMULATION_DISTANCE, // 0x65
SET_SUBTITLE_TEXT, // 0x66
SET_TIME, // 0x67
SET_TITLE_TEXT, // 0x68
SET_TITLES_ANIMATION, // 0x69
SOUND_ENTITY, // 0x6A
SOUND, // 0x6B
START_CONFIGURATION, // 0x6C
STOP_SOUND, // 0x6D
STORE_COOKIE, // 0x6E
SYSTEM_CHAT, // 0x6F
TAB_LIST, // 0x70
TAG_QUERY, // 0x71
TAKE_ITEM_ENTITY, // 0x72
TELEPORT_ENTITY, // 0x73
TICKING_STATE, // 0x74
TICKING_STEP, // 0x75
TRANSFER, // 0x76
UPDATE_ADVANCEMENTS, // 0x77
UPDATE_ATTRIBUTES, // 0x78
UPDATE_MOB_EFFECT, // 0x79
UPDATE_RECIPES, // 0x7A
UPDATE_TAGS, // 0x7B
PROJECTILE_POWER, // 0x7C
CUSTOM_REPORT_DETAILS, // 0x7D
SERVER_LINKS; // 0x7E
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}

View File

@ -0,0 +1,23 @@
/*
* 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.v1_21to1_21_2.packet;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
public interface ServerboundPacket1_21_2 extends ServerboundPacketType {
}

View File

@ -0,0 +1,92 @@
/*
* 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.v1_21to1_21_2.packet;
public enum ServerboundPackets1_21_2 implements ServerboundPacket1_21_2 {
ACCEPT_TELEPORTATION, // 0x00
BLOCK_ENTITY_TAG_QUERY, // 0x01
BUNDLE_ITEM_SELECTED, // 0x02
CHANGE_DIFFICULTY, // 0x03
CHAT_ACK, // 0x04
CHAT_COMMAND, // 0x05
CHAT_COMMAND_SIGNED, // 0x06
CHAT, // 0x07
CHAT_SESSION_UPDATE, // 0x08
CHUNK_BATCH_RECEIVED, // 0x09
CLIENT_COMMAND, // 0x0A
CLIENT_TICK_END, // 0x0B
CLIENT_INFORMATION, // 0x0C
COMMAND_SUGGESTION, // 0x0D
CONFIGURATION_ACKNOWLEDGED, // 0x0E
CONTAINER_BUTTON_CLICK, // 0x0F
CONTAINER_CLICK, // 0x10
CONTAINER_CLOSE, // 0x11
CONTAINER_SLOT_STATE_CHANGED, // 0x12
COOKIE_RESPONSE, // 0x13
CUSTOM_PAYLOAD, // 0x14
DEBUG_SAMPLE_SUBSCRIPTION, // 0x15
EDIT_BOOK, // 0x16
ENTITY_TAG_QUERY, // 0x17
INTERACT, // 0x18
JIGSAW_GENERATE, // 0x19
KEEP_ALIVE, // 0x1A
LOCK_DIFFICULTY, // 0x1B
MOVE_PLAYER_POS, // 0x1C
MOVE_PLAYER_POS_ROT, // 0x1D
MOVE_PLAYER_ROT, // 0x1E
MOVE_PLAYER_STATUS_ONLY, // 0x1F
MOVE_VEHICLE, // 0x20
PADDLE_BOAT, // 0x21
PICK_ITEM, // 0x22
PING_REQUEST, // 0x23
PLACE_RECIPE, // 0x24
PLAYER_ABILITIES, // 0x25
PLAYER_ACTION, // 0x26
PLAYER_COMMAND, // 0x27
PLAYER_INPUT, // 0x28
PONG, // 0x29
RECIPE_BOOK_CHANGE_SETTINGS, // 0x2A
RECIPE_BOOK_SEEN_RECIPE, // 0x2B
RENAME_ITEM, // 0x2C
RESOURCE_PACK, // 0x2D
SEEN_ADVANCEMENTS, // 0x2E
SELECT_TRADE, // 0x2F
SET_BEACON, // 0x30
SET_CARRIED_ITEM, // 0x31
SET_COMMAND_BLOCK, // 0x32
SET_COMMAND_MINECART, // 0x33
SET_CREATIVE_MODE_SLOT, // 0x34
SET_JIGSAW_BLOCK, // 0x35
SET_STRUCTURE_BLOCK, // 0x36
SIGN_UPDATE, // 0x37
SWING, // 0x38
TELEPORT_TO_ENTITY, // 0x39
USE_ITEM_ON, // 0x3A
USE_ITEM; // 0x3B
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}

View File

@ -0,0 +1,267 @@
/*
* 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.v1_21to1_21_2.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
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.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.data.Instrument1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
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.version.Types1_21;
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPacket1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<ClientboundPacket1_21, ServerboundPacket1_21_2, Protocol1_21To1_21_2> {
public BlockItemPacketRewriter1_21_2(final Protocol1_21To1_21_2 protocol) {
super(protocol,
Types1_21.ITEM, Types1_21.ITEM_ARRAY, Types1_21_2.ITEM, Types1_21_2.ITEM_ARRAY,
Types1_21.ITEM_COST, Types1_21.OPTIONAL_ITEM_COST, Types1_21_2.ITEM_COST, Types1_21_2.OPTIONAL_ITEM_COST,
Types1_21.PARTICLE, Types1_21_2.PARTICLE
);
}
@Override
public void registerPackets() {
final BlockRewriter<ClientboundPacket1_21> blockRewriter = BlockRewriter.for1_20_2(protocol);
blockRewriter.registerBlockEvent(ClientboundPackets1_21.BLOCK_EVENT);
blockRewriter.registerBlockUpdate(ClientboundPackets1_21.BLOCK_UPDATE);
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21.SECTION_BLOCKS_UPDATE);
blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21.LEVEL_EVENT, 2001);
blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_20_2::new);
blockRewriter.registerBlockEntityData(ClientboundPackets1_21.BLOCK_ENTITY_DATA);
registerCooldown(ClientboundPackets1_21.COOLDOWN);
registerAdvancements1_20_3(ClientboundPackets1_21.UPDATE_ADVANCEMENTS);
registerSetEquipment(ClientboundPackets1_21.SET_EQUIPMENT);
registerMerchantOffers1_20_5(ClientboundPackets1_21.MERCHANT_OFFERS);
registerSetCreativeModeSlot(ServerboundPackets1_21_2.SET_CREATIVE_MODE_SLOT);
registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES);
protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_SET_CONTENT, wrapper -> {
updateContainerId(wrapper);
wrapper.passthrough(Types.VAR_INT); // State id
Item[] items = wrapper.read(itemArrayType());
wrapper.write(mappedItemArrayType(), items);
for (int i = 0; i < items.length; i++) {
items[i] = handleItemToClient(wrapper.user(), items[i]);
}
passthroughClientboundItem(wrapper);
});
protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_SET_SLOT, wrapper -> {
updateContainerId(wrapper);
wrapper.passthrough(Types.VAR_INT); // State id
wrapper.passthrough(Types.SHORT); // Slot id
passthroughClientboundItem(wrapper);
});
protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_CLOSE, this::updateContainerId);
protocol.registerClientbound(ClientboundPackets1_21.CONTAINER_SET_DATA, this::updateContainerId);
protocol.registerClientbound(ClientboundPackets1_21.HORSE_SCREEN_OPEN, this::updateContainerId);
protocol.registerClientbound(ClientboundPackets1_21.PLACE_GHOST_RECIPE, this::updateContainerId);
protocol.registerClientbound(ClientboundPackets1_21.SET_CARRIED_ITEM, ClientboundPackets1_21_2.SET_HELD_SLOT);
protocol.registerServerbound(ServerboundPackets1_21_2.CONTAINER_CLOSE, this::updateContainerIdServerbound);
protocol.registerServerbound(ServerboundPackets1_21_2.PLACE_RECIPE, this::updateContainerIdServerbound);
protocol.registerServerbound(ServerboundPackets1_21_2.CONTAINER_CLICK, wrapper -> {
updateContainerIdServerbound(wrapper);
wrapper.passthrough(Types.VAR_INT); // State id
wrapper.passthrough(Types.SHORT); // Slot
wrapper.passthrough(Types.BYTE); // Button
wrapper.passthrough(Types.VAR_INT); // Mode
final int length = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < length; i++) {
wrapper.passthrough(Types.SHORT); // Slot
passthroughServerboundItem(wrapper);
}
passthroughServerboundItem(wrapper);
});
protocol.registerClientbound(ClientboundPackets1_21.EXPLODE, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // Center X
wrapper.passthrough(Types.DOUBLE); // Center Y
wrapper.passthrough(Types.DOUBLE); // Center Z
final float power = wrapper.read(Types.FLOAT); // Power
final int blocks = wrapper.read(Types.VAR_INT);
for (int i = 0; i < blocks; i++) {
// TODO ?
wrapper.read(Types.BYTE); // Relative X
wrapper.read(Types.BYTE); // Relative Y
wrapper.read(Types.BYTE); // Relative Z
}
final float knockbackX = wrapper.read(Types.FLOAT);
final float knockbackY = wrapper.read(Types.FLOAT);
final float knockbackZ = wrapper.read(Types.FLOAT);
if (knockbackX != 0 && knockbackY != 0 && knockbackZ != 0) {
wrapper.write(Types.BOOLEAN, true);
wrapper.write(Types.DOUBLE, (double) knockbackX);
wrapper.write(Types.DOUBLE, (double) knockbackY);
wrapper.write(Types.DOUBLE, (double) knockbackZ);
} else {
wrapper.write(Types.BOOLEAN, false);
}
wrapper.read(Types.VAR_INT); // Block interaction type
final Particle smallExplosionParticle = wrapper.read(Types1_21.PARTICLE);
final Particle largeExplosionParticle = wrapper.read(Types1_21.PARTICLE);
if (power >= 2.0F && blocks != 0) {
rewriteParticle(wrapper.user(), largeExplosionParticle);
wrapper.write(Types1_21_2.PARTICLE, largeExplosionParticle);
} else {
rewriteParticle(wrapper.user(), smallExplosionParticle);
wrapper.write(Types1_21_2.PARTICLE, smallExplosionParticle);
}
new SoundRewriter<>(protocol).soundHolderHandler().handle(wrapper);
});
new RecipeRewriter1_20_3<>(protocol) {
@Override
protected void handleIngredient(final PacketWrapper wrapper) {
wrapper.write(Types.HOLDER_SET, ingredient(wrapper));
}
@Override
public void handleCraftingShaped(final PacketWrapper wrapper) {
wrapper.passthrough(Types.STRING); // Group
wrapper.passthrough(Types.VAR_INT); // Crafting book category
final int width = wrapper.passthrough(Types.VAR_INT);
final int height = wrapper.passthrough(Types.VAR_INT);
final int ingredients = width * height;
wrapper.write(Types.VAR_INT, ingredients);
for (int i = 0; i < ingredients; i++) {
wrapper.write(Types.HOLDER_SET, ingredient(wrapper));
}
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); // Result
wrapper.passthrough(Types.BOOLEAN); // Show notification
}
@Override
public void handleCraftingShapeless(final PacketWrapper wrapper) {
wrapper.passthrough(Types.STRING); // Group
wrapper.passthrough(Types.VAR_INT); // Crafting book category
final int ingredients = wrapper.read(Types.VAR_INT);
final HolderSet[] ingredient = new HolderSet[ingredients];
for (int i = 0; i < ingredients; i++) {
ingredient[i] = ingredient(wrapper);
}
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType())));
// Also moved below here
wrapper.write(Types.VAR_INT, ingredients);
for (final HolderSet item : ingredient) {
wrapper.write(Types.HOLDER_SET, item);
}
}
private HolderSet ingredient(final PacketWrapper wrapper) {
final Item[] items = wrapper.read(itemArrayType());
final int[] ids = new int[items.length];
for (int i = 0; i < items.length; i++) {
final Item item = rewrite(wrapper.user(), items[i]);
ids[i] = item.identifier();
}
return HolderSet.of(ids);
}
@Override
public void handleRecipeType(final PacketWrapper wrapper, final String type) {
if (type.equals("crafting_special_suspiciousstew")) {
wrapper.read(Types.VAR_INT); // Crafting book category
} else {
super.handleRecipeType(wrapper, type);
}
}
}.register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES);
}
@Override
public Item handleItemToClient(final UserConnection connection, final Item item) {
super.handleItemToClient(connection, item);
updateItemData(item);
return item;
}
@Override
public Item handleItemToServer(final UserConnection connection, final Item item) {
super.handleItemToServer(connection, item);
downgradeItemData(item);
return item;
}
private void updateContainerId(final PacketWrapper wrapper) {
final int containerId = wrapper.read(Types.UNSIGNED_BYTE).intValue();
wrapper.write(Types.VAR_INT, containerId);
}
private void updateContainerIdServerbound(final PacketWrapper wrapper) {
final int containerId = wrapper.read(Types.VAR_INT);
wrapper.write(Types.UNSIGNED_BYTE, (short) containerId);
}
public static void updateItemData(final Item item) {
final StructuredDataContainer dataContainer = item.dataContainer();
dataContainer.replace(StructuredDataKey.INSTRUMENT1_20_5, StructuredDataKey.INSTRUMENT1_21_2, instrument -> {
if (instrument.hasId()) {
return Holder.of(instrument.id());
}
final Instrument1_20_5 value = instrument.value();
return Holder.of(new Instrument1_21_2(value.soundEvent(), value.useDuration(), value.range(), null));
});
dataContainer.replaceKey(StructuredDataKey.CONTAINER1_21, StructuredDataKey.CONTAINER1_21_2);
dataContainer.replaceKey(StructuredDataKey.CHARGED_PROJECTILES1_21, StructuredDataKey.CHARGED_PROJECTILES1_21_2);
dataContainer.replaceKey(StructuredDataKey.BUNDLE_CONTENTS1_21, StructuredDataKey.BUNDLE_CONTENTS1_21_2);
}
public static void downgradeItemData(final Item item) {
final StructuredDataContainer dataContainer = item.dataContainer();
dataContainer.replace(StructuredDataKey.INSTRUMENT1_21_2, StructuredDataKey.INSTRUMENT1_20_5, instrument -> {
if (instrument.hasId()) {
return Holder.of(instrument.id());
}
final Instrument1_21_2 value = instrument.value();
return Holder.of(new Instrument1_20_5(value.soundEvent(), (int) value.useDuration(), value.range()));
});
dataContainer.replaceKey(StructuredDataKey.CONTAINER1_21_2, StructuredDataKey.CONTAINER1_21);
dataContainer.replaceKey(StructuredDataKey.CHARGED_PROJECTILES1_21_2, StructuredDataKey.CHARGED_PROJECTILES1_21);
dataContainer.replaceKey(StructuredDataKey.BUNDLE_CONTENTS1_21_2, StructuredDataKey.BUNDLE_CONTENTS1_21);
dataContainer.remove(StructuredDataKey.REPAIRABLE);
dataContainer.remove(StructuredDataKey.ENCHANTABLE);
}
}

View File

@ -0,0 +1,227 @@
/*
* 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.v1_21to1_21_2.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_21;
import com.viaversion.viaversion.api.type.types.version.Types1_21_2;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.Protocol1_21To1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.TagUtil;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
public final class EntityPacketRewriter1_21_2 extends EntityRewriter<ClientboundPacket1_21, Protocol1_21To1_21_2> {
public EntityPacketRewriter1_21_2(final Protocol1_21To1_21_2 protocol) {
super(protocol);
}
@Override
public void registerPackets() {
registerTrackerWithData1_19(ClientboundPackets1_21.ADD_ENTITY, EntityTypes1_20_5.FALLING_BLOCK);
registerSetEntityData(ClientboundPackets1_21.SET_ENTITY_DATA, Types1_21.ENTITY_DATA_LIST, Types1_21_2.ENTITY_DATA_LIST);
registerRemoveEntities(ClientboundPackets1_21.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, wrapper -> {
final String registryKey = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING));
RegistryEntry[] entries = wrapper.read(Types.REGISTRY_ENTRY_ARRAY);
if (registryKey.equals("enchantment")) {
for (final RegistryEntry entry : entries) {
if (entry.tag() == null) {
continue;
}
final CompoundTag effects = ((CompoundTag) entry.tag()).getCompoundTag("effects");
if (effects != null) {
updateLocationChangedAttributes(effects);
updateAttributesFields(effects);
}
}
} else if (registryKey.equals("damage_type")) {
// Add new damage types
final int length = entries.length;
entries = Arrays.copyOf(entries, length + 2);
final CompoundTag enderpearlData = new CompoundTag();
enderpearlData.putString("scaling", "when_caused_by_living_non_player");
enderpearlData.putString("message_id", "fall");
enderpearlData.putFloat("exhaustion", 0.0F);
entries[length] = new RegistryEntry("minecraft:ender_pearl", enderpearlData);
final CompoundTag maceSmashData = new CompoundTag();
maceSmashData.putString("scaling", "when_caused_by_living_non_player");
maceSmashData.putString("message_id", "mace_smash");
maceSmashData.putFloat("exhaustion", 0.1F);
entries[length + 1] = new RegistryEntry("minecraft:mace_smash", maceSmashData);
}
wrapper.write(Types.REGISTRY_ENTRY_ARRAY, entries);
handleRegistryData1_20_5(wrapper.user(), registryKey, entries);
});
protocol.registerClientbound(ClientboundPackets1_21.LOGIN, new PacketHandlers() {
@Override
public void register() {
map(Types.INT); // Entity id
map(Types.BOOLEAN); // Hardcore
map(Types.STRING_ARRAY); // World List
map(Types.VAR_INT); // Max players
map(Types.VAR_INT); // View distance
map(Types.VAR_INT); // Simulation distance
map(Types.BOOLEAN); // Reduced debug info
map(Types.BOOLEAN); // Show death screen
map(Types.BOOLEAN); // Limited crafting
map(Types.VAR_INT); // Dimension id
map(Types.STRING); // World
map(Types.LONG); // Seed
map(Types.BYTE); // Gamemode
map(Types.BYTE); // Previous gamemode
map(Types.BOOLEAN); // Debug
map(Types.BOOLEAN); // Flat
map(Types.OPTIONAL_GLOBAL_POSITION); // Last death location
map(Types.VAR_INT); // Portal cooldown
handler(worldDataTrackerHandlerByKey1_20_5(3));
handler(playerTrackerHandler());
create(Types.VAR_INT, 64); // Sea level, was hardcoded at 64 before
}
});
protocol.registerClientbound(ClientboundPackets1_21.RESPAWN, wrapper -> {
final int dimensionId = wrapper.passthrough(Types.VAR_INT);
final String world = wrapper.passthrough(Types.STRING);
wrapper.passthrough(Types.LONG); // Seed
wrapper.passthrough(Types.BYTE); // Gamemode
wrapper.passthrough(Types.BYTE); // Previous gamemode
wrapper.passthrough(Types.BOOLEAN); // Debug
wrapper.passthrough(Types.BOOLEAN); // Flat
wrapper.passthrough(Types.OPTIONAL_GLOBAL_POSITION); // Last death location
wrapper.passthrough(Types.VAR_INT); // Portal cooldown
wrapper.write(Types.VAR_INT, 64); // Sea level
trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world);
});
protocol.appendServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_POS, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
readOnGround(wrapper);
});
protocol.appendServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_POS_ROT, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
wrapper.passthrough(Types.FLOAT); // Yaw
wrapper.passthrough(Types.FLOAT); // Pitch
readOnGround(wrapper);
});
protocol.appendServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_ROT, wrapper -> {
wrapper.passthrough(Types.FLOAT); // Yaw
wrapper.passthrough(Types.FLOAT); // Pitch
readOnGround(wrapper);
});
protocol.appendServerbound(ServerboundPackets1_21_2.MOVE_PLAYER_STATUS_ONLY, this::readOnGround);
}
private void updateAttributesFields(final CompoundTag effects) {
final ListTag<CompoundTag> attributesList = TagUtil.getNamespacedCompoundTagList(effects, "attributes");
if (attributesList == null) {
return;
}
for (final CompoundTag attributeData : attributesList) {
updateAttributeField(attributeData);
}
}
private void updateLocationChangedAttributes(final CompoundTag effects) {
final ListTag<CompoundTag> locationChanged = TagUtil.getNamespacedCompoundTagList(effects, "location_changed");
if (locationChanged == null) {
return;
}
for (final CompoundTag data : locationChanged) {
final CompoundTag effect = data.getCompoundTag("effect");
if (effect != null) {
updateAttributeField(effect);
}
}
}
private void updateAttributeField(final CompoundTag attributeData) {
final StringTag attributeTag = attributeData.getStringTag("attribute");
if (attributeTag == null) {
return;
}
final String attribute = Key.stripMinecraftNamespace(attributeTag.getValue());
final int firstSeparator = attribute.indexOf('.');
if (firstSeparator == -1) {
return;
}
// Remove prefix from attributes
final String prefix = attribute.substring(0, firstSeparator);
if (prefix.equals("generic") || prefix.equals("player") || prefix.equals("zombie")) {
attributeTag.setValue(attribute.substring(firstSeparator + 1));
}
}
private void readOnGround(final PacketWrapper wrapper) {
final short data = wrapper.read(Types.UNSIGNED_BYTE);
wrapper.write(Types.BOOLEAN, (data & 1) != 0); // On ground, ignoring horizontal collision data
}
@Override
protected void registerRewrites() {
filter().mapDataType(Types1_21_2.ENTITY_DATA_TYPES::byId);
registerEntityDataTypeHandler(
Types1_21_2.ENTITY_DATA_TYPES.itemType,
Types1_21_2.ENTITY_DATA_TYPES.blockStateType,
Types1_21_2.ENTITY_DATA_TYPES.optionalBlockStateType,
Types1_21_2.ENTITY_DATA_TYPES.particleType,
Types1_21_2.ENTITY_DATA_TYPES.particlesType,
Types1_21_2.ENTITY_DATA_TYPES.componentType,
Types1_21_2.ENTITY_DATA_TYPES.optionalComponentType
);
registerBlockStateHandler(EntityTypes1_20_5.ABSTRACT_MINECART, 11); // Data type
filter().type(EntityTypes1_20_5.SALMON).addIndex(17);
}
@Override
public EntityType typeFromId(final int type) {
return EntityTypes1_20_5.getTypeFromId(type);
}
}

View File

@ -0,0 +1,78 @@
/*
* 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.v1_21to1_21_2.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3;
public class RecipeRewriter1_21_2<C extends ClientboundPacketType> extends RecipeRewriter1_20_3<C> {
public RecipeRewriter1_21_2(final Protocol<C, ?, ?, ?> protocol) {
super(protocol);
}
@Override
public void handleCraftingShaped(final PacketWrapper wrapper) {
wrapper.passthrough(Types.STRING); // Group
wrapper.passthrough(Types.VAR_INT); // Crafting book category
wrapper.passthrough(Types.VAR_INT); // Width
wrapper.passthrough(Types.VAR_INT); // Height
final int ingredients = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < ingredients; i++) {
handleIngredient(wrapper);
}
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); // Result
wrapper.passthrough(Types.BOOLEAN); // Show notification
}
@Override
public void handleCraftingShapeless(final PacketWrapper wrapper) {
wrapper.passthrough(Types.STRING); // Group
wrapper.passthrough(Types.VAR_INT); // Crafting book category
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); // Result
handleIngredients(wrapper);
}
@Override
protected void handleIngredient(final PacketWrapper wrapper) {
final HolderSet items = wrapper.passthrough(Types.HOLDER_SET);
if (items.hasTagKey()) {
return;
}
final int[] ids = items.ids();
for (int i = 0; i < ids.length; i++) {
ids[i] = rewriteItemId(wrapper.user(), ids[i]);
}
}
protected int rewriteItemId(final UserConnection connection, final int id) {
if (protocol.getMappingData() != null && protocol.getMappingData().getItemMappings() != null) {
return protocol.getMappingData().getItemMappings().getNewIdOrDefault(id, id);
}
return id;
}
}

View File

@ -105,30 +105,30 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
}
public void registerSetContent1_17_1(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.UNSIGNED_BYTE); // Window id
map(Types.VAR_INT); // State id
handler(wrapper -> {
Item[] items = wrapper.passthroughAndMap(itemArrayType, mappedItemArrayType);
for (int i = 0; i < items.length; i++) {
items[i] = handleItemToClient(wrapper.user(), items[i]);
}
registerSetContent1_17_1(packetType, Types.UNSIGNED_BYTE);
}
handleClientboundItem(wrapper);
});
public void registerSetContent1_21_2(C packetType) {
registerSetContent1_17_1(packetType, Types.VAR_INT);
}
private void registerSetContent1_17_1(C packetType, Type<? extends Number> containerIdType) {
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(containerIdType); // Container id
wrapper.passthrough(Types.VAR_INT); // State id
Item[] items = wrapper.passthroughAndMap(itemArrayType, mappedItemArrayType);
for (int i = 0; i < items.length; i++) {
items[i] = handleItemToClient(wrapper.user(), items[i]);
}
passthroughClientboundItem(wrapper);
});
}
public void registerOpenScreen(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // Container id
handler(wrapper -> handleMenuType(wrapper));
}
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Container id
handleMenuType(wrapper);
});
}
@ -147,22 +147,27 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.UNSIGNED_BYTE); // Window id
map(Types.UNSIGNED_BYTE); // Container id
map(Types.SHORT); // Slot id
handler(wrapper -> handleClientboundItem(wrapper));
handler(wrapper -> passthroughClientboundItem(wrapper));
}
});
}
public void registerSetSlot1_17_1(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.UNSIGNED_BYTE); // Window id
map(Types.VAR_INT); // State id
map(Types.SHORT); // Slot id
handler(wrapper -> handleClientboundItem(wrapper));
}
registerSetSlot1_17_1(packetType, Types.UNSIGNED_BYTE);
}
public void registerSetSlot1_21_2(C packetType) {
registerSetSlot1_17_1(packetType, Types.VAR_INT);
}
private void registerSetSlot1_17_1(C packetType, Type<? extends Number> containerIdType) {
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(containerIdType); // Container id
wrapper.passthrough(Types.VAR_INT); // State id
wrapper.passthrough(Types.SHORT); // Slot id
passthroughClientboundItem(wrapper);
});
}
@ -173,7 +178,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
public void register() {
map(Types.VAR_INT); // Entity ID
map(Types.VAR_INT); // Slot ID
handler(wrapper -> handleClientboundItem(wrapper));
handler(wrapper -> passthroughClientboundItem(wrapper));
}
});
}
@ -190,7 +195,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
do {
slot = wrapper.passthrough(Types.BYTE);
// & 0x7F into an extra variable if slot is needed
handleClientboundItem(wrapper);
passthroughClientboundItem(wrapper);
} while (slot < 0);
});
}
@ -202,7 +207,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
@Override
public void register() {
map(Types.SHORT); // 0 - Slot
handler(wrapper -> handleServerboundItem(wrapper));
handler(wrapper -> passthroughServerboundItem(wrapper));
}
});
}
@ -211,38 +216,41 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
protocol.registerServerbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.UNSIGNED_BYTE); // 0 - Window ID
map(Types.UNSIGNED_BYTE); // 0 - Container ID
map(Types.SHORT); // 1 - Slot
map(Types.BYTE); // 2 - Button
map(Types.SHORT); // 3 - Action number
map(Types.VAR_INT); // 4 - Mode
handler(wrapper -> handleServerboundItem(wrapper));
handler(wrapper -> passthroughServerboundItem(wrapper));
}
});
}
public void registerContainerClick1_17_1(S packetType) {
protocol.registerServerbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Types.UNSIGNED_BYTE); // Window Id
map(Types.VAR_INT); // State id
map(Types.SHORT); // Slot
map(Types.BYTE); // Button
map(Types.VAR_INT); // Mode
registerContainerClick1_17_1(packetType, Types.UNSIGNED_BYTE);
}
handler(wrapper -> {
// Affected items
int length = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < length; i++) {
wrapper.passthrough(Types.SHORT); // Slot
handleServerboundItem(wrapper);
}
public void registerContainerClick1_21_2(S packetType) {
registerContainerClick1_17_1(packetType, Types.VAR_INT);
}
// Carried item
handleServerboundItem(wrapper);
});
public void registerContainerClick1_17_1(S packetType, Type<? extends Number> containerIdType) {
protocol.registerServerbound(packetType, wrapper -> {
wrapper.passthrough(containerIdType); // Container id
wrapper.passthrough(Types.VAR_INT); // State id
wrapper.passthrough(Types.SHORT); // Slot
wrapper.passthrough(Types.BYTE); // Button
wrapper.passthrough(Types.VAR_INT); // Mode
// Affected items
final int length = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < length; i++) {
wrapper.passthrough(Types.SHORT); // Slot
passthroughServerboundItem(wrapper);
}
// Carried item
passthroughServerboundItem(wrapper);
});
}
@ -274,11 +282,11 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
final int size = wrapper.passthrough(Types.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
handleClientboundItem(wrapper); // Input Item
handleClientboundItem(wrapper); // Output Item
passthroughClientboundItem(wrapper); // Input Item
passthroughClientboundItem(wrapper); // Output Item
if (wrapper.passthrough(Types.BOOLEAN)) {
handleClientboundItem(wrapper); // Second Item
passthroughClientboundItem(wrapper); // Second Item
}
wrapper.passthrough(Types.BOOLEAN); // Trade disabled
@ -294,11 +302,11 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
wrapper.passthrough(Types.VAR_INT);
int size = wrapper.passthrough(Types.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
handleClientboundItem(wrapper); // Input
handleClientboundItem(wrapper); // Output
passthroughClientboundItem(wrapper); // Input
passthroughClientboundItem(wrapper); // Output
if (wrapper.passthrough(Types.BOOLEAN)) { // Has second item
handleClientboundItem(wrapper); // Second item
passthroughClientboundItem(wrapper); // Second item
}
wrapper.passthrough(Types.BOOLEAN); // Trade disabled
@ -319,9 +327,9 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
wrapper.passthrough(Types.VAR_INT); // Container id
int size = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < size; i++) {
handleClientboundItem(wrapper); // Input
handleClientboundItem(wrapper); // Output
handleClientboundItem(wrapper); // Second item
passthroughClientboundItem(wrapper); // Input
passthroughClientboundItem(wrapper); // Output
passthroughClientboundItem(wrapper); // Second item
wrapper.passthrough(Types.BOOLEAN); // Trade disabled
wrapper.passthrough(Types.INT); // Number of tools uses
@ -344,7 +352,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
final Item input = wrapper.read(itemCostType);
wrapper.write(mappedItemCostType, handleItemToClient(wrapper.user(), input));
handleClientboundItem(wrapper); // Result
passthroughClientboundItem(wrapper); // Result
Item secondInput = wrapper.read(optionalItemCostType);
if (secondInput != null) {
@ -382,7 +390,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
componentRewriter.processText(wrapper.user(), description);
}
handleClientboundItem(wrapper); // Icon
passthroughClientboundItem(wrapper); // Icon
wrapper.passthrough(Types.VAR_INT); // Frame type
int flags = wrapper.passthrough(Types.INT); // Flags
if ((flags & 1) != 0) {
@ -420,7 +428,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
componentRewriter.processTag(wrapper.user(), description);
}
handleClientboundItem(wrapper); // Icon
passthroughClientboundItem(wrapper); // Icon
wrapper.passthrough(Types.VAR_INT); // Frame type
int flags = wrapper.passthrough(Types.INT); // Flags
if ((flags & 1) != 0) {
@ -549,6 +557,27 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
});
}
public void registerExplosion1_21_2(C packetType) {
final SoundRewriter<C> soundRewriter = new SoundRewriter<>(protocol);
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
wrapper.passthrough(Types.DOUBLE); // Knockback X
wrapper.passthrough(Types.DOUBLE); // Knockback Y
wrapper.passthrough(Types.DOUBLE); // Knockback Z
final Particle smallExplosionParticle = wrapper.read(particleType);
final Particle largeExplosionParticle = wrapper.read(particleType);
wrapper.write(mappedParticleType, smallExplosionParticle);
wrapper.write(mappedParticleType, largeExplosionParticle);
rewriteParticle(wrapper.user(), smallExplosionParticle);
rewriteParticle(wrapper.user(), largeExplosionParticle);
soundRewriter.soundHolderHandler().handle(wrapper);
});
}
public PacketHandler levelParticlesHandler() {
return levelParticlesHandler(Types.INT);
}
@ -565,7 +594,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
int data = wrapper.read(Types.VAR_INT);
wrapper.write(Types.VAR_INT, protocol.getMappingData().getNewBlockStateId(data));
} else if (mappings.isItemParticle(id)) {
handleClientboundItem(wrapper);
passthroughClientboundItem(wrapper);
}
int mappedId = protocol.getMappingData().getNewParticleId(id);
@ -575,12 +604,12 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
};
}
private void handleClientboundItem(final PacketWrapper wrapper) {
protected void passthroughClientboundItem(final PacketWrapper wrapper) {
final Item item = handleItemToClient(wrapper.user(), wrapper.read(itemType));
wrapper.write(mappedItemType, item);
}
private void handleServerboundItem(final PacketWrapper wrapper) {
protected void passthroughServerboundItem(final PacketWrapper wrapper) {
final Item item = handleItemToServer(wrapper.user(), wrapper.read(mappedItemType));
wrapper.write(itemType, item);
}

View File

@ -18,6 +18,7 @@
package com.viaversion.viaversion.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
@ -80,13 +81,22 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
public void register1_20_5(C packetType) {
protocol.registerClientbound(packetType, wrapper -> {
int size = wrapper.passthrough(Types.VAR_INT);
final int size = wrapper.passthrough(Types.VAR_INT);
int newSize = size;
for (int i = 0; i < size; i++) {
wrapper.passthrough(Types.STRING); // Recipe Identifier
final String recipeIdentifier = wrapper.read(Types.STRING);
final int typeId = wrapper.passthrough(Types.VAR_INT);
final String type = protocol.getMappingData().getRecipeSerializerMappings().identifier(typeId);
handleRecipeType(wrapper, type);
final FullMappings recipeSerializerMappings = protocol.getMappingData().getRecipeSerializerMappings();
final int typeId = wrapper.read(Types.VAR_INT);
final int mappedId = recipeSerializerMappings.getNewId(typeId);
if (mappedId != -1) {
wrapper.write(Types.STRING, recipeIdentifier);
wrapper.write(Types.VAR_INT, mappedId);
} else {
wrapper.set(Types.VAR_INT, 0, --newSize);
}
handleRecipeType(wrapper, Key.stripMinecraftNamespace(recipeSerializerMappings.identifier(typeId))); // Use the original
}
});
}