diff --git a/bukkit-legacy/pom.xml b/bukkit-legacy/pom.xml index 1ad375b8f..83c517ada 100644 --- a/bukkit-legacy/pom.xml +++ b/bukkit-legacy/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 3.0.2-20w27a + 3.0.2-20w28a 4.0.0 diff --git a/bukkit/pom.xml b/bukkit/pom.xml index b70822b5f..07b0cc823 100644 --- a/bukkit/pom.xml +++ b/bukkit/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 3.0.2-20w27a + 3.0.2-20w28a 4.0.0 diff --git a/bungee/pom.xml b/bungee/pom.xml index 78d6c2d71..ada84a0be 100644 --- a/bungee/pom.xml +++ b/bungee/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 3.0.2-20w27a + 3.0.2-20w28a 4.0.0 diff --git a/common/pom.xml b/common/pom.xml index df66ca6f3..7da0a1b94 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 3.0.2-20w27a + 3.0.2-20w28a 4.0.0 diff --git a/common/src/main/java/us/myles/ViaVersion/api/data/MappingDataLoader.java b/common/src/main/java/us/myles/ViaVersion/api/data/MappingDataLoader.java index 448d6c066..6caae609a 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/data/MappingDataLoader.java +++ b/common/src/main/java/us/myles/ViaVersion/api/data/MappingDataLoader.java @@ -14,6 +14,7 @@ import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.URL; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -205,7 +206,11 @@ public class MappingDataLoader { return null; } - private static InputStream getResource(String name) { + public static InputStream getResource(String name) { return MappingDataLoader.class.getClassLoader().getResourceAsStream("assets/viaversion/data/" + name); } + + public static URL getResourceUrl(String name) { + return MappingDataLoader.class.getClassLoader().getResource("assets/viaversion/data/" + name); + } } diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockChangeRecord.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockChangeRecord.java index 4ea1fae42..40b550b03 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockChangeRecord.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockChangeRecord.java @@ -1,29 +1,38 @@ package us.myles.ViaVersion.api.minecraft; -public class BlockChangeRecord { - private final short horizontal; - private final short y; - private int blockId; +public interface BlockChangeRecord { - public BlockChangeRecord(short horizontal, short y, int blockId) { - this.horizontal = horizontal; - this.y = y; - this.blockId = blockId; + /** + * @return relative x coordinate within the chunk section + */ + byte getSectionX(); + + /** + * @return relative y coordinate within the chunk section + */ + byte getSectionY(); + + /** + * @return relative z coordinate within the chunk section + */ + byte getSectionZ(); + + /** + * @param chunkSectionY chunk section + * @return absolute y coordinate + */ + short getY(int chunkSectionY); + + /** + * @return absolute y coordinate + * @deprecated 1.16+ stores the relative y coordinate + */ + @Deprecated + default short getY() { + return getY(-1); } - public short getHorizontal() { - return horizontal; - } + int getBlockId(); - public short getY() { - return y; - } - - public int getBlockId() { - return blockId; - } - - public void setBlockId(int blockId) { - this.blockId = blockId; - } -} + void setBlockId(int blockId); +} \ No newline at end of file diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockChangeRecord1_16_2.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockChangeRecord1_16_2.java new file mode 100644 index 000000000..88d9a3bcf --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockChangeRecord1_16_2.java @@ -0,0 +1,50 @@ +package us.myles.ViaVersion.api.minecraft; + +import com.google.common.base.Preconditions; + +public class BlockChangeRecord1_16_2 implements BlockChangeRecord { + private final byte sectionX; + private final byte sectionY; + private final byte sectionZ; + private int blockId; + + public BlockChangeRecord1_16_2(byte sectionX, byte sectionY, byte sectionZ, int blockId) { + this.sectionX = sectionX; + this.sectionY = sectionY; + this.sectionZ = sectionZ; + this.blockId = blockId; + } + + public BlockChangeRecord1_16_2(int sectionX, int sectionY, int sectionZ, int blockId) { + this((byte) sectionX, (byte) sectionY, (byte) sectionZ, blockId); + } + + @Override + public byte getSectionX() { + return sectionX; + } + + @Override + public byte getSectionY() { + return sectionY; + } + + @Override + public byte getSectionZ() { + return sectionZ; + } + + @Override + public short getY(int chunkSectionY) { + Preconditions.checkArgument(chunkSectionY >= 0 && chunkSectionY < 16); + return (short) ((chunkSectionY << 4) + sectionY); + } + + public int getBlockId() { + return blockId; + } + + public void setBlockId(int blockId) { + this.blockId = blockId; + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockChangeRecord1_8.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockChangeRecord1_8.java new file mode 100644 index 000000000..2aef45583 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockChangeRecord1_8.java @@ -0,0 +1,54 @@ +package us.myles.ViaVersion.api.minecraft; + +public class BlockChangeRecord1_8 implements BlockChangeRecord { + private final byte sectionX; + private final short y; + private final byte sectionZ; + private int blockId; + + public BlockChangeRecord1_8(byte sectionX, short y, byte sectionZ, int blockId) { + this.sectionX = sectionX; + this.y = y; + this.sectionZ = sectionZ; + this.blockId = blockId; + } + + public BlockChangeRecord1_8(int sectionX, int y, int sectionZ, int blockId) { + this((byte) sectionX, (short) y, (byte) sectionZ, blockId); + } + + /** + * @return x coordinate within the chunk section + */ + public byte getSectionX() { + return sectionX; + } + + @Override + public byte getSectionY() { + return (byte) (y & 0xF); + } + + /** + * @return y coordinate + */ + @Override + public short getY(int chunkSectionY) { + return y; + } + + /** + * @return z coordinate within the chunk section + */ + public byte getSectionZ() { + return sectionZ; + } + + public int getBlockId() { + return blockId; + } + + public void setBlockId(int blockId) { + this.blockId = blockId; + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java index d50419f2a..dbe394b08 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java +++ b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java @@ -84,7 +84,7 @@ public class ProtocolVersion { register(v1_15_2 = new ProtocolVersion(578, "1.15.2")); register(v1_16 = new ProtocolVersion(735, "1.16")); register(v1_16_1 = new ProtocolVersion(736, "1.16.1")); - register(v1_16_2 = new ProtocolVersion(738, "1.16.2")); + register(v1_16_2 = new ProtocolVersion(740, "1.16.2")); register(unknown = new ProtocolVersion(-1, "UNKNOWN")); } diff --git a/common/src/main/java/us/myles/ViaVersion/api/rewriters/BlockRewriter.java b/common/src/main/java/us/myles/ViaVersion/api/rewriters/BlockRewriter.java index 0d128576c..b6905933f 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/rewriters/BlockRewriter.java +++ b/common/src/main/java/us/myles/ViaVersion/api/rewriters/BlockRewriter.java @@ -63,9 +63,22 @@ public class BlockRewriter { public void registerMap() { map(Type.INT); // 0 - Chunk X map(Type.INT); // 1 - Chunk Z - map(Type.BLOCK_CHANGE_RECORD_ARRAY); // 2 - Records handler(wrapper -> { - for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) { + for (BlockChangeRecord record : wrapper.passthrough(Type.BLOCK_CHANGE_RECORD_ARRAY)) { + record.setBlockId(blockStateRewriter.rewrite(record.getBlockId())); + } + }); + } + }); + } + + public void registerVarLongMultiBlockChange(ClientboundPacketType packetType) { + protocol.registerOutgoing(packetType, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.LONG); // Chunk position + handler(wrapper -> { + for (BlockChangeRecord record : wrapper.passthrough(Type.VAR_LONG_BLOCK_CHANGE_RECORD_ARRAY)) { record.setBlockId(blockStateRewriter.rewrite(record.getBlockId())); } }); diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/Type.java b/common/src/main/java/us/myles/ViaVersion/api/type/Type.java index b300033b3..7071fd369 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/Type.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/Type.java @@ -3,10 +3,51 @@ package us.myles.ViaVersion.api.type; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.google.gson.JsonElement; -import us.myles.ViaVersion.api.minecraft.*; +import us.myles.ViaVersion.api.minecraft.BlockChangeRecord; +import us.myles.ViaVersion.api.minecraft.EulerAngle; +import us.myles.ViaVersion.api.minecraft.Position; +import us.myles.ViaVersion.api.minecraft.Vector; +import us.myles.ViaVersion.api.minecraft.VillagerData; import us.myles.ViaVersion.api.minecraft.item.Item; -import us.myles.ViaVersion.api.type.types.*; -import us.myles.ViaVersion.api.type.types.minecraft.*; +import us.myles.ViaVersion.api.type.types.ArrayType; +import us.myles.ViaVersion.api.type.types.BooleanType; +import us.myles.ViaVersion.api.type.types.ByteArrayType; +import us.myles.ViaVersion.api.type.types.ByteType; +import us.myles.ViaVersion.api.type.types.ComponentType; +import us.myles.ViaVersion.api.type.types.DoubleType; +import us.myles.ViaVersion.api.type.types.FloatType; +import us.myles.ViaVersion.api.type.types.IntType; +import us.myles.ViaVersion.api.type.types.LongType; +import us.myles.ViaVersion.api.type.types.RemainingBytesType; +import us.myles.ViaVersion.api.type.types.ShortType; +import us.myles.ViaVersion.api.type.types.StringType; +import us.myles.ViaVersion.api.type.types.UUIDIntArrayType; +import us.myles.ViaVersion.api.type.types.UUIDType; +import us.myles.ViaVersion.api.type.types.UnsignedByteType; +import us.myles.ViaVersion.api.type.types.UnsignedShortType; +import us.myles.ViaVersion.api.type.types.VarIntArrayType; +import us.myles.ViaVersion.api.type.types.VarIntType; +import us.myles.ViaVersion.api.type.types.VarLongType; +import us.myles.ViaVersion.api.type.types.VoidType; +import us.myles.ViaVersion.api.type.types.minecraft.BlockChangeRecordType; +import us.myles.ViaVersion.api.type.types.minecraft.EulerAngleType; +import us.myles.ViaVersion.api.type.types.minecraft.FlatItemArrayType; +import us.myles.ViaVersion.api.type.types.minecraft.FlatItemType; +import us.myles.ViaVersion.api.type.types.minecraft.FlatVarIntItemArrayType; +import us.myles.ViaVersion.api.type.types.minecraft.FlatVarIntItemType; +import us.myles.ViaVersion.api.type.types.minecraft.ItemArrayType; +import us.myles.ViaVersion.api.type.types.minecraft.ItemType; +import us.myles.ViaVersion.api.type.types.minecraft.NBTType; +import us.myles.ViaVersion.api.type.types.minecraft.OptPosition1_14Type; +import us.myles.ViaVersion.api.type.types.minecraft.OptPositionType; +import us.myles.ViaVersion.api.type.types.minecraft.OptUUIDType; +import us.myles.ViaVersion.api.type.types.minecraft.OptionalComponentType; +import us.myles.ViaVersion.api.type.types.minecraft.OptionalVarIntType; +import us.myles.ViaVersion.api.type.types.minecraft.Position1_14Type; +import us.myles.ViaVersion.api.type.types.minecraft.PositionType; +import us.myles.ViaVersion.api.type.types.minecraft.VarLongBlockChangeRecordType; +import us.myles.ViaVersion.api.type.types.minecraft.VectorType; +import us.myles.ViaVersion.api.type.types.minecraft.VillagerDataType; import java.util.UUID; @@ -94,7 +135,7 @@ public abstract class Type implements ByteBufReader, ByteBufWriter { public static final Type VAR_INT_ARRAY = new ArrayType<>(Type.VAR_INT); public static final Type VAR_INT_ARRAY_PRIMITIVE = new VarIntArrayType(); public static final Type OPTIONAL_VAR_INT = new OptionalVarIntType(); - public static final Type VAR_LONG = new VarLongType(); + public static final VarLongType VAR_LONG = new VarLongType(); /** * @deprecated unreasonable overhead */ @@ -121,6 +162,9 @@ public abstract class Type implements ByteBufReader, ByteBufWriter { public static final Type BLOCK_CHANGE_RECORD = new BlockChangeRecordType(); public static final Type BLOCK_CHANGE_RECORD_ARRAY = new ArrayType<>(Type.BLOCK_CHANGE_RECORD); + public static final Type VAR_LONG_BLOCK_CHANGE_RECORD = new VarLongBlockChangeRecordType(); + public static final Type VAR_LONG_BLOCK_CHANGE_RECORD_ARRAY = new ArrayType<>(Type.VAR_LONG_BLOCK_CHANGE_RECORD); + public static final Type VILLAGER_DATA = new VillagerDataType(); /* 1.13 Flat Item (no data) */ diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/VarLongType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/VarLongType.java index 5dfbb54df..a72fefb5c 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/VarLongType.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/VarLongType.java @@ -10,10 +10,25 @@ public class VarLongType extends Type implements TypeConverter { super("VarLong", Long.class); } - @Override - public void write(ByteBuf buffer, Long object) { + public long readPrimitive(ByteBuf buffer) { + long out = 0; + int bytes = 0; + byte in; + do { + in = buffer.readByte(); + + out |= (long) (in & 0x7F) << (bytes++ * 7); + + if (bytes > 10) { // 10 is maxBytes + throw new RuntimeException("VarLong too big"); + } + } while ((in & 0x80) == 0x80); + return out; + } + + public void writePrimitive(ByteBuf buffer, long object) { int part; - while (true) { + do { part = (int) (object & 0x7F); object >>>= 7; @@ -22,35 +37,26 @@ public class VarLongType extends Type implements TypeConverter { } buffer.writeByte(part); - - if (object == 0) { - break; - } - } + } while (object != 0); } + /** + * @deprecated use {@link #readPrimitive(ByteBuf)} for manual reading to avoid wrapping + */ @Override + @Deprecated public Long read(ByteBuf buffer) { - long out = 0; - int bytes = 0; - byte in; - while (true) { - in = buffer.readByte(); - - out |= (in & 0x7F) << (bytes++ * 7); - - if (bytes > 10) { // 10 is maxBytes - throw new RuntimeException("VarLong too big"); - } - - if ((in & 0x80) != 0x80) { - break; - } - } - - return out; + return readPrimitive(buffer); } + /** + * @deprecated use {@link #writePrimitive(ByteBuf, long)} for manual reading to avoid wrapping + */ + @Override + @Deprecated + public void write(ByteBuf buffer, Long object) { + writePrimitive(buffer, object); + } @Override public Long from(Object o) { diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/BlockChangeRecordType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/BlockChangeRecordType.java index 1ff20f973..ff2bb2014 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/BlockChangeRecordType.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/BlockChangeRecordType.java @@ -2,26 +2,25 @@ package us.myles.ViaVersion.api.type.types.minecraft; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.minecraft.BlockChangeRecord; +import us.myles.ViaVersion.api.minecraft.BlockChangeRecord1_8; import us.myles.ViaVersion.api.type.Type; public class BlockChangeRecordType extends Type { + public BlockChangeRecordType() { super(BlockChangeRecord.class); } @Override public BlockChangeRecord read(ByteBuf buffer) throws Exception { - short horizontal = Type.UNSIGNED_BYTE.read(buffer); - short y = Type.UNSIGNED_BYTE.read(buffer); + short position = Type.SHORT.readPrimitive(buffer); int blockId = Type.VAR_INT.readPrimitive(buffer); - - return new BlockChangeRecord(horizontal, y, blockId); + return new BlockChangeRecord1_8(position >> 12 & 0xF, position & 0xFF, position >> 8 & 0xF, blockId); } @Override public void write(ByteBuf buffer, BlockChangeRecord object) throws Exception { - Type.UNSIGNED_BYTE.write(buffer, object.getHorizontal()); - Type.UNSIGNED_BYTE.write(buffer, object.getY()); + Type.SHORT.writePrimitive(buffer, (short) (object.getSectionX() << 12 | object.getSectionZ() << 8 | object.getY())); Type.VAR_INT.writePrimitive(buffer, object.getBlockId()); } } diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/VarLongBlockChangeRecordType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/VarLongBlockChangeRecordType.java new file mode 100644 index 000000000..039522802 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/VarLongBlockChangeRecordType.java @@ -0,0 +1,26 @@ +package us.myles.ViaVersion.api.type.types.minecraft; + +import io.netty.buffer.ByteBuf; +import us.myles.ViaVersion.api.minecraft.BlockChangeRecord; +import us.myles.ViaVersion.api.minecraft.BlockChangeRecord1_16_2; +import us.myles.ViaVersion.api.type.Type; + +public class VarLongBlockChangeRecordType extends Type { + + public VarLongBlockChangeRecordType() { + super(BlockChangeRecord.class); + } + + @Override + public BlockChangeRecord read(ByteBuf buffer) throws Exception { + long data = Type.VAR_LONG.readPrimitive(buffer); + short position = (short) (data & 0xFFFL); + return new BlockChangeRecord1_16_2(position >>> 8 & 0xF, position & 0xF, position >>> 4 & 0xF, (int) (data >>> 12)); + } + + @Override + public void write(ByteBuf buffer, BlockChangeRecord object) throws Exception { + short position = (short) (object.getSectionX() << 8 | object.getSectionZ() << 4 | object.getSectionY()); + Type.VAR_LONG.writePrimitive(buffer, (long) object.getBlockId() << 12 | position); + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java index 80940ba8b..9e14a37c2 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java @@ -11,7 +11,7 @@ import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.MappingDataLoader; import us.myles.ViaVersion.api.data.UserConnection; -import us.myles.ViaVersion.api.minecraft.BlockChangeRecord; +import us.myles.ViaVersion.api.minecraft.BlockChangeRecord1_8; import us.myles.ViaVersion.api.minecraft.BlockFace; import us.myles.ViaVersion.api.minecraft.Position; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; @@ -29,7 +29,7 @@ import java.util.Map; import java.util.Map.Entry; public class ConnectionData { - private static final BlockChangeRecord[] EMPTY_RECORDS = new BlockChangeRecord[0]; + private static final BlockChangeRecord1_8[] EMPTY_RECORDS = new BlockChangeRecord1_8[0]; public static BlockConnectionProvider blockConnectionProvider; static Int2ObjectMap idToKey = new Int2ObjectOpenHashMap<>(8582, 1F); static Map keyToId = new HashMap<>(8582, 1F); @@ -61,7 +61,7 @@ public class ConnectionData { for (int chunkDeltaZ = -1; chunkDeltaZ <= 1; chunkDeltaZ++) { if (Math.abs(chunkDeltaX) + Math.abs(chunkDeltaZ) == 0) continue; - List updates = new ArrayList<>(); + List updates = new ArrayList<>(); if (Math.abs(chunkDeltaX) + Math.abs(chunkDeltaZ) == 2) { // Corner for (int blockY = chunkSectionY * 16; blockY < chunkSectionY * 16 + 16; blockY++) { @@ -132,13 +132,13 @@ public class ConnectionData { } } - public static void updateBlock(UserConnection user, Position pos, List records) { + public static void updateBlock(UserConnection user, Position pos, List records) { int blockState = blockConnectionProvider.getBlockData(user, pos.getX(), pos.getY(), pos.getZ()); ConnectionHandler handler = getConnectionHandler(blockState); if (handler == null) return; int newBlockState = handler.connect(user, pos, blockState); - records.add(new BlockChangeRecord((short) (((pos.getX() & 0xF) << 4) | (pos.getZ() & 0xF)), pos.getY(), newBlockState)); + records.add(new BlockChangeRecord1_8(pos.getX() & 0xF, pos.getY(), pos.getZ() & 0xF, newBlockState)); } public static void updateBlockStorage(UserConnection userConnection, int x, int y, int z, int blockState) { diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java index 7a9a42be6..8de58d31f 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java @@ -207,9 +207,9 @@ public class WorldPackets { for (BlockChangeRecord record : records) { int newBlock = toNewId(record.getBlockId()); Position position = new Position( - (record.getHorizontal() >> 4 & 15) + (chunkX * 16), + record.getSectionX() + (chunkX * 16), record.getY(), - (record.getHorizontal() & 15) + (chunkZ * 16)); + record.getSectionZ() + (chunkZ * 16)); if (Via.getConfig().isServersideBlockConnections()) { ConnectionData.updateBlockStorage(userConnection, position.getX(), position.getY(), position.getZ(), newBlock); @@ -222,9 +222,9 @@ public class WorldPackets { int blockState = record.getBlockId(); Position position = new Position( - (record.getHorizontal() >> 4 & 15) + (chunkX * 16), + record.getSectionX() + (chunkX * 16), record.getY(), - (record.getHorizontal() & 15) + (chunkZ * 16)); + record.getSectionZ() + (chunkZ * 16)); ConnectionHandler handler = ConnectionData.getConnectionHandler(blockState); if (handler != null) { @@ -238,9 +238,9 @@ public class WorldPackets { for (BlockChangeRecord record : records) { Position position = new Position( - (record.getHorizontal() >> 4 & 15) + (chunkX * 16), + record.getSectionX() + (chunkX * 16), record.getY(), - (record.getHorizontal() & 15) + (chunkZ * 16)); + record.getSectionZ() + (chunkZ * 16)); ConnectionData.update(userConnection, position); } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/ClientboundPackets1_16_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/ClientboundPackets1_16_2.java new file mode 100644 index 000000000..6b476922b --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/ClientboundPackets1_16_2.java @@ -0,0 +1,99 @@ +package us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1; + +import us.myles.ViaVersion.api.protocol.ClientboundPacketType; + +public enum ClientboundPackets1_16_2 implements ClientboundPacketType { + + SPAWN_ENTITY, // 0x00 + SPAWN_EXPERIENCE_ORB, // 0x01 + SPAWN_MOB, // 0x02 + SPAWN_PAINTING, // 0x03 + SPAWN_PLAYER, // 0x04 + ENTITY_ANIMATION, // 0x05 + STATISTICS, // 0x06 + ACKNOWLEDGE_PLAYER_DIGGING, // 0x07 + BLOCK_BREAK_ANIMATION, // 0x08 + BLOCK_ENTITY_DATA, // 0x09 + BLOCK_ACTION, // 0x0A + BLOCK_CHANGE, // 0x0B + BOSSBAR, // 0x0C + SERVER_DIFFICULTY, // 0x0D + CHAT_MESSAGE, // 0x0E + TAB_COMPLETE, // 0x0F + DECLARE_COMMANDS, // 0x10 + WINDOW_CONFIRMATION, // 0x11 + CLOSE_WINDOW, // 0x12 + WINDOW_ITEMS, // 0x13 + WINDOW_PROPERTY, // 0x14 + SET_SLOT, // 0x15 + COOLDOWN, // 0x16 + PLUGIN_MESSAGE, // 0x17 + NAMED_SOUND, // 0x18 + DISCONNECT, // 0x19 + ENTITY_STATUS, // 0x1A + EXPLOSION, // 0x1B + UNLOAD_CHUNK, // 0x1C + GAME_EVENT, // 0x1D + OPEN_HORSE_WINDOW, // 0x1E + KEEP_ALIVE, // 0x1F + CHUNK_DATA, // 0x20 + EFFECT, // 0x21 + SPAWN_PARTICLE, // 0x22 + UPDATE_LIGHT, // 0x23 + JOIN_GAME, // 0x24 + MAP_DATA, // 0x25 + TRADE_LIST, // 0x26 + ENTITY_POSITION, // 0x27 + ENTITY_POSITION_AND_ROTATION, // 0x28 + ENTITY_ROTATION, // 0x29 + ENTITY_MOVEMENT, // 0x2A + VEHICLE_MOVE, // 0x2B + OPEN_BOOK, // 0x2C + OPEN_WINDOW, // 0x2D + OPEN_SIGN_EDITOR, // 0x2E + CRAFT_RECIPE_RESPONSE, // 0x2F + PLAYER_ABILITIES, // 0x30 + COMBAT_EVENT, // 0x31 + PLAYER_INFO, // 0x32 + FACE_PLAYER, // 0x33 + PLAYER_POSITION, // 0x34 + UNLOCK_RECIPES, // 0x35 + DESTROY_ENTITIES, // 0x36 + REMOVE_ENTITY_EFFECT, // 0x37 + RESOURCE_PACK, // 0x38 + RESPAWN, // 0x39 + ENTITY_HEAD_LOOK, // 0x3A + MULTI_BLOCK_CHANGE, // 0x3B + SELECT_ADVANCEMENTS_TAB, // 0x3C + WORLD_BORDER, // 0x3D + CAMERA, // 0x3E + HELD_ITEM_CHANGE, // 0x3F + UPDATE_VIEW_POSITION, // 0x40 + UPDATE_VIEW_DISTANCE, // 0x41 + SPAWN_POSITION, // 0x42 + DISPLAY_SCOREBOARD, // 0x43 + ENTITY_METADATA, // 0x44 + ATTACH_ENTITY, // 0x45 + ENTITY_VELOCITY, // 0x46 + ENTITY_EQUIPMENT, // 0x47 + SET_EXPERIENCE, // 0x48 + UPDATE_HEALTH, // 0x49 + SCOREBOARD_OBJECTIVE, // 0x4A + SET_PASSENGERS, // 0x4B + TEAMS, // 0x4C + UPDATE_SCORE, // 0x4D + TIME_UPDATE, // 0x4E + TITLE, // 0x4F + ENTITY_SOUND, // 0x50 + SOUND, // 0x51 + STOP_SOUND, // 0x52 + TAB_LIST, // 0x53 + NBT_QUERY, // 0x54 + COLLECT_ITEM, // 0x55 + ENTITY_TELEPORT, // 0x56 + ADVANCEMENTS, // 0x57 + ENTITY_PROPERTIES, // 0x58 + ENTITY_EFFECT, // 0x59 + DECLARE_RECIPES, // 0x5A + TAGS, // 0x5B +} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/Protocol1_16_2To1_16_1.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/Protocol1_16_2To1_16_1.java index c6b2f5a5c..73eb4bd0e 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/Protocol1_16_2To1_16_1.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/Protocol1_16_2To1_16_1.java @@ -18,12 +18,12 @@ import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16 import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.ServerboundPackets1_16; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; -public class Protocol1_16_2To1_16_1 extends Protocol { +public class Protocol1_16_2To1_16_1 extends Protocol { private TagRewriter tagRewriter; public Protocol1_16_2To1_16_1() { - super(ClientboundPackets1_16.class, ClientboundPackets1_16.class, ServerboundPackets1_16.class, ServerboundPackets1_16_2.class, true); + super(ClientboundPackets1_16.class, ClientboundPackets1_16_2.class, ServerboundPackets1_16.class, ServerboundPackets1_16_2.class, true); } @Override diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/data/MappingData.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/data/MappingData.java index 6208b8f81..b9c7e8cc7 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/data/MappingData.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/data/MappingData.java @@ -1,12 +1,18 @@ package us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.data; +import com.github.steveice10.opennbt.NBTIO; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.google.gson.JsonObject; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.MappingDataLoader; import us.myles.ViaVersion.api.data.Mappings; import us.myles.ViaVersion.util.Int2IntBiMap; +import java.io.File; +import java.io.IOException; + public class MappingData { + public static CompoundTag dimensionRegistry; public static Int2IntBiMap oldToNewItems = new Int2IntBiMap(); public static Mappings blockMappings; public static Mappings blockStateMappings; @@ -17,6 +23,13 @@ public class MappingData { JsonObject mapping1_16 = MappingDataLoader.loadData("mapping-1.16.json", true); JsonObject mapping1_16_2 = MappingDataLoader.loadData("mapping-1.16.2.json", true); + try { + dimensionRegistry = NBTIO.readFile(new File(MappingDataLoader.getResourceUrl("dimenstion-registry-1.16.2.nbt").getFile())); + } catch (IOException e) { + Via.getPlatform().getLogger().severe("Error loading dimenstion registry:"); + e.printStackTrace(); + } + oldToNewItems.defaultReturnValue(-1); blockStateMappings = new Mappings(mapping1_16.getAsJsonObject("blockstates"), mapping1_16_2.getAsJsonObject("blockstates")); blockMappings = new Mappings(mapping1_16.getAsJsonObject("blocks"), mapping1_16_2.getAsJsonObject("blocks")); diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/packets/EntityPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/packets/EntityPackets.java index 934f92141..1d155525c 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/packets/EntityPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/packets/EntityPackets.java @@ -5,6 +5,7 @@ import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.api.type.types.version.Types1_14; import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.Protocol1_16_2To1_16_1; +import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.data.MappingData; import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.metadata.MetadataRewriter1_16_2To1_16_1; import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.storage.EntityTracker1_16_2; import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16; @@ -35,7 +36,11 @@ public class EntityPackets { }); map(Type.BYTE); // Previous Gamemode map(Type.STRING_ARRAY); // World List - map(Type.NBT); // Dimension Registry + handler(wrapper -> { + // Throw away the old dimension registry, extra conversion would be too hard of a hit + wrapper.read(Type.NBT); + wrapper.write(Type.NBT, MappingData.dimensionRegistry); + }); map(Type.STRING); // Dimension Type map(Type.STRING); // Dimension map(Type.LONG); // Seed diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/packets/WorldPackets.java index 83ba4301a..fc554f8e8 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/packets/WorldPackets.java @@ -1,5 +1,6 @@ package us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.packets; +import us.myles.ViaVersion.api.minecraft.BlockChangeRecord; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.protocol.Protocol; @@ -7,6 +8,7 @@ import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.rewriters.BlockRewriter; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.Protocol1_16_2To1_16_1; +import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.types.Chunk1_16_2Type; import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16; import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.types.Chunk1_16Type; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; @@ -18,7 +20,6 @@ public class WorldPackets { blockRewriter.registerBlockAction(ClientboundPackets1_16.BLOCK_ACTION); blockRewriter.registerBlockChange(ClientboundPackets1_16.BLOCK_CHANGE); - blockRewriter.registerMultiBlockChange(ClientboundPackets1_16.MULTI_BLOCK_CHANGE); blockRewriter.registerAcknowledgePlayerDigging(ClientboundPackets1_16.ACKNOWLEDGE_PLAYER_DIGGING); protocol.registerOutgoing(ClientboundPackets1_16.CHUNK_DATA, new PacketRemapper() { @@ -26,7 +27,9 @@ public class WorldPackets { public void registerMap() { handler(wrapper -> { ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - Chunk chunk = wrapper.passthrough(new Chunk1_16Type(clientWorld)); + Chunk chunk = wrapper.read(new Chunk1_16Type(clientWorld)); + wrapper.write(new Chunk1_16_2Type(clientWorld), chunk); + for (int s = 0; s < 16; s++) { ChunkSection section = chunk.getSections()[s]; if (section == null) continue; @@ -39,8 +42,49 @@ public class WorldPackets { } }); + protocol.registerOutgoing(ClientboundPackets1_16.MULTI_BLOCK_CHANGE, new PacketRemapper() { + @Override + public void registerMap() { + handler(wrapper -> { + wrapper.cancel(); + + int chunkX = wrapper.read(Type.INT); + int chunkZ = wrapper.read(Type.INT); + wrapper.write(Type.LONG, asLong(chunkX, 0, chunkZ)); //TODO + + BlockChangeRecord[] blockChangeRecord = wrapper.read(Type.BLOCK_CHANGE_RECORD_ARRAY); + wrapper.write(Type.VAR_LONG_BLOCK_CHANGE_RECORD_ARRAY, blockChangeRecord); + for (BlockChangeRecord record : blockChangeRecord) { + record.setBlockId(Protocol1_16_2To1_16_1.getNewBlockId(record.getBlockId())); + } + }); + } + }); + blockRewriter.registerEffect(ClientboundPackets1_16.EFFECT, 1010, 2001, InventoryPackets::getNewItemId); blockRewriter.registerSpawnParticle(ClientboundPackets1_16.SPAWN_PARTICLE, 3, 23, 34, null, InventoryPackets::toClient, Type.FLAT_VAR_INT_ITEM, Type.DOUBLE); } + + //TODO to chunk coordinates + public static int x(final long long1) { + return (int) (long1 >> 42); + } + + public static int y(final long long1) { + return (int) (long1 << 44 >> 44); + } + + public static int z(final long long1) { + return (int) (long1 << 22 >> 42); + } + + + public static long asLong(final int x, final int y, final int z) { + long long4 = 0L; + long4 |= (x & 0x3FFFFFL) << 42; + long4 |= (y & 0xFFFFFL); + long4 |= (z & 0x3FFFFFL) << 20; + return long4; + } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/types/Chunk1_16_2Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/types/Chunk1_16_2Type.java new file mode 100644 index 000000000..8fd73884f --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_16_2to1_16_1/types/Chunk1_16_2Type.java @@ -0,0 +1,106 @@ +package us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.types; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import io.netty.buffer.ByteBuf; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.minecraft.chunks.BaseChunk; +import us.myles.ViaVersion.api.minecraft.chunks.Chunk; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; +import us.myles.ViaVersion.api.type.PartialType; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType; +import us.myles.ViaVersion.api.type.types.version.Types1_16; +import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Chunk1_16_2Type extends PartialType { + private static final CompoundTag[] EMPTY_COMPOUNDS = new CompoundTag[0]; + + public Chunk1_16_2Type(ClientWorld param) { + super(param, Chunk.class); + } + + @Override + public Chunk read(ByteBuf input, ClientWorld world) throws Exception { + int chunkX = input.readInt(); + int chunkZ = input.readInt(); + + boolean fullChunk = input.readBoolean(); + boolean ignoreOldLightData = input.readBoolean(); + int primaryBitmask = Type.VAR_INT.readPrimitive(input); + CompoundTag heightMap = Type.NBT.read(input); + + int[] biomeData = null; + if (fullChunk) { + biomeData = Type.VAR_INT_ARRAY_PRIMITIVE.read(input); + } + + Type.VAR_INT.readPrimitive(input); // data size in bytes + + // Read sections + ChunkSection[] sections = new ChunkSection[16]; + for (int i = 0; i < 16; i++) { + if ((primaryBitmask & (1 << i)) == 0) continue; // Section not set + + short nonAirBlocksCount = input.readShort(); + ChunkSection section = Types1_16.CHUNK_SECTION.read(input); + section.setNonAirBlocksCount(nonAirBlocksCount); + sections[i] = section; + } + + List nbtData = new ArrayList<>(Arrays.asList(Type.NBT_ARRAY.read(input))); + + // Read all the remaining bytes (workaround for #681) + if (input.readableBytes() > 0) { + byte[] array = Type.REMAINING_BYTES.read(input); + if (Via.getManager().isDebug()) { + Via.getPlatform().getLogger().warning("Found " + array.length + " more bytes than expected while reading the chunk: " + chunkX + "/" + chunkZ); + } + } + + return new BaseChunk(chunkX, chunkZ, fullChunk, ignoreOldLightData, primaryBitmask, sections, biomeData, heightMap, nbtData); + } + + @Override + public void write(ByteBuf output, ClientWorld world, Chunk chunk) throws Exception { + output.writeInt(chunk.getX()); + output.writeInt(chunk.getZ()); + + output.writeBoolean(chunk.isFullChunk()); + output.writeBoolean(chunk.isIgnoreOldLightData()); + Type.VAR_INT.writePrimitive(output, chunk.getBitmask()); + Type.NBT.write(output, chunk.getHeightMap()); + + // Write biome data + if (chunk.isBiomeData()) { + Type.VAR_INT_ARRAY_PRIMITIVE.write(output, chunk.getBiomeData()); + } + + ByteBuf buf = output.alloc().buffer(); + try { + for (int i = 0; i < 16; i++) { + ChunkSection section = chunk.getSections()[i]; + if (section == null) continue; // Section not set + + buf.writeShort(section.getNonAirBlocksCount()); + Types1_16.CHUNK_SECTION.write(buf, section); + } + buf.readerIndex(0); + Type.VAR_INT.writePrimitive(output, buf.readableBytes()); + output.writeBytes(buf); + } finally { + buf.release(); // release buffer + } + + // Write Block Entities + Type.NBT_ARRAY.write(output, chunk.getBlockEntities().toArray(EMPTY_COMPOUNDS)); + } + + @Override + public Class getBaseClass() { + return BaseChunkType.class; + } +} diff --git a/common/src/main/resources/assets/viaversion/data/dimension-registry-1.16.2.nbt b/common/src/main/resources/assets/viaversion/data/dimension-registry-1.16.2.nbt new file mode 100644 index 000000000..76b74bcee Binary files /dev/null and b/common/src/main/resources/assets/viaversion/data/dimension-registry-1.16.2.nbt differ diff --git a/fabric/pom.xml b/fabric/pom.xml index c6834bb7b..6a0f4e1dd 100644 --- a/fabric/pom.xml +++ b/fabric/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 3.0.2-20w27a + 3.0.2-20w28a 4.0.0 diff --git a/jar/pom.xml b/jar/pom.xml index eccda7698..eeffe666b 100644 --- a/jar/pom.xml +++ b/jar/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 3.0.2-20w27a + 3.0.2-20w28a 4.0.0 viaversion-jar diff --git a/pom.xml b/pom.xml index 0dec419c2..58dfdf531 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ us.myles viaversion-parent - 3.0.2-20w27a + 3.0.2-20w28a pom viaversion-parent diff --git a/sponge-legacy/pom.xml b/sponge-legacy/pom.xml index 9cd2b6a32..76ca91ff2 100644 --- a/sponge-legacy/pom.xml +++ b/sponge-legacy/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 3.0.2-20w27a + 3.0.2-20w28a 4.0.0 diff --git a/sponge/pom.xml b/sponge/pom.xml index 20bba0b3a..a170bd396 100644 --- a/sponge/pom.xml +++ b/sponge/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 3.0.2-20w27a + 3.0.2-20w28a 4.0.0 diff --git a/velocity/pom.xml b/velocity/pom.xml index ad650e9ce..24fdb80b7 100644 --- a/velocity/pom.xml +++ b/velocity/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 3.0.2-20w27a + 3.0.2-20w28a 4.0.0