Merge & resolve conflicts
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -14,17 +14,16 @@ import java.util.UUID;
|
||||
public abstract class NetOutputStream_p340 extends NetOutputStream {
|
||||
@Override
|
||||
public void writeVarInt(int value) {
|
||||
do {
|
||||
byte temp = (byte)(value & 0b01111111);
|
||||
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
|
||||
while ((value & -128) != 0) {
|
||||
writeByte(value & 127 | 128);
|
||||
value >>>= 7;
|
||||
if (value != 0) {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
writeByte(temp);
|
||||
} while (value != 0);
|
||||
}
|
||||
|
||||
writeByte(value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void writeString(String value) {
|
||||
if (value.length() > Short.MAX_VALUE) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* DmitriyMX <dimon550@gmail.com>
|
||||
* 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.network.proto_1_12_2.ByteArrayOutputNetStream;
|
||||
import mc.core.world.ChunkSection;
|
||||
import mc.core.world.block.Block;
|
||||
|
||||
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 | | | (we use 4 bits per block)
|
||||
| | |--------------------|---------------------| | |
|
||||
| | | 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 | | | (Half byte per block)
|
||||
| | |--------------------|---------------------| | |
|
||||
| | | Sky Light | Optional Byte Array | | | (Only if in the Overworld; half byte per block)
|
||||
| | +------------------------------------------+ | |
|
||||
| |-----------------------|------------------------| |
|
||||
| | Biomes | Optional Byte array | |
|
||||
| +------------------------------------------------+ |
|
||||
|--------------------------|---------------------------|
|
||||
| Number of block entities | VarInt |
|
||||
|--------------------------|---------------------------|
|
||||
| Block entities | Array of NBT |
|
||||
+------------------------------------------------------+
|
||||
*/
|
||||
|
||||
@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<ChunkSection> chunks = new ArrayList<>();
|
||||
|
||||
private int serializeBlockState(int id, int meta) {
|
||||
return (id << 4) | meta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSelf(NetOutputStream netStream) {
|
||||
netStream.writeInt(x); // Chunk X
|
||||
netStream.writeInt(z); // Chunk Y
|
||||
netStream.writeBoolean(initChunk); // Init Chunk
|
||||
netStream.writeVarInt(0b00000001); // Primary Bit Mask
|
||||
|
||||
final ByteArrayOutputNetStream data = new ByteArrayOutputNetStream();
|
||||
int dataItems = 0;
|
||||
final int airBlockPalette = serializeBlockState(0, 0);
|
||||
|
||||
for (ChunkSection chunk : chunks) {
|
||||
final List<Integer> palette = new ArrayList<>();
|
||||
palette.add(airBlockPalette);
|
||||
final ByteArrayOutputNetStream dataArray = new ByteArrayOutputNetStream();
|
||||
final ByteArrayOutputNetStream blockLight = new ByteArrayOutputNetStream();
|
||||
final ByteArrayOutputNetStream skyLight = new ByteArrayOutputNetStream();
|
||||
final ByteArrayOutputNetStream biomes = new ByteArrayOutputNetStream();
|
||||
|
||||
long dataValueCompacted = 0;
|
||||
int blockLightCompacted = 0;
|
||||
int skyLightCompacted = 0;
|
||||
|
||||
int idxHalfLong = 0;
|
||||
int idxHalfByte = 0;
|
||||
boolean biomeFinally = false;
|
||||
|
||||
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);
|
||||
int blockState = serializeBlockState(block.getId(), block.getMeta());
|
||||
|
||||
int currentIndexPaletteBlock;
|
||||
if (!palette.contains(blockState)) {
|
||||
palette.add(blockState);
|
||||
currentIndexPaletteBlock = palette.size()-1;
|
||||
} else {
|
||||
currentIndexPaletteBlock = palette.indexOf(blockState);
|
||||
}
|
||||
|
||||
if (idxHalfLong == 0) {
|
||||
dataValueCompacted = currentIndexPaletteBlock;
|
||||
idxHalfLong++;
|
||||
} else if (idxHalfLong > 0 && idxHalfLong < 15) {
|
||||
dataValueCompacted = (dataValueCompacted << 4) | currentIndexPaletteBlock;
|
||||
idxHalfLong++;
|
||||
} else {
|
||||
dataValueCompacted = (dataValueCompacted << 4) | currentIndexPaletteBlock;
|
||||
dataArray.writeLong(dataValueCompacted);
|
||||
idxHalfLong = 0;
|
||||
dataItems++;
|
||||
}
|
||||
|
||||
if (idxHalfByte == 0) {
|
||||
blockLightCompacted = block.getLight();
|
||||
skyLightCompacted = chunk.getSkyLight(x, y, z);
|
||||
idxHalfByte++;
|
||||
} else {
|
||||
blockLightCompacted = (blockLightCompacted << 4) | block.getLight();
|
||||
blockLight.writeByte(blockLightCompacted);
|
||||
skyLightCompacted = (skyLightCompacted << 4) | chunk.getSkyLight(x, y, z);
|
||||
skyLight.writeByte(skyLightCompacted);
|
||||
idxHalfByte = 0;
|
||||
}
|
||||
|
||||
if (!biomeFinally) {
|
||||
biomes.writeByte(chunk.getBiome(x, z).getId());
|
||||
if (x == 15 && z == 15) {
|
||||
biomeFinally = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <Chunk Section>
|
||||
// <Palette>
|
||||
data.writeUnsignedByte(4); // Bits Per Block
|
||||
data.writeVarInt(palette.size()); // Size of palette
|
||||
palette.forEach(data::writeVarInt); // Palette
|
||||
// </Palette>
|
||||
// <Data Array>
|
||||
data.writeVarInt(dataItems); // Size of Data Array
|
||||
data.writeBytes(dataArray.toByteArray()); // Data Array
|
||||
// </Data Array>
|
||||
// <Block Light>
|
||||
data.writeBytes(blockLight.toByteArray());
|
||||
// </Block Light>
|
||||
// <Sky Light>
|
||||
data.writeBytes(skyLight.toByteArray());
|
||||
// </Sky Light>
|
||||
// </Chunk Section>
|
||||
// <Biomes>
|
||||
data.writeBytes(biomes.toByteArray());
|
||||
// </Biomes>
|
||||
}
|
||||
|
||||
netStream.writeVarInt(data.size()); // Size of Data
|
||||
netStream.writeBytes(data.toByteArray()); // Data
|
||||
netStream.writeVarInt(0); // Number of block entities
|
||||
/* writeNBT */
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user