From d699dae60111ce6e5cf55b9ebeee13772a5df2ff Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Wed, 1 Aug 2018 09:36:36 +0300 Subject: [PATCH 1/5] stash 1 --- .../mc/core/network/proto_1_12_2/State.java | 1 + .../proto_1_12_2/packets/ChunkDataPacket.java | 58 +++++++++++++++++++ .../netty/handlers/LoginHandler.java | 8 +++ 3 files changed, 67 insertions(+) create mode 100644 proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java diff --git a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/State.java b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/State.java index 237aa4f..feb4f26 100644 --- a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/State.java +++ b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/State.java @@ -87,6 +87,7 @@ public enum State { .put(PluginMessagePacket.class, 0x18) .put(ChangeGameState.class, 0x1E) .put(KeepAlivePacket.class, 0x1F) + .put(ChunkDataPacket.class, 0x20) .put(JoinGamePacket.class, 0x23) .put(PlayerAbilitiesPacket.class, 0x2C) .put(PlayerListItemPacket.class, 0x2E) diff --git a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java new file mode 100644 index 0000000..c05c479 --- /dev/null +++ b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java @@ -0,0 +1,58 @@ +/* + * DmitriyMX + * 2018-07-21 + */ +package mc.core.network.proto_1_12_2.packets; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import mc.core.network.NetOutputStream; +import mc.core.network.SCPacket; +import mc.core.world.Chunk; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@NoArgsConstructor +public class ChunkDataPacket implements SCPacket { + @Setter + private int x; + @Setter + private int z; + @Setter + private boolean initChunk = true; // "Ground-Up Continuous" + @Getter + private List chunks = new ArrayList<>(); + + @Override + public void writeSelf(NetOutputStream netStream) { + netStream.writeInt(x); + netStream.writeInt(z); + netStream.writeBoolean(initChunk); + netStream.writeVarInt(0b11111111); // Primary Bit Mask + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + for (Chunk chunk : chunks) { + netStream.writeByte(4); // Bits Per Block + // + // + // + // + // +// baos.write(ChunkSerializer.serializeBiomes(chunk)); + } + } catch (IOException e) { + log.error("Error serialize chunk", e); // what? is it possible?? + } + netStream.writeVarInt(baos.size()); // Size of Data in bytes + netStream.writeBytes(baos.toByteArray()); // Data chunks + netStream.writeVarInt(0); // size NBT + /* writeNBT */ + } +} diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java index eb5cd65..4ceb337 100644 --- a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java @@ -80,6 +80,14 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand channel.write(pkt3); channel.flush(); + // Send chunk data + ChunkDataPacket pkt8 = new ChunkDataPacket(); + pkt8.setX(0); + pkt8.setZ(0); + pkt8.getChunks().add(world.getChunk(0,0)); + pkt8.setInitChunk(true); + channel.writeAndFlush(pkt8); + // Player Position And Look PlayerPositionAndLookPacket pkt4 = new PlayerPositionAndLookPacket(); pkt4.setLocation(player.getLocation()); From 0152377289a07748187ada538feedd9575521d01 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 2 Aug 2018 14:25:29 +0300 Subject: [PATCH 2/5] stash 2 --- core/src/main/java/mc/core/world/Block.java | 15 ++++ core/src/main/java/mc/core/world/Chunk.java | 15 ++-- .../ByteArrayOutputNetStream.java | 4 ++ .../proto_1_12_2/packets/ChunkDataPacket.java | 71 +++++++++++++++---- 4 files changed, 84 insertions(+), 21 deletions(-) create mode 100644 core/src/main/java/mc/core/world/Block.java diff --git a/core/src/main/java/mc/core/world/Block.java b/core/src/main/java/mc/core/world/Block.java new file mode 100644 index 0000000..ba2865a --- /dev/null +++ b/core/src/main/java/mc/core/world/Block.java @@ -0,0 +1,15 @@ +/* + * DmitriyMX + * 2018-08-02 + */ +package mc.core.world; + +import mc.core.Location; + +public interface Block { + int getId(); + int getState(); + int getMetadata(); + int getLight(); + Location getLocation(); +} diff --git a/core/src/main/java/mc/core/world/Chunk.java b/core/src/main/java/mc/core/world/Chunk.java index 15ee0fa..db8f289 100644 --- a/core/src/main/java/mc/core/world/Chunk.java +++ b/core/src/main/java/mc/core/world/Chunk.java @@ -4,16 +4,15 @@ */ package mc.core.world; +import mc.core.Location; + /* 16x16x16 */ public interface Chunk { - int getBlockType(int x, int y, int z); - void setBlockType(int x, int y, int z, int type); - - int getBlockMetadata(int x, int y, int z); - void setBlockMetadata(int x, int y, int z, int metadata); - - int getBlockLight(int x, int y, int z); - void setBlockLight(int x, int y, int z, int lightLevel); + Block getBlock(int x, int y, int z); + default Block getBlock(Location location) { + return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + } + void setBlock(Block block); int getSkyLight(int x, int y, int z); void setSkyLight(int x, int y, int z, int lightLevel); diff --git a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/ByteArrayOutputNetStream.java b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/ByteArrayOutputNetStream.java index 15810b7..d496e05 100644 --- a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/ByteArrayOutputNetStream.java +++ b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/ByteArrayOutputNetStream.java @@ -65,6 +65,10 @@ public class ByteArrayOutputNetStream extends NetOutputStream_p340 { writeLong(Double.doubleToLongBits(value)); } + public int size() { + return baos.size(); + } + public byte[] toByteArray() { return baos.toByteArray(); } diff --git a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java index c05c479..f1e9f98 100644 --- a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java +++ b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java @@ -10,6 +10,7 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; import mc.core.network.NetOutputStream; import mc.core.network.SCPacket; +import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream; import mc.core.world.Chunk; import java.io.ByteArrayOutputStream; @@ -17,6 +18,55 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +/* +Packet structure + +- https://wiki.vg/Chunk_Format#Packet_structure + ++------------------------------------------------------+ +| Field | Type | +|--------------------------|---------------------------| +| Chunk X | int | +|--------------------------|---------------------------| +| Chunk Y | int | +|--------------------------|---------------------------| +| Init Chunk | boolean | ("Ground-Up Continuous") +|--------------------------|---------------------------| +| Primary Bit Mask | VarInt | +|--------------------------|---------------------------| +| Size of Data | VarInt | +|--------------------------|---------------------------| +| Data | Byte array | - https://wiki.vg/Chunk_Format#Data_structure +| +------------------------------------------------+ | +| | Chunk Section | Byte array | | - https://wiki.vg/Chunk_Format#Chunk_Section_structure +| | +------------------------------------------+ | | +| | | Bits Per Block | Unsigned Byte | | | +| | |--------------------|---------------------| | | +| | | Palette | Byte array | | | - https://wiki.vg/Chunk_Format#Palettes +| | | +------------------------------------+ | | | (we use Indirect type palette) +| | | | Size of palette | VarInt | | | | +| | | |-----------------|------------------| | | | +| | | | Palette | Array of VarInt | | | | +| | | +------------------------------------+ | | | +| | |--------------------|---------------------| | | +| | | Size of Data Array | VarInt | | | +| | |--------------------|---------------------| | | +| | | Data Array | Array of Long | | | +| | |--------------------|---------------------| | | +| | | Block Light | Byte Array | | | +| | |--------------------|---------------------| | | +| | | Sky Light | Optional Byte Array | | | +| | +------------------------------------------+ | | +| |-----------------------|------------------------| | +| | Biomes | Optional Byte array | | +| +------------------------------------------------+ | +|--------------------------|---------------------------| +| Number of block entities | VarInt | +|--------------------------|---------------------------| +| Block entities | Array of NBT | ++------------------------------------------------------+ + */ + @Slf4j @NoArgsConstructor public class ChunkDataPacket implements SCPacket { @@ -36,19 +86,14 @@ public class ChunkDataPacket implements SCPacket { netStream.writeBoolean(initChunk); netStream.writeVarInt(0b11111111); // Primary Bit Mask - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - for (Chunk chunk : chunks) { - netStream.writeByte(4); // Bits Per Block - // - // - // - // - // -// baos.write(ChunkSerializer.serializeBiomes(chunk)); - } - } catch (IOException e) { - log.error("Error serialize chunk", e); // what? is it possible?? + ByteArrayOutputNetStream baos = new ByteArrayOutputNetStream(); + for (Chunk chunk : chunks) { + // + // + // + // + // + // } netStream.writeVarInt(baos.size()); // Size of Data in bytes netStream.writeBytes(baos.toByteArray()); // Data chunks From 55ef6eec6650d8053a1ea12a414e4c41036ec0df Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 2 Aug 2018 15:59:11 +0300 Subject: [PATCH 3/5] stash 3 --- .../proto_1_12_2/packets/ChunkDataPacket.java | 94 +++++++++++++++---- 1 file changed, 78 insertions(+), 16 deletions(-) diff --git a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java index f1e9f98..af8789f 100644 --- a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java +++ b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java @@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import mc.core.network.NetOutputStream; import mc.core.network.SCPacket; import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream; +import mc.core.world.Block; import mc.core.world.Chunk; import java.io.ByteArrayOutputStream; @@ -40,7 +41,7 @@ Packet structure | +------------------------------------------------+ | | | Chunk Section | Byte array | | - https://wiki.vg/Chunk_Format#Chunk_Section_structure | | +------------------------------------------+ | | -| | | Bits Per Block | Unsigned Byte | | | +| | | Bits Per Block | Unsigned Byte | | | (we use 4 bits per block) | | |--------------------|---------------------| | | | | | Palette | Byte array | | | - https://wiki.vg/Chunk_Format#Palettes | | | +------------------------------------+ | | | (we use Indirect type palette) @@ -53,9 +54,9 @@ Packet structure | | |--------------------|---------------------| | | | | | Data Array | Array of Long | | | | | |--------------------|---------------------| | | -| | | Block Light | Byte Array | | | +| | | Block Light | Byte Array | | | (Half byte per block) | | |--------------------|---------------------| | | -| | | Sky Light | Optional Byte Array | | | +| | | Sky Light | Optional Byte Array | | | (Only if in the Overworld; half byte per block) | | +------------------------------------------+ | | | |-----------------------|------------------------| | | | Biomes | Optional Byte array | | @@ -79,25 +80,86 @@ public class ChunkDataPacket implements SCPacket { @Getter private List chunks = new ArrayList<>(); + private long serializeBlockState(Block block) { + return (block.getId() << 4) | block.getState(); + } + @Override public void writeSelf(NetOutputStream netStream) { - netStream.writeInt(x); - netStream.writeInt(z); - netStream.writeBoolean(initChunk); + netStream.writeInt(x); // Chunk X + netStream.writeInt(z); // Chunk Y + netStream.writeBoolean(initChunk); // Init Chunk netStream.writeVarInt(0b11111111); // Primary Bit Mask - ByteArrayOutputNetStream baos = new ByteArrayOutputNetStream(); + final ByteArrayOutputNetStream data = new ByteArrayOutputNetStream(); + for (Chunk chunk : chunks) { - // - // - // - // - // - // + final List palette = new ArrayList<>(); + final ByteArrayOutputNetStream dataArray = new ByteArrayOutputNetStream(); + final ByteArrayOutputNetStream blockLight = new ByteArrayOutputNetStream(); + final ByteArrayOutputNetStream skyLight = new ByteArrayOutputNetStream(); + final ByteArrayOutputNetStream biomes = new ByteArrayOutputNetStream(); + + int blockLightCompacted = 0; + boolean flagFirstHalf = true; + + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + Block block = chunk.getBlock(x, y, z); + long blockState = serializeBlockState(block); + + int currentIndexPaletteBlock; + if (!palette.contains(blockState)) { + palette.add(blockState); + currentIndexPaletteBlock = palette.size()-1; + } else { + currentIndexPaletteBlock = palette.indexOf(blockState); + } + + dataArray.writeLong(currentIndexPaletteBlock); + if (flagFirstHalf) { + blockLightCompacted = block.getLight(); + flagFirstHalf = false; + } else { + blockLightCompacted = (blockLightCompacted << 4) | block.getLight(); + blockLight.writeByte(blockLightCompacted); + flagFirstHalf = true; + skyLight.writeByte(0b11111111); //FIXME + } + + biomes.writeByte(chunk.getBiome(x, z)); + } + } + } + + // + // + data.writeUnsignedByte(4); // Bits Per Block + data.writeVarInt(palette.size()); // Size of palette + palette.stream() + .mapToInt(Long::intValue) + .forEach(data::writeVarInt); // Palette + // + // + data.writeVarInt(dataArray.size()); // Size of Data Array + data.writeBytes(dataArray.toByteArray()); // Data Array + // + // + data.writeBytes(blockLight.toByteArray()); + // + // + data.writeBytes(skyLight.toByteArray()); + // + // + // + data.writeBytes(biomes.toByteArray()); + // } - netStream.writeVarInt(baos.size()); // Size of Data in bytes - netStream.writeBytes(baos.toByteArray()); // Data chunks - netStream.writeVarInt(0); // size NBT + + netStream.writeVarInt(data.size()); // Size of Data + netStream.writeBytes(data.toByteArray()); // Data + netStream.writeVarInt(0); // Number of block entities /* writeNBT */ } } From 2bc4e5e1b5ddbce1dc6bfc5698e2ff762d19ce9a Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 2 Aug 2018 16:27:02 +0300 Subject: [PATCH 4/5] stash 4 --- .../network/proto_1_12_2/netty/handlers/LoginHandler.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java index 4ceb337..a0c9591 100644 --- a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java @@ -88,6 +88,14 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand pkt8.setInitChunk(true); channel.writeAndFlush(pkt8); + // One Chunk + ChunkDataPacket pkt9 = new ChunkDataPacket(); + pkt9.setInitChunk(true); + pkt9.setX(0); + pkt9.setZ(0); + pkt9.getChunks().add(world.getChunk(0, 0)); + channel.writeAndFlush(pkt9); + // Player Position And Look PlayerPositionAndLookPacket pkt4 = new PlayerPositionAndLookPacket(); pkt4.setLocation(player.getLocation()); From 3ffd621e022c57e1c3169e10dbcf970b18f3d88e Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 2 Aug 2018 21:13:54 +0300 Subject: [PATCH 5/5] stash 5 --- .../main/java/mc/world/flat/SimpleBlock.java | 20 ++++++++++ .../main/java/mc/world/flat/SimpleChunk.java | 40 ++++++------------- 2 files changed, 33 insertions(+), 27 deletions(-) create mode 100644 flat_world/src/main/java/mc/world/flat/SimpleBlock.java diff --git a/flat_world/src/main/java/mc/world/flat/SimpleBlock.java b/flat_world/src/main/java/mc/world/flat/SimpleBlock.java new file mode 100644 index 0000000..5691732 --- /dev/null +++ b/flat_world/src/main/java/mc/world/flat/SimpleBlock.java @@ -0,0 +1,20 @@ +/* + * DmitriyMX + * 2018-08-02 + */ +package mc.world.flat; + +import lombok.Getter; +import lombok.Setter; +import mc.core.Location; +import mc.core.world.Block; + +@Getter +@Setter +public class SimpleBlock implements Block { + private int id; + private int state; + private int metadata; + private int light; + private Location location; +} diff --git a/flat_world/src/main/java/mc/world/flat/SimpleChunk.java b/flat_world/src/main/java/mc/world/flat/SimpleChunk.java index 5186615..a44c23a 100644 --- a/flat_world/src/main/java/mc/world/flat/SimpleChunk.java +++ b/flat_world/src/main/java/mc/world/flat/SimpleChunk.java @@ -4,40 +4,26 @@ */ package mc.world.flat; +import mc.core.world.Block; import mc.core.world.Chunk; public class SimpleChunk implements Chunk { @Override - public int getBlockType(int x, int y, int z) { - if (y == 0) return 7; - else if (y >= 1 && y <= 2) return 3; - else if (y == 3) return 2; - else return 0; + public Block getBlock(int x, int y, int z) { + SimpleBlock block = new SimpleBlock(); + block.setMetadata(0); + block.setLight(0); + + if (y == 0) block.setId(7); + else if (y >= 1 && y <= 2) block.setId(3); + else if (y == 3) block.setId(2); + else block.setId(0); + + return block; } @Override - public void setBlockType(int x, int y, int z, int type) { - - } - - @Override - public int getBlockMetadata(int x, int y, int z) { - return 0; - } - - @Override - public void setBlockMetadata(int x, int y, int z, int metadata) { - - } - - @Override - public int getBlockLight(int x, int y, int z) { - return 0; - } - - @Override - public void setBlockLight(int x, int y, int z, int lightLevel) { - + public void setBlock(Block block) { } @Override