use of cn.nukkit.utils.BinaryStream in project Nukkit by Nukkit.
the class Chunk method toFastBinary.
@Override
public byte[] toFastBinary() {
BinaryStream stream = new BinaryStream(new byte[65536]);
stream.put(Binary.writeInt(this.getX()));
stream.put(Binary.writeInt(this.getZ()));
stream.put(this.getBlockIdArray());
stream.put(this.getBlockDataArray());
stream.put(this.getBlockSkyLightArray());
stream.put(this.getBlockLightArray());
stream.put(this.getHeightMapArray());
for (int color : this.getBiomeColorArray()) {
stream.put(Binary.writeInt(color));
}
stream.putByte((byte) ((this.isLightPopulated() ? 1 << 2 : 0) + (this.isPopulated() ? 1 << 2 : 0) + (this.isGenerated() ? 1 : 0)));
return stream.getBuffer();
}
use of cn.nukkit.utils.BinaryStream in project Nukkit by Nukkit.
the class Chunk method toBinary.
@Override
public byte[] toBinary() {
CompoundTag nbt = this.getNBT().copy();
nbt.putInt("xPos", this.getX());
nbt.putInt("zPos", this.getZ());
if (this.isGenerated()) {
nbt.putByteArray("Blocks", this.getBlockIdArray());
nbt.putByteArray("Data", this.getBlockDataArray());
nbt.putByteArray("SkyLight", this.getBlockSkyLightArray());
nbt.putByteArray("BlockLight", this.getBlockLightArray());
nbt.putIntArray("BiomeColors", this.getBiomeColorArray());
int[] heightInts = new int[256];
byte[] heightBytes = this.getHeightMapArray();
for (int i = 0; i < heightInts.length; i++) {
heightInts[i] = heightBytes[i] & 0xFF;
}
nbt.putIntArray("HeightMap", heightInts);
}
ArrayList<CompoundTag> entities = new ArrayList<>();
for (Entity entity : this.getEntities().values()) {
if (!(entity instanceof Player) && !entity.closed) {
entity.saveNBT();
entities.add(entity.namedTag);
}
}
ListTag<CompoundTag> entityListTag = new ListTag<>("Entities");
entityListTag.setAll(entities);
nbt.putList(entityListTag);
ArrayList<CompoundTag> tiles = new ArrayList<>();
for (BlockEntity blockEntity : this.getBlockEntities().values()) {
blockEntity.saveNBT();
tiles.add(blockEntity.namedTag);
}
ListTag<CompoundTag> tileListTag = new ListTag<>("TileEntities");
tileListTag.setAll(tiles);
nbt.putList(tileListTag);
BinaryStream extraData = new BinaryStream();
Map<Integer, Integer> extraDataArray = this.getBlockExtraDataArray();
extraData.putInt(extraDataArray.size());
for (Integer key : extraDataArray.keySet()) {
extraData.putInt(key);
extraData.putShort(extraDataArray.get(key));
}
nbt.putByteArray("ExtraData", extraData.getBuffer());
CompoundTag chunk = new CompoundTag("");
chunk.putCompound("Level", nbt);
try {
return Zlib.deflate(NBTIO.write(chunk, ByteOrder.BIG_ENDIAN), RegionLoader.COMPRESSION_LEVEL);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of cn.nukkit.utils.BinaryStream in project Nukkit by Nukkit.
the class McRegion method requestChunkTask.
@Override
public AsyncTask requestChunkTask(int x, int z) throws ChunkException {
BaseFullChunk chunk = this.getChunk(x, z, false);
if (chunk == null) {
throw new ChunkException("Invalid Chunk Sent");
}
long timestamp = chunk.getChanges();
byte[] tiles = new byte[0];
if (!chunk.getBlockEntities().isEmpty()) {
List<CompoundTag> tagList = new ArrayList<>();
for (BlockEntity blockEntity : chunk.getBlockEntities().values()) {
if (blockEntity instanceof BlockEntitySpawnable) {
tagList.add(((BlockEntitySpawnable) blockEntity).getSpawnCompound());
}
}
try {
tiles = NBTIO.write(tagList, ByteOrder.LITTLE_ENDIAN, true);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Map<Integer, Integer> extra = chunk.getBlockExtraDataArray();
BinaryStream extraData;
if (!extra.isEmpty()) {
extraData = new BinaryStream();
extraData.putLInt(extra.size());
for (Map.Entry<Integer, Integer> entry : extra.entrySet()) {
extraData.putLInt(entry.getKey());
extraData.putLShort(entry.getValue());
}
} else {
extraData = null;
}
BinaryStream stream = new BinaryStream();
stream.put(chunk.getBlockIdArray());
stream.put(chunk.getBlockDataArray());
stream.put(chunk.getBlockSkyLightArray());
stream.put(chunk.getBlockLightArray());
stream.put(chunk.getHeightMapArray());
for (int color : chunk.getBiomeColorArray()) {
stream.put(Binary.writeInt(color));
}
if (extraData != null) {
stream.put(extraData.getBuffer());
} else {
stream.putLInt(0);
}
stream.put(tiles);
this.getLevel().chunkRequestCallback(timestamp, x, z, stream.getBuffer());
return null;
}
use of cn.nukkit.utils.BinaryStream in project Nukkit by Nukkit.
the class Chunk method fromBinary.
public static Chunk fromBinary(byte[] data, LevelProvider provider) {
try {
int chunkX = Binary.readLInt(new byte[] { data[0], data[1], data[2], data[3] });
int chunkZ = Binary.readLInt(new byte[] { data[4], data[5], data[6], data[7] });
byte[] chunkData = Binary.subBytes(data, 8, data.length - 1);
int flags = data[data.length - 1];
List<CompoundTag> entities = new ArrayList<>();
List<CompoundTag> tiles = new ArrayList<>();
Map<Integer, Integer> extraDataMap = new HashMap<>();
if (provider instanceof LevelDB) {
byte[] entityData = ((LevelDB) provider).getDatabase().get(EntitiesKey.create(chunkX, chunkZ).toArray());
if (entityData != null && entityData.length > 0) {
try (NBTInputStream nbtInputStream = new NBTInputStream(new ByteArrayInputStream(entityData), ByteOrder.LITTLE_ENDIAN)) {
while (nbtInputStream.available() > 0) {
Tag tag = Tag.readNamedTag(nbtInputStream);
if (!(tag instanceof CompoundTag)) {
throw new IOException("Root tag must be a named compound tag");
}
entities.add((CompoundTag) tag);
}
}
}
byte[] tileData = ((LevelDB) provider).getDatabase().get(TilesKey.create(chunkX, chunkZ).toArray());
if (tileData != null && tileData.length > 0) {
try (NBTInputStream nbtInputStream = new NBTInputStream(new ByteArrayInputStream(tileData), ByteOrder.LITTLE_ENDIAN)) {
while (nbtInputStream.available() > 0) {
Tag tag = Tag.readNamedTag(nbtInputStream);
if (!(tag instanceof CompoundTag)) {
throw new IOException("Root tag must be a named compound tag");
}
tiles.add((CompoundTag) tag);
}
}
}
byte[] extraData = ((LevelDB) provider).getDatabase().get(ExtraDataKey.create(chunkX, chunkZ).toArray());
if (extraData != null && extraData.length > 0) {
BinaryStream stream = new BinaryStream(tileData);
int count = stream.getInt();
for (int i = 0; i < count; ++i) {
int key = stream.getInt();
int value = stream.getShort();
extraDataMap.put(key, value);
}
}
/*if (!entities.isEmpty() || !blockEntities.isEmpty()) {
CompoundTag ct = new CompoundTag();
ListTag<CompoundTag> entityList = new ListTag<>("entities");
ListTag<CompoundTag> tileList = new ListTag<>("blockEntities");
entityList.list = entities;
tileList.list = blockEntities;
ct.putList(entityList);
ct.putList(tileList);
NBTIO.write(ct, new File(Nukkit.DATA_PATH + chunkX + "_" + chunkZ + ".dat"));
}*/
Chunk chunk = new Chunk(provider, chunkX, chunkZ, chunkData, entities, tiles, extraDataMap);
if ((flags & 0x01) > 0) {
chunk.setGenerated();
}
if ((flags & 0x02) > 0) {
chunk.setPopulated();
}
if ((flags & 0x04) > 0) {
chunk.setLightPopulated();
}
return chunk;
}
} catch (Exception e) {
Server.getInstance().getLogger().logException(e);
}
return null;
}
use of cn.nukkit.utils.BinaryStream in project Nukkit by Nukkit.
the class Network method processBatch.
public void processBatch(BatchPacket packet, Player player) {
byte[] data;
try {
data = Zlib.inflate(packet.payload, 64 * 1024 * 1024);
} catch (Exception e) {
return;
}
int len = data.length;
BinaryStream stream = new BinaryStream(data);
try {
List<DataPacket> packets = new ArrayList<>();
while (stream.offset < len) {
byte[] buf = stream.getByteArray();
DataPacket pk;
if ((pk = this.getPacket(buf[0])) != null) {
// skip 2 more bytes
pk.setBuffer(buf, 3);
pk.decode();
packets.add(pk);
}
}
processPackets(player, packets);
} catch (Exception e) {
if (Nukkit.DEBUG > 0) {
this.server.getLogger().debug("BatchPacket 0x" + Binary.bytesToHexString(packet.payload));
this.server.getLogger().logException(e);
}
}
}
Aggregations