mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-24 19:15:32 +01:00
Some more pre-sizing
This commit is contained in:
parent
6553fc9ae9
commit
04e936d487
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
28
api/src/main/java/com/viaversion/viaversion/util/Limit.java
Normal file
28
api/src/main/java/com/viaversion/viaversion/util/Limit.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
});
|
||||
|
@ -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));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user