Archived
0

обработка NBT в чанках

This commit is contained in:
2018-12-23 21:14:48 +03:00
parent d783317b5d
commit bd0d762df5
14 changed files with 209 additions and 17 deletions

View File

@@ -1,13 +1,18 @@
package mc.core.network.proto_1_12_2;
import com.flowpowered.nbt.Tag;
import com.flowpowered.nbt.stream.NBTInputStream;
import lombok.extern.slf4j.Slf4j;
import mc.core.network.NetInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
@Slf4j
public abstract class NetInputStream_p340 extends NetInputStream {
private NBTInputStream nbtInputStream;
@Override
public int readVarInt(int[] countReadBytes) {
int numRead = 0;
@@ -51,4 +56,23 @@ public abstract class NetInputStream_p340 extends NetInputStream {
public UUID readUUID() {
return new UUID(readLong(), readLong());
}
@Override
public Tag<?> readNBT() {
if (nbtInputStream == null) {
try {
nbtInputStream = new NBTInputStream(this, false);
} catch (IOException e) {
log.error("Create NBT stream", e);
return null;
}
}
try {
return nbtInputStream.readTag();
} catch (IOException e) {
log.error("Read NBT", e);
return null;
}
}
}

View File

@@ -1,13 +1,18 @@
package mc.core.network.proto_1_12_2;
import com.flowpowered.nbt.Tag;
import com.flowpowered.nbt.stream.NBTOutputStream;
import lombok.extern.slf4j.Slf4j;
import mc.core.network.NetOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
@Slf4j
public abstract class NetOutputStream_p340 extends NetOutputStream {
private NBTOutputStream nbtOutputStream;
@Override
public void writeVarInt(int value) {
while ((value & -128) != 0) {
@@ -37,4 +42,22 @@ public abstract class NetOutputStream_p340 extends NetOutputStream {
writeLong(uuid.getMostSignificantBits());
writeLong(uuid.getLeastSignificantBits());
}
@Override
public void writeNBT(Tag<?> tag) {
if (nbtOutputStream == null) {
try {
nbtOutputStream = new NBTOutputStream(this, false);
} catch (IOException e) {
log.error("Create NBT stream", e);
return;
}
}
try {
nbtOutputStream.writeTag(tag);
} catch (IOException e) {
log.error("Write NBT", e);
}
}
}

View File

@@ -1,5 +1,6 @@
package mc.core.network.proto_1_12_2.packets;
import com.flowpowered.nbt.CompoundTag;
import gnu.trove.list.TIntList;
import gnu.trove.list.array.TIntArrayList;
import lombok.NoArgsConstructor;
@@ -15,6 +16,7 @@ import mc.core.world.block.BlockType;
import mc.core.world.chunk.Chunk;
import mc.core.world.chunk.ChunkSection;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@@ -133,6 +135,8 @@ public class ChunkDataPacket implements SCPacket {
final ByteArrayOutputNetStream biomes = new ByteArrayOutputNetStream();
boolean biomeWrite = true;
List<CompoundTag> nbtList = new ArrayList<>();
for (int h = 0; h < maxH; h++) {
ChunkSection chunkSection = null;
@@ -151,11 +155,18 @@ public class ChunkDataPacket implements SCPacket {
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
Block block = chunkSection.getBlockLocal(x, y, z);
palettedChunkSection.addBlock(
chunkSection.getBlockLocal(x, y, z),
block,
chunkSection.getSkyLightLocal(x, y, z)
);
CompoundTag nbt = block.getNBTData();
if (nbt != null) {
nbtList.add(nbt);
}
if (biomeWrite) {
biomes.writeByte(chunk.getBiomeLocal(x, z).getId());
if (x == 15 && z == 15) {
@@ -176,8 +187,12 @@ public class ChunkDataPacket implements SCPacket {
netStream.writeVarInt(data.size()); // Size of Data
netStream.writeBytes(data.toByteArray()); // Data
netStream.writeVarInt(0); // Number of block entities
/* writeNBT */
netStream.writeVarInt(nbtList.size()); // Number of block entities
// <NBT>
for (CompoundTag compoundTag : nbtList) {
netStream.writeNBT(compoundTag);
}
// </NBT>
}
@Override

View File

@@ -1,10 +1,10 @@
package mc.core.network.proto_1_12_2.packets;
import com.flowpowered.nbt.*;
import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream;
import mc.core.network.proto_1_12_2.packets.DumbChunkData.DumbChunkSection;
import mc.core.world.Biome;
import mc.core.world.block.BlockFactory;
import mc.core.world.block.BlockType;
import mc.core.world.block.*;
import mc.core.world.chunk.Chunk;
import mc.core.world.chunk.ChunkSection;
import org.apache.commons.io.IOUtils;
@@ -72,6 +72,29 @@ class ChunkDataPacketTest {
setupActualData();
}
private static Block createChestBlock(BlockType type, int x, int y, int z, int height) {
final BlockLocation location = new BlockLocation(x, y, z);
final CompoundMap compoundMap = new CompoundMap();
compoundMap.put(new IntTag("x", x));
compoundMap.put(new IntTag("y", (height << 4) + y));
compoundMap.put(new IntTag("z", z));
compoundMap.put(new StringTag("id", type.getNamedId()));
final CompoundTag compoundTag = new CompoundTag("", compoundMap);
return new AbstractBlock(type) {
@Override
public BlockLocation getLocation() {
return location;
}
@Override
public CompoundTag getNBTData() {
return compoundTag;
}
};
}
private static ChunkSection createChunkSection(int height) {
final ChunkSection chunkSection = mock(ChunkSection.class);
when(chunkSection.getSkyLightLocal(anyInt(), anyInt(), anyInt())).thenReturn(0);
@@ -107,13 +130,23 @@ class ChunkDataPacketTest {
BlockFactory blockFactory = new BlockFactory();
if (y == 0) {
return blockFactory.create(BlockType.DIRT, x, y, z);
} else if (y == 1) {
return blockFactory.create(BlockType.GRASS, x, y, z);
} else {
return blockFactory.create(BlockType.AIR, x, y, z);
// @formatter:off
if (y == 0) return blockFactory.create(BlockType.DIRT, x, y, z);
else if (y == 1) return blockFactory.create(BlockType.GRASS, x, y, z);
else if (y == 2) {
if ((x == 2 || x == 4 || x == 5) && z == 1)
return createChestBlock(BlockType.CHEST_NORTH, x, y, z, height);
else if ((x == 2 || x == 3 || x == 5) && z == 6)
return createChestBlock(BlockType.CHEST_SOUTH, x, y, z, height);
else if (x == 1 && (z == 2 || z == 3 || z == 5))
return createChestBlock(BlockType.CHEST_WEST, x, y, z, height);
else if (x == 6 && (z == 2 || z == 4 || z == 5))
return createChestBlock(BlockType.CHEST_EAST, x, y, z, height);
else
return blockFactory.create(BlockType.AIR, x, y, z);
}
else return blockFactory.create(BlockType.AIR, x, y, z);
// @formatter:on
});
}
@@ -132,6 +165,11 @@ class ChunkDataPacketTest {
@Test
void testNBT() {
assertEquals(expectedDumbChunkData.getNumberNBT(), actualDumbChunkData.getNumberNBT());
assertEquals(expectedDumbChunkData.getNbt().size(), actualDumbChunkData.getNbt().size());
for (Tag<?> tag : actualDumbChunkData.getNbt()) {
assertTrue(expectedDumbChunkData.getNbt().contains(tag));
}
}
@Test

View File

@@ -1,5 +1,6 @@
package mc.core.network.proto_1_12_2.packets;
import com.flowpowered.nbt.Tag;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -8,6 +9,7 @@ import mc.core.world.block.BlockType;
import java.nio.ByteBuffer;
import java.nio.LongBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@@ -23,9 +25,10 @@ class DumbChunkData {
private byte[] biomes;
private int numberNBT;
private List<Tag<?>> nbt;
private static BlockType deserializeBlockState(int blockState) {
return BlockType.getByIdMeta((blockState & 0xF0) >> 4, blockState & 0x0F);
return BlockType.getByIdMeta(blockState >> 4, blockState & 0x0F);
}
static DumbChunkData ReadFromNetInputStream(byte[] bytes) {
@@ -95,6 +98,14 @@ class DumbChunkData {
netStream.readBytes(dumbChunkData.biomes);
dumbChunkData.numberNBT = netStream.readVarInt();
if (dumbChunkData.numberNBT > 0) {
dumbChunkData.nbt = new ArrayList<>(dumbChunkData.numberNBT);
for (int i = 0; i < dumbChunkData.numberNBT; i++) {
dumbChunkData.nbt.add(netStream.readNBT());
}
} else {
dumbChunkData.nbt = Collections.emptyList();
}
return dumbChunkData;
}