Search in sources :

Example 1 with BinaryStream

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();
}
Also used : BinaryStream(cn.nukkit.utils.BinaryStream)

Example 2 with BinaryStream

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);
    }
}
Also used : Entity(cn.nukkit.entity.Entity) BlockEntity(cn.nukkit.blockentity.BlockEntity) Player(cn.nukkit.Player) ArrayList(java.util.ArrayList) BinaryStream(cn.nukkit.utils.BinaryStream) ListTag(cn.nukkit.nbt.tag.ListTag) CompoundTag(cn.nukkit.nbt.tag.CompoundTag) BlockEntity(cn.nukkit.blockentity.BlockEntity)

Example 3 with BinaryStream

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;
}
Also used : BlockEntitySpawnable(cn.nukkit.blockentity.BlockEntitySpawnable) ArrayList(java.util.ArrayList) BinaryStream(cn.nukkit.utils.BinaryStream) IOException(java.io.IOException) ChunkException(cn.nukkit.utils.ChunkException) BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) HashMap(java.util.HashMap) Map(java.util.Map) CompoundTag(cn.nukkit.nbt.tag.CompoundTag) BlockEntity(cn.nukkit.blockentity.BlockEntity)

Example 4 with BinaryStream

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;
}
Also used : BinaryStream(cn.nukkit.utils.BinaryStream) IOException(java.io.IOException) BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) IOException(java.io.IOException) ByteArrayInputStream(java.io.ByteArrayInputStream) NBTInputStream(cn.nukkit.nbt.stream.NBTInputStream) CompoundTag(cn.nukkit.nbt.tag.CompoundTag) Tag(cn.nukkit.nbt.tag.Tag) CompoundTag(cn.nukkit.nbt.tag.CompoundTag)

Example 5 with BinaryStream

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);
        }
    }
}
Also used : ArrayList(java.util.ArrayList) BinaryStream(cn.nukkit.utils.BinaryStream)

Aggregations

BinaryStream (cn.nukkit.utils.BinaryStream)13 CompoundTag (cn.nukkit.nbt.tag.CompoundTag)5 BlockEntity (cn.nukkit.blockentity.BlockEntity)4 IOException (java.io.IOException)4 ArrayList (java.util.ArrayList)4 BaseFullChunk (cn.nukkit.level.format.generic.BaseFullChunk)3 Player (cn.nukkit.Player)2 BlockEntitySpawnable (cn.nukkit.blockentity.BlockEntitySpawnable)2 Entity (cn.nukkit.entity.Entity)2 ChunkException (cn.nukkit.utils.ChunkException)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 CommandOverload (cn.nukkit.command.data.CommandOverload)1 CommandParameter (cn.nukkit.command.data.CommandParameter)1 Item (cn.nukkit.item.Item)1 FullChunk (cn.nukkit.level.format.FullChunk)1 LevelProvider (cn.nukkit.level.format.LevelProvider)1 EntitiesKey (cn.nukkit.level.format.leveldb.key.EntitiesKey)1 ExtraDataKey (cn.nukkit.level.format.leveldb.key.ExtraDataKey)1 TilesKey (cn.nukkit.level.format.leveldb.key.TilesKey)1 NBTInputStream (cn.nukkit.nbt.stream.NBTInputStream)1