mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-14 18:05:51 -04:00
1.14.4 chunk parsing
This commit is contained in:
parent
5aad04d578
commit
be852e24e5
@ -497,6 +497,11 @@ public class Blocks {
|
|||||||
blockList.add(block);
|
blockList.add(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set nullBlock
|
||||||
|
if (block.getIdentifier().equals("air")) {
|
||||||
|
nullBlock = block;
|
||||||
|
}
|
||||||
|
|
||||||
int blockId = getBlockId(statesJSON, version);
|
int blockId = getBlockId(statesJSON, version);
|
||||||
checkAndCrashIfBlockIsIn(blockId, identifierName, versionMapping, version);
|
checkAndCrashIfBlockIsIn(blockId, identifierName, versionMapping, version);
|
||||||
versionMapping.put(blockId, block);
|
versionMapping.put(blockId, block);
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Codename Minosoft
|
||||||
|
* Copyright (C) 2020 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.game.datatypes.world.palette;
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.game.datatypes.blocks.Block;
|
||||||
|
import de.bixilon.minosoft.game.datatypes.blocks.Blocks;
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
||||||
|
|
||||||
|
public class DirectPalette implements Palette {
|
||||||
|
ProtocolVersion version;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Block byId(int id) {
|
||||||
|
return Blocks.getBlock(id, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getBitsPerBlock() {
|
||||||
|
switch (version) {
|
||||||
|
case VERSION_1_9_4:
|
||||||
|
case VERSION_1_10:
|
||||||
|
case VERSION_1_11_2:
|
||||||
|
case VERSION_1_12_2:
|
||||||
|
return 13;
|
||||||
|
case VERSION_1_13_2:
|
||||||
|
case VERSION_1_14_4:
|
||||||
|
return 14;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(InByteBuffer buffer) {
|
||||||
|
this.version = buffer.getVersion();
|
||||||
|
buffer.readVarInt();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Codename Minosoft
|
||||||
|
* Copyright (C) 2020 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.game.datatypes.world.palette;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashBiMap;
|
||||||
|
import de.bixilon.minosoft.game.datatypes.blocks.Block;
|
||||||
|
import de.bixilon.minosoft.game.datatypes.blocks.Blocks;
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
||||||
|
|
||||||
|
public class IndirectPalette implements Palette {
|
||||||
|
ProtocolVersion version;
|
||||||
|
HashBiMap<Integer, Integer> map = HashBiMap.create();
|
||||||
|
byte bitsPerBlock;
|
||||||
|
|
||||||
|
public IndirectPalette(byte bitsPerBlock) {
|
||||||
|
this.bitsPerBlock = bitsPerBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Block byId(int id) {
|
||||||
|
Block block;
|
||||||
|
if (map.containsKey(id)) {
|
||||||
|
block = Blocks.getBlock(map.get(id), version);
|
||||||
|
} else {
|
||||||
|
block = Blocks.getBlock(id, version);
|
||||||
|
}
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getBitsPerBlock() {
|
||||||
|
return bitsPerBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(InByteBuffer buffer) {
|
||||||
|
this.version = buffer.getVersion();
|
||||||
|
switch (version) {
|
||||||
|
case VERSION_1_9_4:
|
||||||
|
case VERSION_1_10:
|
||||||
|
case VERSION_1_11_2:
|
||||||
|
case VERSION_1_12_2:
|
||||||
|
case VERSION_1_13_2:
|
||||||
|
case VERSION_1_14_4: {
|
||||||
|
int paletteLength = buffer.readVarInt();
|
||||||
|
for (int i = 0; i < paletteLength; i++) {
|
||||||
|
map.put(i, buffer.readVarInt());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Codename Minosoft
|
||||||
|
* Copyright (C) 2020 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.game.datatypes.world.palette;
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.game.datatypes.blocks.Block;
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||||
|
|
||||||
|
public interface Palette {
|
||||||
|
static Palette choosePalette(byte bitsPerBlock) {
|
||||||
|
if (bitsPerBlock <= 4) {
|
||||||
|
return new IndirectPalette((byte) 4);
|
||||||
|
} else if (bitsPerBlock <= 8) {
|
||||||
|
return new IndirectPalette(bitsPerBlock);
|
||||||
|
}
|
||||||
|
return new DirectPalette();
|
||||||
|
}
|
||||||
|
|
||||||
|
Block byId(int id);
|
||||||
|
|
||||||
|
byte getBitsPerBlock();
|
||||||
|
|
||||||
|
void read(InByteBuffer buffer);
|
||||||
|
}
|
@ -23,6 +23,7 @@ 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;
|
||||||
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
|
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
||||||
import de.bixilon.minosoft.util.ChunkUtil;
|
import de.bixilon.minosoft.util.ChunkUtil;
|
||||||
import de.bixilon.minosoft.util.Util;
|
import de.bixilon.minosoft.util.Util;
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ import java.util.HashMap;
|
|||||||
public class PacketChunkData implements ClientboundPacket {
|
public class PacketChunkData implements ClientboundPacket {
|
||||||
ChunkLocation location;
|
ChunkLocation location;
|
||||||
Chunk chunk;
|
Chunk chunk;
|
||||||
|
CompoundTag heightMap;
|
||||||
|
|
||||||
HashMap<BlockPosition, CompoundTag> blockEntities = new HashMap<>();
|
HashMap<BlockPosition, CompoundTag> blockEntities = new HashMap<>();
|
||||||
|
|
||||||
@ -70,10 +72,14 @@ public class PacketChunkData implements ClientboundPacket {
|
|||||||
case VERSION_1_10:
|
case VERSION_1_10:
|
||||||
case VERSION_1_11_2:
|
case VERSION_1_11_2:
|
||||||
case VERSION_1_12_2:
|
case VERSION_1_12_2:
|
||||||
case VERSION_1_13_2: {
|
case VERSION_1_13_2:
|
||||||
|
case VERSION_1_14_4: {
|
||||||
this.location = new ChunkLocation(buffer.readInt(), buffer.readInt());
|
this.location = new ChunkLocation(buffer.readInt(), buffer.readInt());
|
||||||
boolean groundUpContinuous = buffer.readBoolean();
|
boolean groundUpContinuous = buffer.readBoolean();
|
||||||
short sectionBitMask = (short) buffer.readVarInt();
|
short sectionBitMask = (short) buffer.readVarInt();
|
||||||
|
if (buffer.getVersion().getVersionNumber() >= ProtocolVersion.VERSION_1_14_4.getVersionNumber()) {
|
||||||
|
heightMap = buffer.readNBT();
|
||||||
|
}
|
||||||
int size = buffer.readVarInt();
|
int size = buffer.readVarInt();
|
||||||
int lastPos = buffer.getPosition();
|
int lastPos = buffer.getPosition();
|
||||||
|
|
||||||
@ -109,6 +115,10 @@ public class PacketChunkData implements ClientboundPacket {
|
|||||||
return blockEntities;
|
return blockEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CompoundTag getHeightMap() {
|
||||||
|
return heightMap;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(PacketHandler h) {
|
public void handle(PacketHandler h) {
|
||||||
h.handle(this);
|
h.handle(this);
|
||||||
|
@ -48,6 +48,7 @@ public class PacketTags implements ClientboundPacket {
|
|||||||
Tag[] ret = new Tag[buffer.readVarInt()];
|
Tag[] ret = new Tag[buffer.readVarInt()];
|
||||||
switch (buffer.getVersion()) {
|
switch (buffer.getVersion()) {
|
||||||
case VERSION_1_13_2:
|
case VERSION_1_13_2:
|
||||||
|
case VERSION_1_14_4:
|
||||||
for (int i = 0; i < ret.length; i++) {
|
for (int i = 0; i < ret.length; i++) {
|
||||||
ret[i] = new Tag(buffer.readString(), buffer.readVarIntArray(buffer.readVarInt()));
|
ret[i] = new Tag(buffer.readString(), buffer.readVarIntArray(buffer.readVarInt()));
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import de.bixilon.minosoft.game.datatypes.blocks.Blocks;
|
|||||||
import de.bixilon.minosoft.game.datatypes.world.Chunk;
|
import de.bixilon.minosoft.game.datatypes.world.Chunk;
|
||||||
import de.bixilon.minosoft.game.datatypes.world.ChunkNibble;
|
import de.bixilon.minosoft.game.datatypes.world.ChunkNibble;
|
||||||
import de.bixilon.minosoft.game.datatypes.world.ChunkNibbleLocation;
|
import de.bixilon.minosoft.game.datatypes.world.ChunkNibbleLocation;
|
||||||
|
import de.bixilon.minosoft.game.datatypes.world.palette.Palette;
|
||||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
|
||||||
|
|
||||||
@ -148,32 +149,20 @@ public class ChunkUtil {
|
|||||||
case VERSION_1_10:
|
case VERSION_1_10:
|
||||||
case VERSION_1_11_2:
|
case VERSION_1_11_2:
|
||||||
case VERSION_1_12_2:
|
case VERSION_1_12_2:
|
||||||
case VERSION_1_13_2: {
|
case VERSION_1_13_2:
|
||||||
|
case VERSION_1_14_4: {
|
||||||
// really big thanks to: https://wiki.vg/index.php?title=Chunk_Format&oldid=13712
|
// 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)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (buffer.getVersion().getVersionNumber() >= ProtocolVersion.VERSION_1_14_4.getVersionNumber()) {
|
||||||
byte bitsPerBlock = buffer.readByte();
|
buffer.readShort(); // block count
|
||||||
if (bitsPerBlock < 4) {
|
|
||||||
bitsPerBlock = 4;
|
|
||||||
} else if (bitsPerBlock > 8) {
|
|
||||||
bitsPerBlock = (byte) ((buffer.getVersion().getVersionNumber() >= ProtocolVersion.VERSION_1_13_2.getVersionNumber()) ? 14 : 13);
|
|
||||||
}
|
}
|
||||||
boolean usePalette = (bitsPerBlock <= 8);
|
Palette palette = Palette.choosePalette(buffer.readByte());
|
||||||
|
palette.read(buffer);
|
||||||
int[] palette = null;
|
int individualValueMask = ((1 << palette.getBitsPerBlock()) - 1);
|
||||||
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());
|
||||||
|
|
||||||
@ -184,9 +173,9 @@ public class ChunkUtil {
|
|||||||
|
|
||||||
|
|
||||||
int blockNumber = (((nibbleY * 16) + nibbleZ) * 16) + nibbleX;
|
int blockNumber = (((nibbleY * 16) + nibbleZ) * 16) + nibbleX;
|
||||||
int startLong = (blockNumber * bitsPerBlock) / 64;
|
int startLong = (blockNumber * palette.getBitsPerBlock()) / 64;
|
||||||
int startOffset = (blockNumber * bitsPerBlock) % 64;
|
int startOffset = (blockNumber * palette.getBitsPerBlock()) % 64;
|
||||||
int endLong = ((blockNumber + 1) * bitsPerBlock - 1) / 64;
|
int endLong = ((blockNumber + 1) * palette.getBitsPerBlock() - 1) / 64;
|
||||||
|
|
||||||
|
|
||||||
int blockId;
|
int blockId;
|
||||||
@ -198,19 +187,7 @@ public class ChunkUtil {
|
|||||||
}
|
}
|
||||||
blockId &= individualValueMask;
|
blockId &= individualValueMask;
|
||||||
|
|
||||||
if (usePalette) {
|
Block block = palette.byId(blockId);
|
||||||
// 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];
|
|
||||||
}
|
|
||||||
Block block;
|
|
||||||
if (buffer.getVersion().getVersionNumber() >= ProtocolVersion.VERSION_1_13_2.getVersionNumber()) {
|
|
||||||
// no meta data anymore
|
|
||||||
block = Blocks.getBlock(blockId, buffer.getVersion());
|
|
||||||
} else {
|
|
||||||
block = Blocks.getBlockByLegacy(blockId >>> 4, blockId & 0xF);
|
|
||||||
}
|
|
||||||
if (block == Blocks.nullBlock) {
|
if (block == Blocks.nullBlock) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -219,9 +196,11 @@ public class ChunkUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] light = buffer.readBytes(2048);
|
if (buffer.getVersion().getVersionNumber() < ProtocolVersion.VERSION_1_14_4.getVersionNumber()) {
|
||||||
if (containsSkyLight) {
|
byte[] light = buffer.readBytes(2048);
|
||||||
byte[] skyLight = buffer.readBytes(2048);
|
if (containsSkyLight) {
|
||||||
|
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