From a54d8c681fe82eaa0e44e29888578597fa968c1b Mon Sep 17 00:00:00 2001 From: Gero Date: Tue, 19 Dec 2023 12:13:11 +0100 Subject: [PATCH] Support conversion of mixed json array components --- .../protocol/packet/chat/ComponentHolder.java | 47 ++++++++++--------- .../proxy/component/ComponentHolderTest.java | 39 +++++++++++++++ 2 files changed, 64 insertions(+), 22 deletions(-) create mode 100644 proxy/src/test/java/com/velocitypowered/proxy/component/ComponentHolderTest.java diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ComponentHolder.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ComponentHolder.java index debbb8348..246676154 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ComponentHolder.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ComponentHolder.java @@ -28,6 +28,7 @@ import io.netty.buffer.ByteBuf; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.BinaryTagIO; import net.kyori.adventure.nbt.BinaryTagType; +import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.ByteArrayBinaryTag; import net.kyori.adventure.nbt.ByteBinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; @@ -153,8 +154,19 @@ public class ComponentHolder { return ListBinaryTag.empty(); } - BinaryTag listTag; - BinaryTagType listType = serialize(jsonArray.get(0)).type(); + List tagItems = new ArrayList<>(jsonArray.size()); + BinaryTagType listType = null; + + for (JsonElement jsonEl : jsonArray) { + BinaryTag tag = serialize(jsonEl); + tagItems.add(tag); + + if (listType == null) { + listType = tag.type(); + } else if (listType != tag.type()) { + listType = BinaryTagTypes.COMPOUND; + } + } switch (listType.id()) { case 1://BinaryTagTypes.BYTE: @@ -163,42 +175,33 @@ public class ComponentHolder { bytes[i] = (Byte) jsonArray.get(i).getAsNumber(); } - listTag = ByteArrayBinaryTag.byteArrayBinaryTag(bytes); - break; + return ByteArrayBinaryTag.byteArrayBinaryTag(bytes); case 3://BinaryTagTypes.INT: int[] ints = new int[jsonArray.size()]; for (int i = 0; i < ints.length; i++) { ints[i] = (Integer) jsonArray.get(i).getAsNumber(); } - listTag = IntArrayBinaryTag.intArrayBinaryTag(ints); - break; + return IntArrayBinaryTag.intArrayBinaryTag(ints); case 4://BinaryTagTypes.LONG: long[] longs = new long[jsonArray.size()]; for (int i = 0; i < longs.length; i++) { longs[i] = (Long) jsonArray.get(i).getAsNumber(); } - listTag = LongArrayBinaryTag.longArrayBinaryTag(longs); - break; - default: - List tagItems = new ArrayList<>(jsonArray.size()); - - for (JsonElement jsonEl : jsonArray) { - BinaryTag subTag = serialize(jsonEl); - - if (subTag.type() != listType) { - throw new IllegalArgumentException("Cannot convert mixed JsonArray to Tag"); + return LongArrayBinaryTag.longArrayBinaryTag(longs); + case 10://BinaryTagTypes.COMPOUND: + tagItems.replaceAll(tag -> { + if (tag.type() == BinaryTagTypes.COMPOUND) { + return tag; + } else { + return CompoundBinaryTag.builder().put("", tag).build(); } - - tagItems.add(subTag); - } - - listTag = ListBinaryTag.listBinaryTag(listType, tagItems); + }); break; } - return listTag; + return ListBinaryTag.listBinaryTag(listType, tagItems); } return EndBinaryTag.endBinaryTag(); diff --git a/proxy/src/test/java/com/velocitypowered/proxy/component/ComponentHolderTest.java b/proxy/src/test/java/com/velocitypowered/proxy/component/ComponentHolderTest.java new file mode 100644 index 000000000..9bab68a01 --- /dev/null +++ b/proxy/src/test/java/com/velocitypowered/proxy/component/ComponentHolderTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021-2023 Velocity 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 . + */ + +package com.velocitypowered.proxy.component; + +import com.velocitypowered.api.network.ProtocolVersion; +import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.junit.jupiter.api.Test; + +/** + * ComponentHolder tests. + */ +public class ComponentHolderTest { + + @Test + void testJsonToBinary() { + Component component = MiniMessage.miniMessage().deserialize( + "<#09add3>A Velocity <#09add3>Server"); + ComponentHolder holder = new ComponentHolder(ProtocolVersion.MINECRAFT_1_20_3, component); + holder.getJson(); + holder.getBinaryTag(); + } +}