From 5d0846abe2c6f032f261f6ca6495384e4fafe3c1 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Wed, 29 May 2024 18:19:48 +0200 Subject: [PATCH] Handle chat and horse container changes --- .../api/minecraft/item/data/ChatType.java | 68 +++++++++++++++++++ .../v1_20_5to1_21/Protocol1_20_5To1_21.java | 36 ++++++++++ .../rewriter/BlockItemPacketRewriter1_21.java | 8 +++ 3 files changed, 112 insertions(+) create mode 100644 api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ChatType.java diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ChatType.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ChatType.java new file mode 100644 index 000000000..eb062798e --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/item/data/ChatType.java @@ -0,0 +1,68 @@ +/* + * 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.type.Type; +import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.api.type.types.misc.HolderType; +import io.netty.buffer.ByteBuf; + +public record ChatType(ChatTypeDecoration chatDecoration, ChatTypeDecoration narrationDecoration) { + + public static final HolderType TYPE = new HolderType<>() { + @Override + public ChatType readDirect(final ByteBuf buffer) { + final ChatTypeDecoration chatDecoration = ChatTypeDecoration.TYPE.read(buffer); + final ChatTypeDecoration narrationDecoration = ChatTypeDecoration.TYPE.read(buffer); + return new ChatType(chatDecoration, narrationDecoration); + } + + @Override + public void writeDirect(final ByteBuf buffer, final ChatType value) { + ChatTypeDecoration.TYPE.write(buffer, value.chatDecoration()); + ChatTypeDecoration.TYPE.write(buffer, value.narrationDecoration()); + } + }; + + public record ChatTypeDecoration(String translationKey, int[] parameters, Tag style) { + + public static final Type TYPE = new Type<>(ChatTypeDecoration.class) { + + @Override + public ChatTypeDecoration read(final ByteBuf buffer) { + final String translationKey = Types.STRING.read(buffer); + final int[] parameters = Types.INT_ARRAY_PRIMITIVE.read(buffer); + final Tag style = Types.TAG.read(buffer); + return new ChatTypeDecoration(translationKey, parameters, style); + } + + @Override + public void write(final ByteBuf buffer, final ChatTypeDecoration value) { + Types.STRING.write(buffer, value.translationKey()); + Types.INT_ARRAY_PRIMITIVE.write(buffer, value.parameters()); + Types.TAG.write(buffer, value.style()); + } + }; + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/Protocol1_20_5To1_21.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/Protocol1_20_5To1_21.java index c9cfeff96..52cb43ab9 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/Protocol1_20_5To1_21.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/Protocol1_20_5To1_21.java @@ -18,8 +18,10 @@ package com.viaversion.viaversion.protocols.v1_20_5to1_21; import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.minecraft.Holder; import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5; +import com.viaversion.viaversion.api.minecraft.item.data.ChatType; import com.viaversion.viaversion.api.protocol.AbstractProtocol; import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider; import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider; @@ -74,6 +76,40 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol(this).register(ClientboundPackets1_20_5.AWARD_STATS); + registerClientbound(ClientboundPackets1_20_5.DISGUISED_CHAT, wrapper -> { + wrapper.passthrough(Types.TAG); // Message + + // Holder time + final int chatType = wrapper.read(Types.VAR_INT); + wrapper.write(ChatType.TYPE, Holder.of(chatType)); + }); + registerClientbound(ClientboundPackets1_20_5.PLAYER_CHAT, wrapper -> { + wrapper.passthrough(Types.UUID); // Sender + wrapper.passthrough(Types.VAR_INT); // Index + wrapper.passthrough(Types.OPTIONAL_SIGNATURE_BYTES); // Signature + wrapper.passthrough(Types.STRING); // Plain content + wrapper.passthrough(Types.LONG); // Timestamp + wrapper.passthrough(Types.LONG); // Salt + + final int lastSeen = wrapper.passthrough(Types.VAR_INT); + for (int i = 0; i < lastSeen; i++) { + final int index = wrapper.passthrough(Types.VAR_INT); + if (index == 0) { + wrapper.passthrough(Types.SIGNATURE_BYTES); + } + } + + wrapper.passthrough(Types.OPTIONAL_TAG); // Unsigned content + + final int filterMaskType = wrapper.passthrough(Types.VAR_INT); + if (filterMaskType == 2) { + wrapper.passthrough(Types.LONG_ARRAY_PRIMITIVE); // Mask + } + + final int chatType = wrapper.read(Types.VAR_INT); + wrapper.write(ChatType.TYPE, Holder.of(chatType)); + }); + registerClientbound(ClientboundPackets1_20_5.UPDATE_ATTRIBUTES, wrapper -> { wrapper.passthrough(Types.VAR_INT); // Entity ID diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java index 53c50dcc6..7e6097655 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_5to1_21/rewriter/BlockItemPacketRewriter1_21.java @@ -69,6 +69,14 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter { + wrapper.passthrough(Types.UNSIGNED_BYTE); // Container id + + // Now written as columns + final int size = wrapper.read(Types.VAR_INT); + wrapper.write(Types.VAR_INT, Math.max(1, (size - 1) / 3)); + }); + protocol.registerClientbound(ClientboundPackets1_20_5.LEVEL_EVENT, wrapper -> { final int id = wrapper.passthrough(Types.INT); wrapper.passthrough(Types.BLOCK_POSITION1_14);