обработка NBT в чанках
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user