Some more pre-sizing

This commit is contained in:
Nassim Jahnke 2024-11-11 14:24:58 +01:00
parent 6553fc9ae9
commit 04e936d487
No known key found for this signature in database
GPG Key ID: EF6771C01F6EF02F
12 changed files with 99 additions and 19 deletions

View File

@ -59,6 +59,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.UseCooldown;
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.ArrayType;
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;
@ -74,7 +75,7 @@ public record StructuredDataKey<T>(String identifier, Type<T> type) {
public static final StructuredDataKey<Tag> CUSTOM_NAME = new StructuredDataKey<>("custom_name", Types.TAG);
public static final StructuredDataKey<Tag> ITEM_NAME = new StructuredDataKey<>("item_name", Types.TAG);
public static final StructuredDataKey<String> ITEM_MODEL = new StructuredDataKey<>("item_model", Types.STRING);
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", Types.TAG_ARRAY);
public static final StructuredDataKey<Tag[]> LORE = new StructuredDataKey<>("lore", new ArrayType<>(Types.TAG, 256));
public static final StructuredDataKey<Integer> RARITY = new StructuredDataKey<>("rarity", Types.VAR_INT);
public static final StructuredDataKey<Enchantments> ENCHANTMENTS = new StructuredDataKey<>("enchantments", Enchantments.TYPE);
public static final StructuredDataKey<AdventureModePredicate> CAN_PLACE_ON = new StructuredDataKey<>("can_place_on", AdventureModePredicate.TYPE);
@ -140,7 +141,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<Item[]> CONTAINER1_21_2 = new StructuredDataKey<>("container", new ArrayType<>(Types1_21_2.ITEM, 256));
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

@ -149,6 +149,8 @@ public final class Types {
public static final VarLongType VAR_LONG = new VarLongType();
/* MC Types */
public static final Type<byte[]> SERVERBOUND_CUSTOM_PAYLOAD_DATA = new RemainingBytesType(Short.MAX_VALUE);
public static final Type<BlockPosition> BLOCK_POSITION1_8 = new BlockPositionType1_8();
public static final Type<BlockPosition> OPTIONAL_POSITION1_8 = new BlockPositionType1_8.OptionalBlockPositionType();
public static final Type<BlockPosition> BLOCK_POSITION1_14 = new BlockPositionType1_14();

View File

@ -26,13 +26,22 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
public class ArrayType<T> extends Type<T[]> {
private final Type<T> elementType;
private final int maxLength;
public ArrayType(Type<T> type) {
this(type, -1);
}
public ArrayType(Type<T> type, int maxLength) {
//noinspection unchecked
super(type.getTypeName() + " Array", (Class<T[]>) getArrayClass(type.getOutputClass()));
this.elementType = type;
this.maxLength = maxLength;
}
public static Class<?> getArrayClass(Class<?> componentType) {
@ -43,16 +52,40 @@ public class ArrayType<T> extends Type<T[]> {
@Override
public T[] read(ByteBuf buffer) {
int amount = Types.VAR_INT.readPrimitive(buffer);
T[] array = (T[]) Array.newInstance(elementType.getOutputClass(), amount);
if (maxLength != -1 && amount > maxLength) {
throw new IllegalArgumentException("Array length " + amount + " is longer than maximum " + maxLength);
}
for (int i = 0; i < amount; i++) {
return amount < Short.MAX_VALUE ? readArray(buffer, amount) : readList(buffer, amount);
}
private T[] readArray(ByteBuf buffer, int length) {
T[] array = createArray(length);
for (int i = 0; i < length; i++) {
array[i] = elementType.read(buffer);
}
return array;
}
private T[] readList(ByteBuf buffer, int length) {
List<T> list = new ArrayList<>();
for (int i = 0; i < length; i++) {
list.add(elementType.read(buffer));
}
return list.toArray(createArray(0));
}
private T[] createArray(int length) {
//noinspection unchecked
return (T[]) Array.newInstance(elementType.getOutputClass(), length);
}
@Override
public void write(ByteBuf buffer, T[] object) {
if (maxLength != -1 && object.length > maxLength) {
throw new IllegalArgumentException("Array length " + object.length + " is longer than maximum " + maxLength);
}
Types.VAR_INT.writePrimitive(buffer, object.length);
for (T o : object) {
elementType.write(buffer, o);

View File

@ -26,19 +26,35 @@ import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class RemainingBytesType extends Type<byte[]> {
private final int maxLength;
public RemainingBytesType() {
this(-1);
}
public RemainingBytesType(final int maxLength) {
super(byte[].class);
this.maxLength = maxLength;
}
@Override
public byte[] read(ByteBuf buffer) {
byte[] array = new byte[buffer.readableBytes()];
public byte[] read(final ByteBuf buffer) {
final int bytes = buffer.readableBytes();
if (maxLength != -1 && bytes > maxLength) {
throw new RuntimeException("Remaining bytes cannot be longer than " + maxLength + " (got " + bytes + ")");
}
final byte[] array = new byte[bytes];
buffer.readBytes(array);
return array;
}
@Override
public void write(ByteBuf buffer, byte[] object) {
public void write(final ByteBuf buffer, final byte[] object) {
if (maxLength != -1 && object.length > maxLength) {
throw new RuntimeException("Remaining bytes cannot be longer than " + maxLength + " (got " + object.length + ")");
}
buffer.writeBytes(object);
}
}

View File

@ -63,7 +63,7 @@ public class ItemType1_20_5 extends Type<Item> {
return new Reference2ObjectOpenHashMap<>();
}
final Map<StructuredDataKey<?>, StructuredData<?>> map = new Reference2ObjectOpenHashMap<>();
final Map<StructuredDataKey<?>, StructuredData<?>> map = new Reference2ObjectOpenHashMap<>(Math.min(valuesSize + markersSize, 128));
for (int i = 0; i < valuesSize; i++) {
final StructuredData<?> value = dataType.read(buffer);
final StructuredDataKey<?> key = dataType.key(value.id());

View File

@ -0,0 +1,28 @@
/*
* 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.util;
public final class Limit {
public static int max(final int value, final int max) {
if (value > max) {
throw new IllegalArgumentException("Value " + value + " is higher than the maximum " + max);
}
return value;
}
}

View File

@ -211,7 +211,7 @@ public class ItemPacketRewriter1_13 extends ItemRewriter<ClientboundPackets1_12_
wrapper.cancel();
return;
} else if (channel.equals("REGISTER") || channel.equals("UNREGISTER")) {
String[] channels = new String(wrapper.read(Types.REMAINING_BYTES), StandardCharsets.UTF_8).split("\0");
String[] channels = new String(wrapper.read(Types.SERVERBOUND_CUSTOM_PAYLOAD_DATA), StandardCharsets.UTF_8).split("\0");
List<String> rewrittenChannels = new ArrayList<>();
for (String s : channels) {
String rewritten = getOldPluginChannelId(s);
@ -221,7 +221,7 @@ public class ItemPacketRewriter1_13 extends ItemRewriter<ClientboundPackets1_12_
protocol.getLogger().warning("Ignoring plugin channel in serverbound " + channel + ": " + s);
}
}
wrapper.write(Types.REMAINING_BYTES, Joiner.on('\0').join(rewrittenChannels).getBytes(StandardCharsets.UTF_8));
wrapper.write(Types.SERVERBOUND_CUSTOM_PAYLOAD_DATA, Joiner.on('\0').join(rewrittenChannels).getBytes(StandardCharsets.UTF_8));
}
wrapper.set(Types.STRING, 0, channel);
});

View File

@ -177,7 +177,7 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
}
wrapper.cancel();
} else if (namespacedChannel.equals("minecraft:register") || namespacedChannel.equals("minecraft:unregister")) {
String[] channels = new String(wrapper.read(Types.REMAINING_BYTES), StandardCharsets.UTF_8).split("\0");
String[] channels = new String(wrapper.read(Types.SERVERBOUND_CUSTOM_PAYLOAD_DATA), StandardCharsets.UTF_8).split("\0");
List<String> checkedChannels = new ArrayList<>(channels.length);
for (String registeredChannel : channels) {
if (registeredChannel.length() > 32) {
@ -195,7 +195,7 @@ public class Protocol1_15_2To1_16 extends AbstractProtocol<ClientboundPackets1_1
return;
}
wrapper.write(Types.REMAINING_BYTES, Joiner.on('\0').join(checkedChannels).getBytes(StandardCharsets.UTF_8));
wrapper.write(Types.SERVERBOUND_CUSTOM_PAYLOAD_DATA, Joiner.on('\0').join(checkedChannels).getBytes(StandardCharsets.UTF_8));
}
});
}

View File

@ -29,6 +29,7 @@ import com.viaversion.viaversion.api.type.types.StringType;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ClientboundPackets1_17;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17;
import com.viaversion.viaversion.protocols.v1_17to1_17_1.packet.ClientboundPackets1_17_1;
import com.viaversion.viaversion.util.Limit;
public final class Protocol1_17To1_17_1 extends AbstractProtocol<ClientboundPackets1_17, ClientboundPackets1_17_1, ServerboundPackets1_17, ServerboundPackets1_17> {
@ -88,14 +89,12 @@ public final class Protocol1_17To1_17_1 extends AbstractProtocol<ClientboundPack
int slot = wrapper.read(Types.VAR_INT);
// Save pages to tag
int pages = wrapper.read(Types.VAR_INT);
int pages = Limit.max(wrapper.read(Types.VAR_INT), 200);
ListTag<StringTag> pagesTag = new ListTag<>(StringTag.class);
for (int i = 0; i < pages; i++) {
String page = wrapper.read(PAGE_STRING_TYPE);
if (i < 200) { // Apply network limit as per game code
pagesTag.add(new StringTag(page));
}
}
// Legacy servers don't like an empty pages list
if (pagesTag.isEmpty()) {

View File

@ -65,6 +65,7 @@ import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Limit;
import com.viaversion.viaversion.util.SerializerVersion;
import com.viaversion.viaversion.util.TagUtil;
import com.viaversion.viaversion.util.Unit;
@ -154,7 +155,7 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
wrapper.passthrough(Types.SHORT); // Slot
wrapper.passthrough(Types.BYTE); // Button
wrapper.passthrough(Types.VAR_INT); // Mode
final int length = wrapper.passthrough(Types.VAR_INT);
final int length = Limit.max(wrapper.passthrough(Types.VAR_INT), 128);
for (int i = 0; i < length; i++) {
wrapper.passthrough(Types.SHORT); // Slot
passthroughServerboundItem(wrapper);

View File

@ -32,6 +32,7 @@ import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
import com.viaversion.viaversion.api.rewriter.RewriterBase;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.util.Limit;
import org.checkerframework.checker.nullness.qual.Nullable;
public class ItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
@ -219,7 +220,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
wrapper.passthrough(Types.VAR_INT); // Mode
// Affected items
final int length = wrapper.passthrough(Types.VAR_INT);
final int length = Limit.max(wrapper.passthrough(Types.VAR_INT), 128);
for (int i = 0; i < length; i++) {
wrapper.passthrough(Types.SHORT); // Slot
passthroughServerboundItem(wrapper);

View File

@ -17,7 +17,6 @@
*/
package com.viaversion.viaversion.util;
import com.viaversion.nbt.tag.ByteTag;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.NumberTag;