Merge pull request #1507 from creeper123123321/primitivebytearray

primitive array types
This commit is contained in:
Myles 2019-11-02 13:32:42 +00:00 committed by GitHub
commit f59c0722e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 146 additions and 45 deletions

View File

@ -150,12 +150,12 @@ public abstract class MetadataRewriter {
protocol.registerOutgoing(State.PLAY, oldPacketId, newPacketId, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT_ARRAY); // 0 - Entity ids
map(Type.VAR_INT_ARRAY_PRIMITIVE); // 0 - Entity ids
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
EntityTracker entityTracker = wrapper.user().get(entityTrackerClass);
for (int entity : wrapper.get(Type.VAR_INT_ARRAY, 0)) {
for (int entity : wrapper.get(Type.VAR_INT_ARRAY_PRIMITIVE, 0)) {
entityTracker.removeEntity(entity);
}
}

View File

@ -14,32 +14,69 @@ import java.util.UUID;
public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
/* Defined Types */
public static final Type<Byte> BYTE = new ByteType();
/**
* @deprecated unreasonable overhead, use BYTE_ARRAY_PRIMITIVE
*/
@Deprecated
public static final Type<Byte[]> BYTE_ARRAY = new ArrayType<>(Type.BYTE);
public static final Type<byte[]> BYTE_ARRAY_PRIMITIVE = new ByteArrayType();
public static final Type<byte[]> REMAINING_BYTES = new RemainingBytesType();
public static final Type<Short> UNSIGNED_BYTE = new UnsignedByteType();
/**
* @deprecated unreasonable overhead
*/
@Deprecated
public static final Type<Short[]> UNSIGNED_BYTE_ARRAY = new ArrayType<>(Type.UNSIGNED_BYTE);
public static final Type<Boolean> BOOLEAN = new BooleanType();
/**
* @deprecated unreasonable overhead
*/
@Deprecated
public static final Type<Boolean[]> BOOLEAN_ARRAY = new ArrayType<>(Type.BOOLEAN);
/* Number Types */
public static final Type<Integer> INT = new IntType();
/**
* @deprecated unreasonable overhead
*/
@Deprecated
public static final Type<Integer[]> INT_ARRAY = new ArrayType<>(Type.INT);
public static final Type<Double> DOUBLE = new DoubleType();
/**
* @deprecated unreasonable overhead
*/
@Deprecated
public static final Type<Double[]> DOUBLE_ARRAY = new ArrayType<>(Type.DOUBLE);
public static final Type<Long> LONG = new LongType();
/**
* @deprecated unreasonable overhead
*/
@Deprecated
public static final Type<Long[]> LONG_ARRAY = new ArrayType<>(Type.LONG);
public static final Type<Float> FLOAT = new FloatType();
/**
* @deprecated unreasonable overhead
*/
@Deprecated
public static final Type<Float[]> FLOAT_ARRAY = new ArrayType<>(Type.FLOAT);
public static final Type<Short> SHORT = new ShortType();
/**
* @deprecated unreasonable overhead
*/
@Deprecated
public static final Type<Short[]> SHORT_ARRAY = new ArrayType<>(Type.SHORT);
public static final Type<Integer> UNSIGNED_SHORT = new UnsignedShortType();
/**
* @deprecated unreasonable overhead
*/
@Deprecated
public static final Type<Integer[]> UNSIGNED_SHORT_ARRAY = new ArrayType<>(Type.UNSIGNED_SHORT);
/* Other Types */
public static final Type<String> STRING = new StringType();
@ -49,9 +86,18 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
public static final Type<UUID[]> UUID_ARRAY = new ArrayType<>(Type.UUID);
/* Variable Types */
public static final Type<Integer> VAR_INT = new VarIntType();
/**
* @deprecated unreasonable overhead, use VAR_INT_ARRAY_PRIMITIVE
*/
@Deprecated
public static final Type<Integer[]> VAR_INT_ARRAY = new ArrayType<>(Type.VAR_INT);
public static final Type<int[]> VAR_INT_ARRAY_PRIMITIVE = new VarIntArrayType();
public static final Type<Integer> OPTIONAL_VAR_INT = new OptionalVarIntType();
public static final Type<Long> VAR_LONG = new VarLongType();
/**
* @deprecated unreasonable overhead
*/
@Deprecated
public static final Type<Long[]> VAR_LONG_ARRAY = new ArrayType<>(Type.VAR_LONG);
/* Special Types */
public static final Type<Void> NOTHING = new VoidType(); // This is purely used for remapping.

View File

@ -0,0 +1,26 @@
package us.myles.ViaVersion.api.type.types;
import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.type.Type;
public class ByteArrayType extends Type<byte[]> {
public ByteArrayType() {
super(byte[].class);
}
@Override
public void write(ByteBuf buffer, byte[] object) throws Exception {
Type.VAR_INT.write(buffer, object.length);
buffer.writeBytes(object);
}
@Override
public byte[] read(ByteBuf buffer) throws Exception {
int length = Type.VAR_INT.read(buffer);
Preconditions.checkArgument(!buffer.isReadable(length), "Length is fewer than readable bytes");
byte[] array = new byte[length];
buffer.readBytes(array);
return array;
}
}

View File

@ -0,0 +1,30 @@
package us.myles.ViaVersion.api.type.types;
import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.type.Type;
public class VarIntArrayType extends Type<int[]> {
public VarIntArrayType() {
super(int[].class);
}
@Override
public int[] read(ByteBuf buffer) throws Exception {
int length = Type.VAR_INT.read(buffer);
Preconditions.checkArgument(buffer.isReadable(length)); // Sanity check, at least 1 byte will be used for each varint
int[] array = new int[length];
for (int i = 0; i < array.length; i++) {
array[i] = Type.VAR_INT.read(buffer);
}
return array;
}
@Override
public void write(ByteBuf buffer, int[] object) throws Exception {
Type.VAR_INT.write(buffer, object.length);
for (int i : object) {
Type.VAR_INT.write(buffer, i);
}
}
}

View File

@ -187,7 +187,7 @@ public class Protocol1_13_1To1_13 extends Protocol {
int blockTagsSize = wrapper.passthrough(Type.VAR_INT); // block tags
for (int i = 0; i < blockTagsSize; i++) {
wrapper.passthrough(Type.STRING);
Integer[] blocks = wrapper.passthrough(Type.VAR_INT_ARRAY);
int[] blocks = wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
for (int j = 0; j < blocks.length; j++) {
blocks[j] = getNewBlockId(blocks[j]);
}
@ -195,7 +195,7 @@ public class Protocol1_13_1To1_13 extends Protocol {
int itemTagsSize = wrapper.passthrough(Type.VAR_INT); // item tags
for (int i = 0; i < itemTagsSize; i++) {
wrapper.passthrough(Type.STRING);
Integer[] items = wrapper.passthrough(Type.VAR_INT_ARRAY);
int[] items = wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
for (int j = 0; j < items.length; j++) {
items[j] = InventoryPackets.getNewItemId(items[j]);
}

View File

@ -87,17 +87,20 @@ public class Protocol1_13To1_12_2 extends Protocol {
wrapper.write(Type.VAR_INT, MappingData.blockTags.size()); // block tags
for (Map.Entry<String, Integer[]> tag : MappingData.blockTags.entrySet()) {
wrapper.write(Type.STRING, tag.getKey());
wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone());
// Needs copy as other protocols may modify it
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
}
wrapper.write(Type.VAR_INT, MappingData.itemTags.size()); // item tags
for (Map.Entry<String, Integer[]> tag : MappingData.itemTags.entrySet()) {
wrapper.write(Type.STRING, tag.getKey());
wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone());
// Needs copy as other protocols may modify it
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
}
wrapper.write(Type.VAR_INT, MappingData.fluidTags.size()); // fluid tags
for (Map.Entry<String, Integer[]> tag : MappingData.fluidTags.entrySet()) {
wrapper.write(Type.STRING, tag.getKey());
wrapper.write(Type.VAR_INT_ARRAY, tag.getValue().clone());
// Needs copy as other protocols may modify it
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
}
}
}).send(Protocol1_13To1_12_2.class);
@ -482,7 +485,7 @@ public class Protocol1_13To1_12_2 extends Protocol {
public void handle(PacketWrapper wrapper) throws Exception {
int action = wrapper.get(Type.VAR_INT, 0);
for (int i = 0; i < (action == 0 ? 2 : 1); i++) {
Integer[] ids = wrapper.read(Type.VAR_INT_ARRAY);
int[] ids = wrapper.read(Type.VAR_INT_ARRAY_PRIMITIVE);
String[] stringIds = new String[ids.length];
for (int j = 0; j < ids.length; j++) {
stringIds[j] = "viaversion:legacy/" + ids[j];
@ -1178,4 +1181,12 @@ public class Protocol1_13To1_12_2 extends Protocol {
}
return name;
}
public static int[] toPrimitive(Integer[] array) {
int[] prim = new int[array.length];
for (int i = 0; i < array.length; i++) {
prim[i] = array[i];
}
return prim;
}
}

View File

@ -153,62 +153,50 @@ public class Protocol1_14To1_13_2 extends Protocol {
wrapper.write(Type.VAR_INT, blockTagsSize + 5); // block tags
for (int i = 0; i < blockTagsSize; i++) {
wrapper.passthrough(Type.STRING);
Integer[] blockIds = wrapper.passthrough(Type.VAR_INT_ARRAY);
int[] blockIds = wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
for (int j = 0; j < blockIds.length; j++) {
blockIds[j] = getNewBlockId(blockIds[j]);
}
}
// Minecraft crashes if we not send signs tags
wrapper.write(Type.STRING, "minecraft:signs");
wrapper.write(Type.VAR_INT_ARRAY, new Integer[]{
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{
getNewBlockId(150), getNewBlockId(155)
});
wrapper.write(Type.STRING, "minecraft:wall_signs");
wrapper.write(Type.VAR_INT_ARRAY, new Integer[]{
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{
getNewBlockId(155)
});
wrapper.write(Type.STRING, "minecraft:standing_signs");
wrapper.write(Type.VAR_INT_ARRAY, new Integer[]{
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{
getNewBlockId(150)
});
// Fences and walls tags - used for block connections
wrapper.write(Type.STRING, "minecraft:fences");
wrapper.write(Type.VAR_INT_ARRAY, new Integer[]{
189,
248,
472,
473,
474,
475
});
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{189, 248, 472, 473, 474, 475});
wrapper.write(Type.STRING, "minecraft:walls");
wrapper.write(Type.VAR_INT_ARRAY, new Integer[]{
271,
272,
});
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{271, 272});
int itemTagsSize = wrapper.read(Type.VAR_INT);
wrapper.write(Type.VAR_INT, itemTagsSize + 2); // item tags
for (int i = 0; i < itemTagsSize; i++) {
wrapper.passthrough(Type.STRING);
Integer[] itemIds = wrapper.passthrough(Type.VAR_INT_ARRAY);
int[] itemIds = wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
for (int j = 0; j < itemIds.length; j++) {
itemIds[j] = InventoryPackets.getNewItemId(itemIds[j]);
}
}
// Should fix fuel shift clicking
wrapper.write(Type.STRING, "minecraft:signs");
wrapper.write(Type.VAR_INT_ARRAY, new Integer[]{
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{
InventoryPackets.getNewItemId(541)
});
// Arrows tag (used by bow)
wrapper.write(Type.STRING, "minecraft:arrows");
wrapper.write(Type.VAR_INT_ARRAY, new Integer[]{
526, 825, 826
});
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{526, 825, 826});
int fluidTagsSize = wrapper.passthrough(Type.VAR_INT); // fluid tags
for (int i = 0; i < fluidTagsSize; i++) {
wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.VAR_INT_ARRAY);
wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
}
wrapper.write(Type.VAR_INT, 0); // new entity tags - do we need to send this?
}

View File

@ -32,7 +32,7 @@ public class WorldPackets {
private static final int VOID_AIR = MappingData.blockStateMappings.getNewId(8591);
private static final int CAVE_AIR = MappingData.blockStateMappings.getNewId(8592);
public static final int SERVERSIDE_VIEW_DISTANCE = 64;
private static final Byte[] FULL_LIGHT = new Byte[2048];
private static final byte[] FULL_LIGHT = new byte[2048];
static {
Arrays.fill(FULL_LIGHT, (byte) 0xff);
@ -234,22 +234,22 @@ public class WorldPackets {
// not sending skylight/setting empty skylight causes client lag due to some weird calculations
// only do this on the initial chunk send (not when chunk.isGroundUp() is false)
if (chunk.isGroundUp())
lightPacket.write(Type.BYTE_ARRAY, FULL_LIGHT); // chunk below 0
lightPacket.write(Type.BYTE_ARRAY_PRIMITIVE, FULL_LIGHT); // chunk below 0
for (ChunkSection section : chunk.getSections()) {
if (section == null || !section.hasSkyLight()) {
if (chunk.isGroundUp()) {
lightPacket.write(Type.BYTE_ARRAY, FULL_LIGHT);
lightPacket.write(Type.BYTE_ARRAY_PRIMITIVE, FULL_LIGHT);
}
continue;
}
lightPacket.write(Type.BYTE_ARRAY, fromPrimitiveArray(section.getSkyLight()));
lightPacket.write(Type.BYTE_ARRAY_PRIMITIVE, section.getSkyLight());
}
if (chunk.isGroundUp())
lightPacket.write(Type.BYTE_ARRAY, FULL_LIGHT); // chunk above 255
lightPacket.write(Type.BYTE_ARRAY_PRIMITIVE, FULL_LIGHT); // chunk above 255
for (ChunkSection section : chunk.getSections()) {
if (section == null) continue;
lightPacket.write(Type.BYTE_ARRAY, fromPrimitiveArray(section.getBlockLight()));
lightPacket.write(Type.BYTE_ARRAY_PRIMITIVE, section.getBlockLight());
}
EntityTracker1_14 entityTracker = wrapper.user().get(EntityTracker1_14.class);

View File

@ -122,7 +122,7 @@ public class Protocol1_15To1_14_4 extends Protocol {
int blockTagsSize = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < blockTagsSize; i++) {
wrapper.passthrough(Type.STRING);
Integer[] blockIds = wrapper.passthrough(Type.VAR_INT_ARRAY);
int[] blockIds = wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
for (int j = 0; j < blockIds.length; j++) {
blockIds[j] = getNewBlockId(blockIds[j]);
}
@ -131,7 +131,7 @@ public class Protocol1_15To1_14_4 extends Protocol {
int itemTagsSize = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < itemTagsSize; i++) {
wrapper.passthrough(Type.STRING);
Integer[] itemIds = wrapper.passthrough(Type.VAR_INT_ARRAY);
int[] itemIds = wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
for (int j = 0; j < itemIds.length; j++) {
itemIds[j] = InventoryPackets.getNewItemId(itemIds[j]);
}
@ -140,13 +140,13 @@ public class Protocol1_15To1_14_4 extends Protocol {
int fluidTagsSize = wrapper.passthrough(Type.VAR_INT); // fluid tags
for (int i = 0; i < fluidTagsSize; i++) {
wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.VAR_INT_ARRAY);
wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
}
int entityTagsSize = wrapper.passthrough(Type.VAR_INT); // entity tags
for (int i = 0; i < entityTagsSize; i++) {
wrapper.passthrough(Type.STRING);
Integer[] entitIds = wrapper.passthrough(Type.VAR_INT_ARRAY);
int[] entitIds = wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
for (int j = 0; j < entitIds.length; j++) {
entitIds[j] = EntityPackets.getNewEntityId(entitIds[j]);
}

View File

@ -55,10 +55,10 @@ public class EntityPackets {
if (!tracker.getVehicleMap().containsKey(passenger))
return null; // Cancel
passengerPacket.write(Type.VAR_INT, tracker.getVehicleMap().remove(passenger));
passengerPacket.write(Type.VAR_INT_ARRAY, new Integer[]{});
passengerPacket.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{});
} else {
passengerPacket.write(Type.VAR_INT, vehicle);
passengerPacket.write(Type.VAR_INT_ARRAY, new Integer[]{passenger});
passengerPacket.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{passenger});
tracker.getVehicleMap().put(passenger, vehicle);
}
passengerPacket.send(Protocol1_9To1_8.class); // Send the packet

View File

@ -346,13 +346,13 @@ public class SpawnPackets {
@Override
public void registerMap() {
map(Type.VAR_INT_ARRAY); // 0 - Entities to destroy
map(Type.VAR_INT_ARRAY_PRIMITIVE); // 0 - Entities to destroy
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Integer[] entities = wrapper.get(Type.VAR_INT_ARRAY, 0);
for (Integer entity : entities) {
int[] entities = wrapper.get(Type.VAR_INT_ARRAY_PRIMITIVE, 0);
for (int entity : entities) {
// EntityTracker
wrapper.user().get(EntityTracker1_9.class).removeEntity(entity);
}