diff --git a/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java index 573f0b855..757cdfbc9 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java @@ -7,6 +7,7 @@ import fr.themode.minestom.net.ConnectionState; import fr.themode.minestom.net.packet.client.ClientPreplayPacket; import fr.themode.minestom.net.packet.server.login.JoinGamePacket; import fr.themode.minestom.net.packet.server.login.LoginSuccessPacket; +import fr.themode.minestom.net.packet.server.play.ChunkDataPacket; import fr.themode.minestom.net.packet.server.play.SpawnPositionPacket; import fr.themode.minestom.net.player.PlayerConnection; import fr.themode.minestom.utils.Utils; @@ -28,7 +29,7 @@ public class LoginStartPacket implements ClientPreplayPacket { // TODO complete login sequence with optionals packets JoinGamePacket joinGamePacket = new JoinGamePacket(); joinGamePacket.entityId = 32; - joinGamePacket.gameMode = GameMode.SURVIVAL; + joinGamePacket.gameMode = GameMode.CREATIVE; joinGamePacket.dimension = Dimension.OVERWORLD; joinGamePacket.maxPlayers = 0; joinGamePacket.levelType = "default"; @@ -42,6 +43,27 @@ public class LoginStartPacket implements ClientPreplayPacket { // TODO player abilities + for (int x = 0; x < 8; x++) { + for (int z = 0; z < 8; z++) { + ChunkDataPacket.ChunkSection chunkSection = new ChunkDataPacket.ChunkSection(); + chunkSection.bitsPerBlock = 13; + chunkSection.data = new long[]{0x1001880C0060020L, 0x200D0068004C020L, 0L}; + + ChunkDataPacket chunkDataPacket = new ChunkDataPacket(); + chunkDataPacket.columnX = x; + chunkDataPacket.columnZ = z; + chunkDataPacket.fullChunk = true; + chunkDataPacket.mask = 0xFFFF; // 16 bits + ChunkDataPacket.ChunkSection[] sections = new ChunkDataPacket.ChunkSection[16]; + for (int i = 0; i < 16; i++) { + sections[i] = chunkSection; + } + chunkDataPacket.chunkSections = sections; + + connection.sendPacket(chunkDataPacket); + } + } + SpawnPositionPacket spawnPositionPacket = new SpawnPositionPacket(); spawnPositionPacket.x = 50; spawnPositionPacket.y = 50; diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/ChunkDataPacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/ChunkDataPacket.java new file mode 100644 index 000000000..c3a7c49d1 --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/ChunkDataPacket.java @@ -0,0 +1,98 @@ +package fr.themode.minestom.net.packet.server.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.net.packet.server.ServerPacket; +import fr.themode.minestom.utils.Utils; + +public class ChunkDataPacket implements ServerPacket { + + public int columnX; + public int columnZ; + public boolean fullChunk; + public int mask; + public ChunkSection[] chunkSections; + public int tileEntitesSize; + // TODO nbt tile entities + + @Override + public void write(Buffer buffer) { + buffer.putInt(columnX); + buffer.putInt(columnZ); + buffer.putBoolean(fullChunk); + Utils.writeVarInt(buffer, mask); + System.out.println("test: " + getDataSize()); + Utils.writeVarInt(buffer, getDataSize()); + writeData(buffer); + Utils.writeVarInt(buffer, tileEntitesSize); + // TODO nbt tile entities + } + + private int getDataSize() { + int result = Integer.BYTES * 256; // Size for 256 biomes value + for (int i = 0; i < chunkSections.length; i++) { + result += chunkSections[i].getSize(); + } + return result; + } + + private void writeData(Buffer buffer) { + for (ChunkSection chunkSection : chunkSections) { + chunkSection.write(buffer); + } + // Biomes data + for (int i = 0; i < 256; i++) { + buffer.putInt(127); // Void biome + } + } + + @Override + public int getId() { + return 0x21; + } + + public static class ChunkSection { + + public byte bitsPerBlock; + public int paletteLength; // Optional + public int[] palette; // Optional + public long[] data; + public byte[] blockLight; + public byte[] skyLight; + + public void write(Buffer buffer) { + buffer.putByte(bitsPerBlock); + + if (bitsPerBlock < 9) { + Utils.writeVarInt(buffer, paletteLength); + for (int p : palette) { + Utils.writeVarInt(buffer, p); + } + } + + Utils.writeVarInt(buffer, data.length); + for (long d : data) { + buffer.putLong(d); + } + //buffer.putBytes(blockLight); + //buffer.putBytes(skyLight); + } + + public int getSize() { + int size = 0; + size++; //bitsPerBlock + if (bitsPerBlock < 9) { + size += Utils.lengthVarInt(paletteLength); + for (int p : palette) { + size += Utils.lengthVarInt(p); + } + } + + size += Utils.lengthVarInt(data.length); + size += Long.BYTES * data.length; + //size += blockLight.length; + //size += skyLight.length; + return size; + } + + } +} diff --git a/src/main/java/fr/themode/minestom/utils/Utils.java b/src/main/java/fr/themode/minestom/utils/Utils.java index 99860987c..c74bbafa1 100644 --- a/src/main/java/fr/themode/minestom/utils/Utils.java +++ b/src/main/java/fr/themode/minestom/utils/Utils.java @@ -75,6 +75,19 @@ public class Utils { return i; } + public static int lengthVarLong(long value) { + int i = 0; + do { + i++; + byte temp = (byte) (value & 0b01111111); + value >>>= 7; + if (value != 0) { + temp |= 0b10000000; + } + } while (value != 0); + return i; + } + public static void writeVarLong(Buffer buffer, long value) { do { byte temp = (byte) (value & 0b01111111);