From d527164d4c608be5666187eadb0d2f14d8b92894 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 13 Nov 2021 23:48:38 -0500 Subject: [PATCH] Initial update to 1.18 protocol --- pom.xml | 2 +- .../mc/protocol/MinecraftConstants.java | 4 +- .../mc/protocol/MinecraftProtocol.java | 35 ++-- .../mc/protocol/data/game/chunk/Chunk.java | 109 ++---------- .../mc/protocol/data/game/chunk/Column.java | 34 ---- .../protocol/data/game/chunk/DataPalette.java | 157 ++++++++++++++++++ .../game/chunk/palette/SingletonPalette.java | 43 +++++ .../data/game/level/LightUpdateData.java | 82 +++++++++ .../game/level/block/BlockEntityInfo.java | 17 ++ .../clientbound/ClientboundLoginPacket.java | 3 + .../ClientboundBlockEntityDataPacket.java | 4 +- .../level/ClientboundLevelChunkPacket.java | 89 ---------- .../ClientboundLevelChunkWithLightPacket.java | 66 ++++++++ .../level/ClientboundLightUpdatePacket.java | 75 +-------- ...lientboundSetSimulationDistancePacket.java | 26 +++ .../ServerboundClientInformationPacket.java | 6 + .../mc/protocol/MinecraftProtocolTest.java | 2 +- .../mc/protocol/packet/PacketTest.java | 2 +- .../ClientboundLevelChunkPacketTest.java | 38 ----- ...entboundLevelChunkWithLightPacketTest.java | 32 ++++ 20 files changed, 481 insertions(+), 345 deletions(-) delete mode 100644 src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/Column.java create mode 100644 src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/DataPalette.java create mode 100644 src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/palette/SingletonPalette.java create mode 100644 src/main/java/com/github/steveice10/mc/protocol/data/game/level/LightUpdateData.java create mode 100644 src/main/java/com/github/steveice10/mc/protocol/data/game/level/block/BlockEntityInfo.java delete mode 100644 src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkPacket.java create mode 100644 src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkWithLightPacket.java create mode 100644 src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundSetSimulationDistancePacket.java delete mode 100644 src/test/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkPacketTest.java create mode 100644 src/test/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkWithLightPacketTest.java diff --git a/pom.xml b/pom.xml index e46d2129..4e374a0d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.github.steveice10 mcprotocollib - 1.17.1-3-SNAPSHOT + 1.18-pre-SNAPSHOT jar MCProtocolLib diff --git a/src/main/java/com/github/steveice10/mc/protocol/MinecraftConstants.java b/src/main/java/com/github/steveice10/mc/protocol/MinecraftConstants.java index 549fe958..612028ca 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/MinecraftConstants.java +++ b/src/main/java/com/github/steveice10/mc/protocol/MinecraftConstants.java @@ -12,12 +12,12 @@ public final class MinecraftConstants { /** * Current supported game version. */ - public static final String GAME_VERSION = "1.17.1"; + public static final String GAME_VERSION = "1.18-pre1"; /** * Current supported protocol version. */ - public static final int PROTOCOL_VERSION = 756; + public static final int PROTOCOL_VERSION = (1 << 30) | 49; // General Key Constants diff --git a/src/main/java/com/github/steveice10/mc/protocol/MinecraftProtocol.java b/src/main/java/com/github/steveice10/mc/protocol/MinecraftProtocol.java index 4d372a21..463cae3e 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/MinecraftProtocol.java +++ b/src/main/java/com/github/steveice10/mc/protocol/MinecraftProtocol.java @@ -344,7 +344,7 @@ public class MinecraftProtocol extends PacketProtocol { clientboundPackets.register(0x1F, ClientboundHorseScreenOpenPacket.class, ClientboundHorseScreenOpenPacket::new); clientboundPackets.register(0x20, ClientboundInitializeBorderPacket.class, ClientboundInitializeBorderPacket::new); clientboundPackets.register(0x21, ClientboundKeepAlivePacket.class, ClientboundKeepAlivePacket::new); - clientboundPackets.register(0x22, ClientboundLevelChunkPacket.class, ClientboundLevelChunkPacket::new); + clientboundPackets.register(0x22, ClientboundLevelChunkWithLightPacket.class, ClientboundLevelChunkWithLightPacket::new); clientboundPackets.register(0x23, ClientboundLevelEventPacket.class, ClientboundLevelEventPacket::new); clientboundPackets.register(0x24, ClientboundLevelParticlesPacket.class, ClientboundLevelParticlesPacket::new); clientboundPackets.register(0x25, ClientboundLightUpdatePacket.class, ClientboundLightUpdatePacket::new); @@ -397,22 +397,23 @@ public class MinecraftProtocol extends PacketProtocol { clientboundPackets.register(0x54, ClientboundSetPassengersPacket.class, ClientboundSetPassengersPacket::new); clientboundPackets.register(0x55, ClientboundSetPlayerTeamPacket.class, ClientboundSetPlayerTeamPacket::new); clientboundPackets.register(0x56, ClientboundSetScorePacket.class, ClientboundSetScorePacket::new); - clientboundPackets.register(0x57, ClientboundSetSubtitleTextPacket.class, ClientboundSetSubtitleTextPacket::new); - clientboundPackets.register(0x58, ClientboundSetTimePacket.class, ClientboundSetTimePacket::new); - clientboundPackets.register(0x59, ClientboundSetTitleTextPacket.class, ClientboundSetTitleTextPacket::new); - clientboundPackets.register(0x5A, ClientboundSetTitlesAnimationPacket.class, ClientboundSetTitlesAnimationPacket::new); - clientboundPackets.register(0x5B, ClientboundSoundEntityPacket.class, ClientboundSoundEntityPacket::new); - clientboundPackets.register(0x5C, ClientboundSoundPacket.class, ClientboundSoundPacket::new); - clientboundPackets.register(0x5D, ClientboundStopSoundPacket.class, ClientboundStopSoundPacket::new); - clientboundPackets.register(0x5E, ClientboundTabListPacket.class, ClientboundTabListPacket::new); - clientboundPackets.register(0x5F, ClientboundTagQueryPacket.class, ClientboundTagQueryPacket::new); - clientboundPackets.register(0x60, ClientboundTakeItemEntityPacket.class, ClientboundTakeItemEntityPacket::new); - clientboundPackets.register(0x61, ClientboundTeleportEntityPacket.class, ClientboundTeleportEntityPacket::new); - clientboundPackets.register(0x62, ClientboundUpdateAdvancementsPacket.class, ClientboundUpdateAdvancementsPacket::new); - clientboundPackets.register(0x63, ClientboundUpdateAttributesPacket.class, ClientboundUpdateAttributesPacket::new); - clientboundPackets.register(0x64, ClientboundUpdateMobEffectPacket.class, ClientboundUpdateMobEffectPacket::new); - clientboundPackets.register(0x65, ClientboundUpdateRecipesPacket.class, ClientboundUpdateRecipesPacket::new); - clientboundPackets.register(0x66, ClientboundUpdateTagsPacket.class, ClientboundUpdateTagsPacket::new); + clientboundPackets.register(0x57, ClientboundSetSimulationDistancePacket.class, ClientboundSetSimulationDistancePacket::new); + clientboundPackets.register(0x58, ClientboundSetSubtitleTextPacket.class, ClientboundSetSubtitleTextPacket::new); + clientboundPackets.register(0x59, ClientboundSetTimePacket.class, ClientboundSetTimePacket::new); + clientboundPackets.register(0x5A, ClientboundSetTitleTextPacket.class, ClientboundSetTitleTextPacket::new); + clientboundPackets.register(0x5B, ClientboundSetTitlesAnimationPacket.class, ClientboundSetTitlesAnimationPacket::new); + clientboundPackets.register(0x5C, ClientboundSoundEntityPacket.class, ClientboundSoundEntityPacket::new); + clientboundPackets.register(0x5D, ClientboundSoundPacket.class, ClientboundSoundPacket::new); + clientboundPackets.register(0x5E, ClientboundStopSoundPacket.class, ClientboundStopSoundPacket::new); + clientboundPackets.register(0x5F, ClientboundTabListPacket.class, ClientboundTabListPacket::new); + clientboundPackets.register(0x60, ClientboundTagQueryPacket.class, ClientboundTagQueryPacket::new); + clientboundPackets.register(0x61, ClientboundTakeItemEntityPacket.class, ClientboundTakeItemEntityPacket::new); + clientboundPackets.register(0x62, ClientboundTeleportEntityPacket.class, ClientboundTeleportEntityPacket::new); + clientboundPackets.register(0x63, ClientboundUpdateAdvancementsPacket.class, ClientboundUpdateAdvancementsPacket::new); + clientboundPackets.register(0x64, ClientboundUpdateAttributesPacket.class, ClientboundUpdateAttributesPacket::new); + clientboundPackets.register(0x65, ClientboundUpdateMobEffectPacket.class, ClientboundUpdateMobEffectPacket::new); + clientboundPackets.register(0x66, ClientboundUpdateRecipesPacket.class, ClientboundUpdateRecipesPacket::new); + clientboundPackets.register(0x67, ClientboundUpdateTagsPacket.class, ClientboundUpdateTagsPacket::new); serverboundPackets.register(0x00, ServerboundAcceptTeleportationPacket.class, ServerboundAcceptTeleportationPacket::new); serverboundPackets.register(0x01, ServerboundBlockEntityTagQuery.class, ServerboundBlockEntityTagQuery::new); diff --git a/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/Chunk.java b/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/Chunk.java index e95a951a..91eee673 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/Chunk.java +++ b/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/Chunk.java @@ -1,16 +1,8 @@ package com.github.steveice10.mc.protocol.data.game.chunk; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.ListPalette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.MapPalette; -import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette; import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetOutput; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NonNull; -import lombok.Setter; +import lombok.*; import java.io.IOException; @@ -18,117 +10,48 @@ import java.io.IOException; @Setter(AccessLevel.NONE) @AllArgsConstructor public class Chunk { - private static final int CHUNK_SIZE = 4096; - private static final int MIN_PALETTE_BITS_PER_ENTRY = 4; private static final int MAX_PALETTE_BITS_PER_ENTRY = 8; - private static final int GLOBAL_PALETTE_BITS_PER_ENTRY = 14; + private static final int MAX_BIOME_BITS_PER_ENTRY = 2; private static final int AIR = 0; private int blockCount; - private @NonNull Palette palette; - private @NonNull BitStorage storage; + private @NonNull DataPalette chunkData; + @Getter + private @NonNull DataPalette biomeData; public Chunk() { - this(0, new ListPalette(MIN_PALETTE_BITS_PER_ENTRY), new BitStorage(MIN_PALETTE_BITS_PER_ENTRY, CHUNK_SIZE)); + this(0, DataPalette.createEmpty(MAX_PALETTE_BITS_PER_ENTRY, DataPalette.CHUNK_SIZE), DataPalette.createEmpty(MAX_BIOME_BITS_PER_ENTRY, DataPalette.BIOME_SIZE)); } public static Chunk read(NetInput in) throws IOException { int blockCount = in.readShort(); - int bitsPerEntry = in.readUnsignedByte(); - Palette palette = readPalette(bitsPerEntry, in); - - BitStorage storage = new BitStorage(bitsPerEntry, CHUNK_SIZE, in.readLongs(in.readVarInt())); - return new Chunk(blockCount, palette, storage); + DataPalette chunkPalette = DataPalette.read(in, MAX_PALETTE_BITS_PER_ENTRY, DataPalette.CHUNK_SIZE); + DataPalette biomePalette = DataPalette.read(in, MAX_BIOME_BITS_PER_ENTRY, DataPalette.BIOME_SIZE); + return new Chunk(blockCount, chunkPalette, biomePalette); } public static void write(NetOutput out, Chunk chunk) throws IOException { out.writeShort(chunk.blockCount); - out.writeByte(chunk.storage.getBitsPerEntry()); - - if (!(chunk.palette instanceof GlobalPalette)) { - int paletteLength = chunk.palette.size(); - out.writeVarInt(paletteLength); - for (int i = 0; i < paletteLength; i++) { - out.writeVarInt(chunk.palette.idToState(i)); - } - } - - long[] data = chunk.storage.getData(); - out.writeVarInt(data.length); - out.writeLongs(data); + DataPalette.write(out, chunk.chunkData); + DataPalette.write(out, chunk.biomeData); } - public int get(int x, int y, int z) { - int id = this.storage.get(index(x, y, z)); - return this.palette.idToState(id); + public int getBlock(int x, int y, int z) { + return this.chunkData.get(x, y, z); } - public void set(int x, int y, int z, @NonNull int state) { - int id = this.palette.stateToId(state); - if (id == -1) { - this.resizePalette(); - id = this.palette.stateToId(state); - } - - int index = index(x, y, z); - int curr = this.storage.get(index); + public void setBlock(int x, int y, int z, int state) { + int curr = this.chunkData.set(x, y, z, state); if (state != AIR && curr == AIR) { this.blockCount++; } else if (state == AIR && curr != AIR) { this.blockCount--; } - - this.storage.set(index, id); } - public boolean isEmpty() { + public boolean isBlockCountEmpty() { return this.blockCount == 0; } - - private int sanitizeBitsPerEntry(int bitsPerEntry) { - if (bitsPerEntry <= MAX_PALETTE_BITS_PER_ENTRY) { - return Math.max(MIN_PALETTE_BITS_PER_ENTRY, bitsPerEntry); - } else { - return GLOBAL_PALETTE_BITS_PER_ENTRY; - } - } - - private void resizePalette() { - Palette oldPalette = this.palette; - BitStorage oldData = this.storage; - - int bitsPerEntry = sanitizeBitsPerEntry(oldData.getBitsPerEntry() + 1); - this.palette = createPalette(bitsPerEntry); - this.storage = new BitStorage(bitsPerEntry, CHUNK_SIZE); - - for (int i = 0; i < CHUNK_SIZE; i++) { - this.storage.set(i, this.palette.stateToId(oldPalette.idToState(oldData.get(i)))); - } - } - - private static Palette createPalette(int bitsPerEntry) { - if (bitsPerEntry <= MIN_PALETTE_BITS_PER_ENTRY) { - return new ListPalette(bitsPerEntry); - } else if (bitsPerEntry <= MAX_PALETTE_BITS_PER_ENTRY) { - return new MapPalette(bitsPerEntry); - } else { - return new GlobalPalette(); - } - } - - private static Palette readPalette(int bitsPerEntry, NetInput in) throws IOException { - if (bitsPerEntry <= MIN_PALETTE_BITS_PER_ENTRY) { - return new ListPalette(bitsPerEntry, in); - } else if (bitsPerEntry <= MAX_PALETTE_BITS_PER_ENTRY) { - return new MapPalette(bitsPerEntry, in); - } else { - return new GlobalPalette(); - } - } - - private static int index(int x, int y, int z) { - return y << 8 | z << 4 | x; - } } diff --git a/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/Column.java b/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/Column.java deleted file mode 100644 index ef8691e1..00000000 --- a/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/Column.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.github.steveice10.mc.protocol.data.game.chunk; - -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import lombok.Data; -import lombok.NonNull; - -import java.util.Arrays; - -@Data -public class Column { - private final int x; - private final int z; - private final @NonNull Chunk[] chunks; - private final @NonNull CompoundTag[] tileEntities; - private final @NonNull CompoundTag heightMaps; - private final @NonNull int[] biomeData; - - /** - * @deprecated Non-full chunks no longer exist since 1.17. - */ - @Deprecated - public Column(int x, int z, @NonNull Chunk[] chunks, @NonNull CompoundTag[] tileEntities, @NonNull CompoundTag heightMaps) { - this(x, z, chunks, tileEntities, heightMaps, new int[1024]); - } - - public Column(int x, int z, @NonNull Chunk[] chunks, @NonNull CompoundTag[] tileEntities, @NonNull CompoundTag heightMaps, @NonNull int[] biomeData) { - this.x = x; - this.z = z; - this.chunks = Arrays.copyOf(chunks, chunks.length); - this.biomeData = biomeData != null ? Arrays.copyOf(biomeData, biomeData.length) : null; - this.tileEntities = tileEntities != null ? tileEntities : new CompoundTag[0]; - this.heightMaps = heightMaps; - } -} diff --git a/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/DataPalette.java b/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/DataPalette.java new file mode 100644 index 00000000..7f5356aa --- /dev/null +++ b/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/DataPalette.java @@ -0,0 +1,157 @@ +package com.github.steveice10.mc.protocol.data.game.chunk; + +import com.github.steveice10.mc.protocol.data.game.chunk.palette.*; +import com.github.steveice10.packetlib.io.NetInput; +import com.github.steveice10.packetlib.io.NetOutput; +import lombok.*; + +import java.io.IOException; + +@Getter +@Setter +@AllArgsConstructor +@EqualsAndHashCode +public class DataPalette { + static final int BIOME_SIZE = 64; + static final int CHUNK_SIZE = 4096; + private static final int MAX_BIOME_BITS_PER_ENTRY = 2; + private static final int MIN_PALETTE_BITS_PER_ENTRY = 4; + private static final int MAX_PALETTE_BITS_PER_ENTRY = 8; + private static final int GLOBAL_PALETTE_BITS_PER_ENTRY = 14; + + private @NonNull Palette palette; + private BitStorage storage; + private final int maxBitsForType; + private final int maxStorageSize; + + public static DataPalette createForChunk() { + return createEmpty(MAX_PALETTE_BITS_PER_ENTRY, CHUNK_SIZE); + } + + public static DataPalette createForBiome() { + return createEmpty(MAX_BIOME_BITS_PER_ENTRY, CHUNK_SIZE); + } + + public static DataPalette createEmpty(int maxBitsForType, int maxStorageSize) { + return new DataPalette(new ListPalette(MIN_PALETTE_BITS_PER_ENTRY), + new BitStorage(MIN_PALETTE_BITS_PER_ENTRY, maxBitsForType), maxBitsForType, maxStorageSize); + } + + public static DataPalette read(NetInput in, int maxBitsForType, int maxSizeForType) throws IOException { + int bitsPerEntry = in.readByte(); + Palette palette = readPalette(bitsPerEntry, maxBitsForType, in); + BitStorage storage; + if (!(palette instanceof SingletonPalette)) { + storage = new BitStorage(bitsPerEntry, maxSizeForType, in.readLongs(in.readVarInt())); + } else { + in.readVarInt(); + storage = null; + } + + return new DataPalette(palette, storage, maxBitsForType, maxSizeForType); + } + + public static void write(NetOutput out, DataPalette palette) throws IOException { + out.writeByte(palette.storage.getBitsPerEntry()); + + if (palette.palette instanceof SingletonPalette) { + out.writeVarInt(palette.palette.idToState(0)); + out.writeVarInt(0); // Data length + return; + } + + if (!(palette.palette instanceof GlobalPalette)) { + int paletteLength = palette.palette.size(); + out.writeVarInt(paletteLength); + for (int i = 0; i < paletteLength; i++) { + out.writeVarInt(palette.palette.idToState(i)); + } + } + + long[] data = palette.storage.getData(); + out.writeVarInt(data.length); + out.writeLongs(data); + } + + public int get(int x, int y, int z) { + if (storage != null) { + int id = this.storage.get(index(x, y, z)); + return this.palette.idToState(id); + } else { + return this.palette.idToState(0); + } + } + + /** + * @return the old value present in the storage. + */ + public int set(int x, int y, int z, int state) { + int id = this.palette.stateToId(state); + if (id == -1) { + resize(); + id = this.palette.stateToId(state); + } + + int index = index(x, y, z); + int curr = this.storage.get(index); + + this.storage.set(index, id); + return curr; + } + + private static Palette readPalette(int bitsPerEntry, int maxBitsPerEntry, NetInput in) throws IOException { + if (bitsPerEntry > maxBitsPerEntry) { + return new GlobalPalette(); + } + if (bitsPerEntry == 0) { + return new SingletonPalette(in); + } + if (bitsPerEntry <= MIN_PALETTE_BITS_PER_ENTRY) { + return new ListPalette(bitsPerEntry, in); + } else { + return new MapPalette(bitsPerEntry, in); + } + } + + private int sanitizeBitsPerEntry(int bitsPerEntry) { + if (bitsPerEntry <= MAX_PALETTE_BITS_PER_ENTRY) { + return Math.max(MIN_PALETTE_BITS_PER_ENTRY, bitsPerEntry); + } else { + return GLOBAL_PALETTE_BITS_PER_ENTRY; + } + } + + private void resize() { + Palette oldPalette = this.palette; + BitStorage oldData = this.storage; + + int bitsPerEntry = sanitizeBitsPerEntry(oldPalette instanceof SingletonPalette ? 1 : oldData.getBitsPerEntry() + 1); + this.palette = createPalette(bitsPerEntry); + this.storage = new BitStorage(bitsPerEntry, maxStorageSize); + + if (oldPalette instanceof SingletonPalette) { + for (int i = 0; i < maxStorageSize; i++) { + // TODO necessary? + this.storage.set(i, 0); + } + } else { + for (int i = 0; i < maxStorageSize; i++) { + this.storage.set(i, this.palette.stateToId(oldPalette.idToState(oldData.get(i)))); + } + } + } + + private static Palette createPalette(int bitsPerEntry) { + if (bitsPerEntry <= MIN_PALETTE_BITS_PER_ENTRY) { + return new ListPalette(bitsPerEntry); + } else if (bitsPerEntry <= MAX_PALETTE_BITS_PER_ENTRY) { + return new MapPalette(bitsPerEntry); + } else { + return new GlobalPalette(); + } + } + + private static int index(int x, int y, int z) { + return y << 8 | z << 4 | x; + } +} diff --git a/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/palette/SingletonPalette.java b/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/palette/SingletonPalette.java new file mode 100644 index 00000000..d435cc70 --- /dev/null +++ b/src/main/java/com/github/steveice10/mc/protocol/data/game/chunk/palette/SingletonPalette.java @@ -0,0 +1,43 @@ +package com.github.steveice10.mc.protocol.data.game.chunk.palette; + +import com.github.steveice10.packetlib.io.NetInput; +import lombok.EqualsAndHashCode; + +import java.io.IOException; + +/** + * A palette containing one state. + */ +@EqualsAndHashCode +public class SingletonPalette implements Palette { + private final int state; + + public SingletonPalette(int state) { + this.state = state; + } + + public SingletonPalette(NetInput in) throws IOException { + this.state = in.readVarInt(); + } + + @Override + public int size() { + return 1; + } + + @Override + public int stateToId(int state) { + if (this.state == state) { + return 0; + } + return -1; + } + + @Override + public int idToState(int id) { + if (id == 0) { + return this.state; + } + return 0; + } +} diff --git a/src/main/java/com/github/steveice10/mc/protocol/data/game/level/LightUpdateData.java b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/LightUpdateData.java new file mode 100644 index 00000000..8c6d7ad5 --- /dev/null +++ b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/LightUpdateData.java @@ -0,0 +1,82 @@ +package com.github.steveice10.mc.protocol.data.game.level; + +import com.github.steveice10.packetlib.io.NetInput; +import com.github.steveice10.packetlib.io.NetOutput; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NonNull; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; + +@Data +@AllArgsConstructor +public class LightUpdateData { + private final @NonNull BitSet skyYMask; + private final @NonNull BitSet blockYMask; + private final @NonNull BitSet emptySkyYMask; + private final @NonNull BitSet emptyBlockYMask; + private final @NonNull List skyUpdates; + private final @NonNull List blockUpdates; + private final boolean trustEdges; + + public static LightUpdateData read(NetInput in) throws IOException { + return new LightUpdateData(in); + } + + private LightUpdateData(NetInput in) throws IOException { + this.trustEdges = in.readBoolean(); + + this.skyYMask = BitSet.valueOf(in.readLongs(in.readVarInt())); + this.blockYMask = BitSet.valueOf(in.readLongs(in.readVarInt())); + this.emptySkyYMask = BitSet.valueOf(in.readLongs(in.readVarInt())); + this.emptyBlockYMask = BitSet.valueOf(in.readLongs(in.readVarInt())); + + int skyUpdateSize = in.readVarInt(); + skyUpdates = new ArrayList<>(skyUpdateSize); + for (int i = 0; i < skyUpdateSize; i++) { + skyUpdates.add(in.readBytes(in.readVarInt())); + } + + int blockUpdateSize = in.readVarInt(); + blockUpdates = new ArrayList<>(blockUpdateSize); + for (int i = 0; i < blockUpdateSize; i++) { + blockUpdates.add(in.readBytes(in.readVarInt())); + } + } + + public static void write(NetOutput out, LightUpdateData data) throws IOException { + data.write(out); + } + + private void write(NetOutput out) throws IOException { + out.writeBoolean(this.trustEdges); + + writeBitSet(out, this.skyYMask); + writeBitSet(out, this.blockYMask); + writeBitSet(out, this.emptySkyYMask); + writeBitSet(out, this.emptyBlockYMask); + + out.writeVarInt(this.skyUpdates.size()); + for (byte[] array : this.skyUpdates) { + out.writeVarInt(array.length); + out.writeBytes(array); + } + + out.writeVarInt(this.blockUpdates.size()); + for (byte[] array : this.blockUpdates) { + out.writeVarInt(array.length); + out.writeBytes(array); + } + } + + private void writeBitSet(NetOutput out, BitSet bitSet) throws IOException { + long[] array = bitSet.toLongArray(); + out.writeVarInt(array.length); + for (long content : array) { + out.writeLong(content); + } + } +} diff --git a/src/main/java/com/github/steveice10/mc/protocol/data/game/level/block/BlockEntityInfo.java b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/block/BlockEntityInfo.java new file mode 100644 index 00000000..d6cffe50 --- /dev/null +++ b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/block/BlockEntityInfo.java @@ -0,0 +1,17 @@ +package com.github.steveice10.mc.protocol.data.game.level.block; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import lombok.AllArgsConstructor; +import lombok.Data; + +import javax.annotation.Nullable; + +@Data +@AllArgsConstructor +public class BlockEntityInfo { + private final int x; + private final int y; + private final int z; + private final int id; + private final @Nullable CompoundTag nbt; +} diff --git a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/ClientboundLoginPacket.java b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/ClientboundLoginPacket.java index 57a991e9..dbaac9a0 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/ClientboundLoginPacket.java +++ b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/ClientboundLoginPacket.java @@ -32,6 +32,7 @@ public class ClientboundLoginPacket implements Packet { private final long hashedSeed; private final int maxPlayers; private final int viewDistance; + private final int simulationDistance; private final boolean reducedDebugInfo; private final boolean enableRespawnScreen; private final boolean debug; @@ -55,6 +56,7 @@ public class ClientboundLoginPacket implements Packet { this.hashedSeed = in.readLong(); this.maxPlayers = in.readVarInt(); this.viewDistance = in.readVarInt(); + this.simulationDistance = in.readVarInt(); this.reducedDebugInfo = in.readBoolean(); this.enableRespawnScreen = in.readBoolean(); this.debug = in.readBoolean(); @@ -80,6 +82,7 @@ public class ClientboundLoginPacket implements Packet { out.writeLong(this.hashedSeed); out.writeVarInt(this.maxPlayers); out.writeVarInt(this.viewDistance); + out.writeVarInt(this.simulationDistance); out.writeBoolean(this.reducedDebugInfo); out.writeBoolean(this.enableRespawnScreen); out.writeBoolean(this.debug); diff --git a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundBlockEntityDataPacket.java b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundBlockEntityDataPacket.java index 93722c9f..1a1bcac6 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundBlockEntityDataPacket.java +++ b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundBlockEntityDataPacket.java @@ -25,14 +25,14 @@ public class ClientboundBlockEntityDataPacket implements Packet { public ClientboundBlockEntityDataPacket(NetInput in) throws IOException { this.position = Position.read(in); - this.type = MagicValues.key(UpdatedTileType.class, in.readUnsignedByte()); + this.type = MagicValues.key(UpdatedTileType.class, in.readVarInt()); this.nbt = NBT.read(in); } @Override public void write(NetOutput out) throws IOException { Position.write(out, this.position); - out.writeByte(MagicValues.value(Integer.class, this.type)); + out.writeVarInt(MagicValues.value(Integer.class, this.type)); NBT.write(out, this.nbt); } } diff --git a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkPacket.java b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkPacket.java deleted file mode 100644 index 1f05ce97..00000000 --- a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkPacket.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.github.steveice10.mc.protocol.packet.ingame.clientbound.level; - -import com.github.steveice10.mc.protocol.data.game.NBT; -import com.github.steveice10.mc.protocol.data.game.chunk.Chunk; -import com.github.steveice10.mc.protocol.data.game.chunk.Column; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.github.steveice10.packetlib.io.NetInput; -import com.github.steveice10.packetlib.io.NetOutput; -import com.github.steveice10.packetlib.io.stream.StreamNetInput; -import com.github.steveice10.packetlib.io.stream.StreamNetOutput; -import com.github.steveice10.packetlib.packet.Packet; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NonNull; -import lombok.With; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.BitSet; - -@Data -@With -@AllArgsConstructor -public class ClientboundLevelChunkPacket implements Packet { - private final @NonNull Column column; - - public ClientboundLevelChunkPacket(NetInput in) throws IOException { - int x = in.readInt(); - int z = in.readInt(); - BitSet chunkMask = BitSet.valueOf(in.readLongs(in.readVarInt())); - CompoundTag heightMaps = NBT.read(in); - int[] biomeData = new int[in.readVarInt()]; - for (int index = 0; index < biomeData.length; index++) { - biomeData[index] = in.readVarInt(); - } - byte[] data = in.readBytes(in.readVarInt()); - - NetInput dataIn = new StreamNetInput(new ByteArrayInputStream(data)); - Chunk[] chunks = new Chunk[chunkMask.size()]; - for (int index = 0; index < chunks.length; index++) { - if (chunkMask.get(index)) { - chunks[index] = Chunk.read(dataIn); - } - } - - CompoundTag[] tileEntities = new CompoundTag[in.readVarInt()]; - for (int i = 0; i < tileEntities.length; i++) { - tileEntities[i] = NBT.read(in); - } - - this.column = new Column(x, z, chunks, tileEntities, heightMaps, biomeData); - } - - @Override - public void write(NetOutput out) throws IOException { - ByteArrayOutputStream dataBytes = new ByteArrayOutputStream(); - NetOutput dataOut = new StreamNetOutput(dataBytes); - - BitSet bitSet = new BitSet(); - Chunk[] chunks = this.column.getChunks(); - for (int index = 0; index < chunks.length; index++) { - Chunk chunk = chunks[index]; - if (chunk != null && !chunk.isEmpty()) { - bitSet.set(index); - Chunk.write(dataOut, chunk); - } - } - - out.writeInt(this.column.getX()); - out.writeInt(this.column.getZ()); - long[] longArray = bitSet.toLongArray(); - out.writeVarInt(longArray.length); - for (long content : longArray) { - out.writeLong(content); - } - NBT.write(out, this.column.getHeightMaps()); - out.writeVarInt(this.column.getBiomeData().length); - for (int biomeData : this.column.getBiomeData()) { - out.writeVarInt(biomeData); - } - out.writeVarInt(dataBytes.size()); - out.writeBytes(dataBytes.toByteArray(), dataBytes.size()); - out.writeVarInt(this.column.getTileEntities().length); - for (CompoundTag tag : this.column.getTileEntities()) { - NBT.write(out, tag); - } - } -} diff --git a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkWithLightPacket.java b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkWithLightPacket.java new file mode 100644 index 00000000..f4d9b44a --- /dev/null +++ b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkWithLightPacket.java @@ -0,0 +1,66 @@ +package com.github.steveice10.mc.protocol.packet.ingame.clientbound.level; + +import com.github.steveice10.mc.protocol.data.game.NBT; +import com.github.steveice10.mc.protocol.data.game.level.LightUpdateData; +import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.packetlib.io.NetInput; +import com.github.steveice10.packetlib.io.NetOutput; +import com.github.steveice10.packetlib.packet.Packet; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NonNull; +import lombok.With; + +import java.io.IOException; + +@Data +@With +@AllArgsConstructor +public class ClientboundLevelChunkWithLightPacket implements Packet { + private final int x; + private final int z; + private final @NonNull byte[] chunkData; + private final @NonNull CompoundTag heightMaps; + private final @NonNull BlockEntityInfo[] blockEntities; + private final @NonNull LightUpdateData lightData; + + public ClientboundLevelChunkWithLightPacket(NetInput in) throws IOException { + this.x = in.readInt(); + this.z = in.readInt(); + this.heightMaps = NBT.read(in); + this.chunkData = in.readBytes(in.readVarInt()); + + this.blockEntities = new BlockEntityInfo[in.readVarInt()]; + for (int i = 0; i < blockEntities.length; i++) { + byte xz = in.readByte(); + int blockEntityX = (xz >> 4) & 15; + int blockEntityZ = xz & 15; + int blockEntityY = in.readShort(); + int type = in.readVarInt(); + CompoundTag tag = NBT.read(in); + blockEntities[i] = new BlockEntityInfo(blockEntityX, blockEntityY, blockEntityZ, type, tag); + } + + this.lightData = LightUpdateData.read(in); + } + + @Override + public void write(NetOutput out) throws IOException { + out.writeInt(this.x); + out.writeInt(this.z); + NBT.write(out, this.heightMaps); + out.writeVarInt(this.chunkData.length); + out.writeBytes(this.chunkData); + + out.writeVarInt(this.blockEntities.length); + for (BlockEntityInfo blockEntity : this.blockEntities) { + out.writeByte(((blockEntity.getX() & 15) << 4) | blockEntity.getZ() & 15); + out.writeShort(blockEntity.getY()); + out.writeVarInt(blockEntity.getId()); + NBT.write(out, blockEntity.getNbt()); + } + + LightUpdateData.write(out, this.lightData); + } +} diff --git a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLightUpdatePacket.java b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLightUpdatePacket.java index 146c1349..82973de0 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLightUpdatePacket.java +++ b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLightUpdatePacket.java @@ -1,32 +1,26 @@ package com.github.steveice10.mc.protocol.packet.ingame.clientbound.level; +import com.github.steveice10.mc.protocol.data.game.level.LightUpdateData; import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.packet.Packet; -import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.Data; -import lombok.NoArgsConstructor; import lombok.NonNull; -import lombok.Setter; import lombok.With; +import javax.annotation.Nonnull; import java.io.IOException; -import java.util.ArrayList; import java.util.BitSet; import java.util.List; @Data @With +@AllArgsConstructor public class ClientboundLightUpdatePacket implements Packet { private final int x; private final int z; - private final @NonNull BitSet skyYMask; - private final @NonNull BitSet blockYMask; - private final @NonNull BitSet emptySkyYMask; - private final @NonNull BitSet emptyBlockYMask; - private final @NonNull List skyUpdates; - private final @NonNull List blockUpdates; - private final boolean trustEdges; + private final @Nonnull LightUpdateData lightData; public ClientboundLightUpdatePacket(int x, int z, @NonNull BitSet skyYMask, @NonNull BitSet blockYMask, @NonNull BitSet emptySkyYMask, @NonNull BitSet emptyBlockYMask, @@ -43,72 +37,19 @@ public class ClientboundLightUpdatePacket implements Packet { } this.x = x; this.z = z; - this.skyYMask = skyYMask; - this.blockYMask = blockYMask; - this.emptySkyYMask = emptySkyYMask; - this.emptyBlockYMask = emptyBlockYMask; - this.skyUpdates = skyUpdates; - this.blockUpdates = blockUpdates; - this.trustEdges = trustEdges; + this.lightData = new LightUpdateData(skyYMask, blockYMask, emptySkyYMask, emptyBlockYMask, skyUpdates, blockUpdates, trustEdges); } public ClientboundLightUpdatePacket(NetInput in) throws IOException { this.x = in.readVarInt(); this.z = in.readVarInt(); - this.trustEdges = in.readBoolean(); - - this.skyYMask = BitSet.valueOf(in.readLongs(in.readVarInt())); - this.blockYMask = BitSet.valueOf(in.readLongs(in.readVarInt())); - this.emptySkyYMask = BitSet.valueOf(in.readLongs(in.readVarInt())); - this.emptyBlockYMask = BitSet.valueOf(in.readLongs(in.readVarInt())); - - int skyUpdateSize = in.readVarInt(); - skyUpdates = new ArrayList<>(skyUpdateSize); - for (int i = 0; i < skyUpdateSize; i++) { - skyUpdates.add(in.readBytes(in.readVarInt())); - } - - int blockUpdateSize = in.readVarInt(); - blockUpdates = new ArrayList<>(blockUpdateSize); - for (int i = 0; i < blockUpdateSize; i++) { - blockUpdates.add(in.readBytes(in.readVarInt())); - } + this.lightData = LightUpdateData.read(in); } @Override public void write(NetOutput out) throws IOException { out.writeVarInt(this.x); out.writeVarInt(this.z); - out.writeBoolean(this.trustEdges); - - writeBitSet(out, this.skyYMask); - writeBitSet(out, this.blockYMask); - writeBitSet(out, this.emptySkyYMask); - writeBitSet(out, this.emptyBlockYMask); - - out.writeVarInt(this.skyUpdates.size()); - for (byte[] array : this.skyUpdates) { - out.writeVarInt(array.length); - out.writeBytes(array); - } - - out.writeVarInt(this.blockUpdates.size()); - for (byte[] array : this.blockUpdates) { - out.writeVarInt(array.length); - out.writeBytes(array); - } - } - - @Override - public boolean isPriority() { - return false; - } - - private void writeBitSet(NetOutput out, BitSet bitSet) throws IOException { - long[] array = bitSet.toLongArray(); - out.writeVarInt(array.length); - for (long content : array) { - out.writeLong(content); - } + LightUpdateData.write(out, this.lightData); } } diff --git a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundSetSimulationDistancePacket.java b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundSetSimulationDistancePacket.java new file mode 100644 index 00000000..856b02b0 --- /dev/null +++ b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundSetSimulationDistancePacket.java @@ -0,0 +1,26 @@ +package com.github.steveice10.mc.protocol.packet.ingame.clientbound.level; + +import com.github.steveice10.packetlib.io.NetInput; +import com.github.steveice10.packetlib.io.NetOutput; +import com.github.steveice10.packetlib.packet.Packet; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.With; + +import java.io.IOException; + +@Data +@With +@AllArgsConstructor +public class ClientboundSetSimulationDistancePacket implements Packet { + private final int simulationDistance; + + public ClientboundSetSimulationDistancePacket(NetInput in) throws IOException { + this.simulationDistance = in.readVarInt(); + } + + @Override + public void write(NetOutput out) throws IOException { + out.writeVarInt(this.simulationDistance); + } +} diff --git a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/serverbound/ServerboundClientInformationPacket.java b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/serverbound/ServerboundClientInformationPacket.java index 3280c595..9469c692 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/serverbound/ServerboundClientInformationPacket.java +++ b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/serverbound/ServerboundClientInformationPacket.java @@ -27,6 +27,10 @@ public class ServerboundClientInformationPacket implements Packet { private final @NonNull List visibleParts; private final @NonNull HandPreference mainHand; private final boolean textFilteringEnabled; + /** + * Whether the client permits being shown in server ping responses. + */ + private final boolean allowsListing; public ServerboundClientInformationPacket(NetInput in) throws IOException { this.locale = in.readString(); @@ -45,6 +49,7 @@ public class ServerboundClientInformationPacket implements Packet { this.mainHand = MagicValues.key(HandPreference.class, in.readVarInt()); this.textFilteringEnabled = in.readBoolean(); + this.allowsListing = in.readBoolean(); } @Override @@ -63,5 +68,6 @@ public class ServerboundClientInformationPacket implements Packet { out.writeVarInt(MagicValues.value(Integer.class, this.mainHand)); out.writeBoolean(this.textFilteringEnabled); + out.writeBoolean(allowsListing); } } diff --git a/src/test/java/com/github/steveice10/mc/protocol/MinecraftProtocolTest.java b/src/test/java/com/github/steveice10/mc/protocol/MinecraftProtocolTest.java index 4800933b..71e3835f 100644 --- a/src/test/java/com/github/steveice10/mc/protocol/MinecraftProtocolTest.java +++ b/src/test/java/com/github/steveice10/mc/protocol/MinecraftProtocolTest.java @@ -49,7 +49,7 @@ public class MinecraftProtocolTest { Component.text("Hello world!"), null ); - private static final ClientboundLoginPacket JOIN_GAME_PACKET = new ClientboundLoginPacket(0, false, GameMode.SURVIVAL, GameMode.SURVIVAL, 1, new String[]{"minecraft:world"}, getDimensionTag(), getOverworldTag(), "minecraft:world", 100, 0, 16, false, false, false, false); + private static final ClientboundLoginPacket JOIN_GAME_PACKET = new ClientboundLoginPacket(0, false, GameMode.SURVIVAL, GameMode.SURVIVAL, 1, new String[]{"minecraft:world"}, getDimensionTag(), getOverworldTag(), "minecraft:world", 100, 0, 16, 16, false, false, false, false); private static Server server; diff --git a/src/test/java/com/github/steveice10/mc/protocol/packet/PacketTest.java b/src/test/java/com/github/steveice10/mc/protocol/packet/PacketTest.java index 9b5a47b0..f36388a2 100644 --- a/src/test/java/com/github/steveice10/mc/protocol/packet/PacketTest.java +++ b/src/test/java/com/github/steveice10/mc/protocol/packet/PacketTest.java @@ -38,7 +38,7 @@ public abstract class PacketTest { return constructor.newInstance(in); } catch (NoSuchMethodError e) { - throw new IllegalStateException("Packet \"" + clazz.getName() + "\" does not have a no-params constructor for instantiation."); + throw new IllegalStateException("Packet \"" + clazz.getName() + "\" does not have a NetInput constructor for instantiation."); } catch (Exception e) { throw new IllegalStateException("Failed to instantiate packet \"" + clazz.getName() + "\".", e); } diff --git a/src/test/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkPacketTest.java b/src/test/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkPacketTest.java deleted file mode 100644 index d99a92f3..00000000 --- a/src/test/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkPacketTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.github.steveice10.mc.protocol.packet.ingame.clientbound.level; - -import com.github.steveice10.mc.protocol.data.game.chunk.Chunk; -import com.github.steveice10.mc.protocol.data.game.chunk.Column; -import com.github.steveice10.mc.protocol.packet.PacketTest; -import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import org.junit.Before; - -public class ClientboundLevelChunkPacketTest extends PacketTest { - @Before - public void setup() { - Chunk chunk = new Chunk(); - chunk.set(0, 0, 0, 10); - - this.setPackets( - new ClientboundLevelChunkPacket( - new Column(0, 0, new Chunk[]{ - null, null, null, null, null, null, null, chunk, - null, chunk, null, null, null, chunk, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null - }, new CompoundTag[0], new CompoundTag("HeightMaps"), new int[1024]) - ), - new ClientboundLevelChunkPacket( - new Column(1, 1, new Chunk[]{ - chunk, chunk, chunk, chunk, chunk, chunk, chunk, chunk, - chunk, chunk, chunk, chunk, chunk, chunk, chunk, chunk, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, null, null, null - }, new CompoundTag[]{ - new CompoundTag("TileEntity") - }, new CompoundTag("HeightMaps"), new int[1024]) - ) - ); - } -} diff --git a/src/test/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkWithLightPacketTest.java b/src/test/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkWithLightPacketTest.java new file mode 100644 index 00000000..7199dc40 --- /dev/null +++ b/src/test/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelChunkWithLightPacketTest.java @@ -0,0 +1,32 @@ +package com.github.steveice10.mc.protocol.packet.ingame.clientbound.level; + +import com.github.steveice10.mc.protocol.data.game.chunk.Chunk; +import com.github.steveice10.mc.protocol.data.game.level.LightUpdateData; +import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo; +import com.github.steveice10.mc.protocol.packet.PacketTest; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.junit.Before; + +import java.io.IOException; +import java.util.BitSet; +import java.util.Collections; + +public class ClientboundLevelChunkWithLightPacketTest extends PacketTest { + @Before + public void setup() throws IOException { + Chunk chunk = new Chunk(); + chunk.setBlock(0, 0, 0, 10); + + this.setPackets( + new ClientboundLevelChunkWithLightPacket(0, 0, + new byte[0], new CompoundTag("HeightMaps"), new BlockEntityInfo[0], + new LightUpdateData(new BitSet(), new BitSet(), new BitSet(), new BitSet(), Collections.emptyList(), Collections.emptyList(), false) + ), + new ClientboundLevelChunkWithLightPacket(1, 1, + new byte[256], new CompoundTag("HeightMaps"), new BlockEntityInfo[]{ + new BlockEntityInfo(1, 0, 1, 0, null) + }, new LightUpdateData(new BitSet(), new BitSet(), new BitSet(), new BitSet(), Collections.emptyList(), Collections.emptyList(), true) + ) + ); + } +}