mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
chunk parsing 1.9
This commit is contained in:
parent
2fea59f5d0
commit
2fe88acd12
@ -131,6 +131,6 @@ public enum Blocks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getData() {
|
public int getData() {
|
||||||
return id;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,4 +141,10 @@ public class World {
|
|||||||
public CompoundTag getBlockEntityData(BlockPosition position) {
|
public CompoundTag getBlockEntityData(BlockPosition position) {
|
||||||
return blockEntityMeta.get(position);
|
return blockEntityMeta.get(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBlockEntityData(HashMap<BlockPosition, CompoundTag> blockEntities) {
|
||||||
|
for (Map.Entry<BlockPosition, CompoundTag> entrySet : blockEntities.entrySet()) {
|
||||||
|
blockEntityMeta.put(entrySet.getKey(), entrySet.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ public class Network {
|
|||||||
boolean success = packet.read(inPacketBuffer);
|
boolean success = packet.read(inPacketBuffer);
|
||||||
if (inPacketBuffer.getBytesLeft() > 0 || !success) {
|
if (inPacketBuffer.getBytesLeft() > 0 || !success) {
|
||||||
// warn not all data used
|
// warn not all data used
|
||||||
Log.warn(String.format("[IN] Could not parse packet %s completely (used=%d, available=%d, total=%d)", ((p != null) ? p.name() : "null"), inPacketBuffer.getPosition(), inPacketBuffer.getBytesLeft(), inPacketBuffer.getLength()));
|
Log.warn(String.format("[IN] Could not parse packet %s (used=%d, available=%d, total=%d, success=%s)", ((p != null) ? p.name() : "null"), inPacketBuffer.getPosition(), inPacketBuffer.getBytesLeft(), inPacketBuffer.getLength(), success));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,11 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.protocol.packets.clientbound.play;
|
package de.bixilon.minosoft.protocol.packets.clientbound.play;
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
|
||||||
import de.bixilon.minosoft.game.datatypes.world.Chunk;
|
import de.bixilon.minosoft.game.datatypes.world.Chunk;
|
||||||
import de.bixilon.minosoft.game.datatypes.world.ChunkLocation;
|
import de.bixilon.minosoft.game.datatypes.world.ChunkLocation;
|
||||||
import de.bixilon.minosoft.logging.Log;
|
import de.bixilon.minosoft.logging.Log;
|
||||||
|
import de.bixilon.minosoft.nbt.tag.CompoundTag;
|
||||||
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
|
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
|
||||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||||
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
|
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
|
||||||
@ -23,10 +25,13 @@ import de.bixilon.minosoft.protocol.protocol.PacketHandler;
|
|||||||
import de.bixilon.minosoft.util.ChunkUtil;
|
import de.bixilon.minosoft.util.ChunkUtil;
|
||||||
import de.bixilon.minosoft.util.Util;
|
import de.bixilon.minosoft.util.Util;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class PacketChunkData implements ClientboundPacket {
|
public class PacketChunkData implements ClientboundPacket {
|
||||||
ChunkLocation location;
|
ChunkLocation location;
|
||||||
Chunk chunk;
|
Chunk chunk;
|
||||||
|
|
||||||
|
HashMap<BlockPosition, CompoundTag> blockEntities = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean read(InPacketBuffer buffer) {
|
public boolean read(InPacketBuffer buffer) {
|
||||||
@ -55,16 +60,16 @@ public class PacketChunkData implements ClientboundPacket {
|
|||||||
case VERSION_1_9_4: {
|
case VERSION_1_9_4: {
|
||||||
this.location = new ChunkLocation(buffer.readInteger(), buffer.readInteger());
|
this.location = new ChunkLocation(buffer.readInteger(), buffer.readInteger());
|
||||||
boolean groundUpContinuous = buffer.readBoolean();
|
boolean groundUpContinuous = buffer.readBoolean();
|
||||||
short sectionBitMask = buffer.readShort();
|
short sectionBitMask = (short) buffer.readVarInt();
|
||||||
int size = buffer.readVarInt();
|
int size = buffer.readVarInt();
|
||||||
|
|
||||||
chunk = ChunkUtil.readChunkPacket(buffer, sectionBitMask, (short) 0, groundUpContinuous, true);
|
chunk = ChunkUtil.readChunkPacket(buffer, sectionBitMask, (short) 0, groundUpContinuous, true);
|
||||||
int blockEntities = buffer.readVarInt();
|
int blockEntitiesCount = buffer.readVarInt();
|
||||||
for (int i = 0; i < blockEntities; i++) {
|
for (int i = 0; i < blockEntitiesCount; i++) {
|
||||||
buffer.readNBT();
|
CompoundTag tag = buffer.readNBT();
|
||||||
//ToDo
|
blockEntities.put(new BlockPosition(tag.getIntTag("x").getValue(), (short) tag.getIntTag("y").getValue(), tag.getIntTag("z").getValue()), tag);
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +90,10 @@ public class PacketChunkData implements ClientboundPacket {
|
|||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HashMap<BlockPosition, CompoundTag> getBlockEntities() {
|
||||||
|
return blockEntities;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(PacketHandler h) {
|
public void handle(PacketHandler h) {
|
||||||
h.handle(this);
|
h.handle(this);
|
||||||
|
@ -300,6 +300,8 @@ public class PacketHandler {
|
|||||||
|
|
||||||
public void handle(PacketChunkData pkg) {
|
public void handle(PacketChunkData pkg) {
|
||||||
connection.getPlayer().getWorld().setChunk(pkg.getLocation(), pkg.getChunk());
|
connection.getPlayer().getWorld().setChunk(pkg.getLocation(), pkg.getChunk());
|
||||||
|
connection.getPlayer().getWorld().setBlockEntityData(pkg.getBlockEntities());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle(PacketEntityEffect pkg) {
|
public void handle(PacketEntityEffect pkg) {
|
||||||
|
@ -135,8 +135,7 @@ public class ChunkUtil {
|
|||||||
return new Chunk(nibbleMap);
|
return new Chunk(nibbleMap);
|
||||||
}
|
}
|
||||||
case VERSION_1_9_4: {
|
case VERSION_1_9_4: {
|
||||||
byte sections = BitByte.getBitCount(sectionBitMask);
|
// really big thanks to: https://wiki.vg/index.php?title=Chunk_Format&oldid=13712
|
||||||
|
|
||||||
HashMap<Byte, ChunkNibble> nibbleMap = new HashMap<>();
|
HashMap<Byte, ChunkNibble> nibbleMap = new HashMap<>();
|
||||||
for (byte c = 0; c < 16; c++) { // max sections per chunks in chunk column
|
for (byte c = 0; c < 16; c++) { // max sections per chunks in chunk column
|
||||||
if (!BitByte.isBitSet(sectionBitMask, c)) {
|
if (!BitByte.isBitSet(sectionBitMask, c)) {
|
||||||
@ -144,34 +143,66 @@ public class ChunkUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
byte bitsPerBlock = buffer.readByte();
|
byte bitsPerBlock = buffer.readByte();
|
||||||
int[] palette = new int[buffer.readVarInt()];
|
if (bitsPerBlock < 4) {
|
||||||
for (int i = 0; i < palette.length; i++) {
|
bitsPerBlock = 4;
|
||||||
palette[i] = buffer.readVarInt();
|
} else if (bitsPerBlock > 8) {
|
||||||
|
bitsPerBlock = 13;
|
||||||
}
|
}
|
||||||
|
boolean usePalette = (bitsPerBlock <= 8);
|
||||||
|
|
||||||
|
int[] palette = null;
|
||||||
|
if (usePalette) {
|
||||||
|
palette = new int[buffer.readVarInt()];
|
||||||
|
for (int i = 0; i < palette.length; i++) {
|
||||||
|
palette[i] = buffer.readVarInt();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buffer.readVarInt();
|
||||||
|
}
|
||||||
|
int individualValueMask = ((1 << bitsPerBlock) - 1);
|
||||||
|
|
||||||
long[] data = buffer.readLongs(buffer.readVarInt());
|
long[] data = buffer.readLongs(buffer.readVarInt());
|
||||||
|
|
||||||
HashMap<ChunkNibbleLocation, Blocks> blockMap = new HashMap<>();
|
HashMap<ChunkNibbleLocation, Blocks> blockMap = new HashMap<>();
|
||||||
int blocks = 0;
|
|
||||||
/*
|
|
||||||
for (int nibbleY = 0; nibbleY < 16; nibbleY++) {
|
for (int nibbleY = 0; nibbleY < 16; nibbleY++) {
|
||||||
for (int nibbleZ = 0; nibbleZ < 16; nibbleZ++) {
|
for (int nibbleZ = 0; nibbleZ < 16; nibbleZ++) {
|
||||||
for (int nibbleX = 0; nibbleX < 16; nibbleX++) {
|
for (int nibbleX = 0; nibbleX < 16; nibbleX++) {
|
||||||
Blocks block = Blocks.byId(blockData[arrayPos] >>> 4, blockData[arrayPos] & 0xF);
|
|
||||||
|
|
||||||
|
int blockNumber = (((nibbleY * 16) + nibbleZ) * 16) + nibbleX;
|
||||||
|
int startLong = (blockNumber * bitsPerBlock) / 64;
|
||||||
|
int startOffset = (blockNumber * bitsPerBlock) % 64;
|
||||||
|
int endLong = ((blockNumber + 1) * bitsPerBlock - 1) / 64;
|
||||||
|
|
||||||
|
|
||||||
|
int blockId;
|
||||||
|
if (startLong == endLong) {
|
||||||
|
blockId = (int) (data[startLong] >>> startOffset);
|
||||||
|
} else {
|
||||||
|
int endOffset = 64 - startOffset;
|
||||||
|
blockId = (int) (data[startLong] >>> startOffset | data[endLong] << endOffset);
|
||||||
|
}
|
||||||
|
blockId &= individualValueMask;
|
||||||
|
|
||||||
|
if (usePalette) {
|
||||||
|
// data should always be within the palette length
|
||||||
|
// If you're reading a power of 2 minus one (15, 31, 63, 127, etc...) that's out of bounds,
|
||||||
|
// you're probably reading light data instead
|
||||||
|
blockId = palette[blockId];
|
||||||
|
}
|
||||||
|
|
||||||
|
Blocks block = Blocks.byId(blockId >>> 4, blockId & 0xF);
|
||||||
if (block == Blocks.AIR) {
|
if (block == Blocks.AIR) {
|
||||||
arrayPos++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
blockMap.put(new ChunkNibbleLocation(nibbleX, nibbleY, nibbleZ), block);
|
blockMap.put(new ChunkNibbleLocation(nibbleX, nibbleY, nibbleZ), block);
|
||||||
arrayPos++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
byte[] light = buffer.readBytes(2048);
|
||||||
|
|
||||||
byte[] light = buffer.readBytes(blocks / 2);
|
|
||||||
if (containsSkyLight) {
|
if (containsSkyLight) {
|
||||||
byte[] skyLight = buffer.readBytes(blocks / 2);
|
byte[] skyLight = buffer.readBytes(2048);
|
||||||
}
|
}
|
||||||
|
|
||||||
nibbleMap.put(c, new ChunkNibble(blockMap));
|
nibbleMap.put(c, new ChunkNibble(blockMap));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user