Search in sources :

Example 1 with EmptyChunkSection

use of cn.nukkit.level.format.generic.EmptyChunkSection in project Nukkit by Nukkit.

the class Chunk method toFastBinary.

@Override
public byte[] toFastBinary() {
    CompoundTag nbt = this.getNBT().copy();
    nbt.putInt("xPos", this.getX());
    nbt.putInt("zPos", this.getZ());
    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;
    }
    for (cn.nukkit.level.format.ChunkSection section : this.getSections()) {
        if (section instanceof EmptyChunkSection) {
            continue;
        }
        CompoundTag s = new CompoundTag(null);
        s.putByte("Y", section.getY());
        s.putByteArray("Blocks", section.getIdArray());
        s.putByteArray("Data", section.getDataArray());
        s.putByteArray("BlockLight", section.getLightArray());
        s.putByteArray("SkyLight", section.getSkyLightArray());
        nbt.getList("Sections", CompoundTag.class).add(s);
    }
    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);
    Set<BlockUpdateEntry> entries = this.provider.getLevel().getPendingBlockUpdates(this);
    if (entries != null) {
        ListTag<CompoundTag> tileTickTag = new ListTag<>("TileTicks");
        long totalTime = this.provider.getLevel().getCurrentTick();
        for (BlockUpdateEntry entry : entries) {
            CompoundTag entryNBT = new CompoundTag().putString("i", entry.block.getSaveId()).putInt("x", entry.pos.getFloorX()).putInt("y", entry.pos.getFloorY()).putInt("z", entry.pos.getFloorZ()).putInt("t", (int) (entry.delay - totalTime)).putInt("p", entry.priority);
            tileTickTag.add(entryNBT);
        }
        nbt.putList(tileTickTag);
    }
    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 NBTIO.write(chunk, ByteOrder.BIG_ENDIAN);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : Entity(cn.nukkit.entity.Entity) BlockEntity(cn.nukkit.blockentity.BlockEntity) Player(cn.nukkit.Player) IOException(java.io.IOException) EmptyChunkSection(cn.nukkit.level.format.generic.EmptyChunkSection) BlockEntity(cn.nukkit.blockentity.BlockEntity)

Example 2 with EmptyChunkSection

use of cn.nukkit.level.format.generic.EmptyChunkSection in project Nukkit by Nukkit.

the class Level method tickChunks.

private void tickChunks() {
    if (this.chunksPerTicks <= 0 || this.loaders.isEmpty()) {
        this.chunkTickList.clear();
        return;
    }
    int chunksPerLoader = Math.min(200, Math.max(1, (int) (((double) (this.chunksPerTicks - this.loaders.size()) / this.loaders.size() + 0.5))));
    int randRange = 3 + chunksPerLoader / 30;
    randRange = randRange > this.chunkTickRadius ? this.chunkTickRadius : randRange;
    ThreadLocalRandom random = ThreadLocalRandom.current();
    if (!this.loaders.isEmpty()) {
        for (ChunkLoader loader : this.loaders.values()) {
            int chunkX = (int) loader.getX() >> 4;
            int chunkZ = (int) loader.getZ() >> 4;
            long index = Level.chunkHash(chunkX, chunkZ);
            int existingLoaders = Math.max(0, this.chunkTickList.getOrDefault(index, 0));
            this.chunkTickList.put(index, (Integer) (existingLoaders + 1));
            for (int chunk = 0; chunk < chunksPerLoader; ++chunk) {
                int dx = random.nextInt(2 * randRange) - randRange;
                int dz = random.nextInt(2 * randRange) - randRange;
                long hash = Level.chunkHash(dx + chunkX, dz + chunkZ);
                if (!this.chunkTickList.containsKey(hash) && provider.isChunkLoaded(hash)) {
                    this.chunkTickList.put(hash, (Integer) (-1));
                }
            }
        }
    }
    int blockTest = 0;
    if (!chunkTickList.isEmpty()) {
        ObjectIterator<Long2ObjectMap.Entry<Integer>> iter = chunkTickList.long2ObjectEntrySet().fastIterator();
        while (iter.hasNext()) {
            Long2ObjectMap.Entry<Integer> entry = iter.next();
            long index = entry.getLongKey();
            if (!areNeighboringChunksLoaded(index)) {
                iter.remove();
                continue;
            }
            int loaders = entry.getValue();
            int chunkX = getHashX(index);
            int chunkZ = getHashZ(index);
            FullChunk chunk;
            if ((chunk = this.getChunk(chunkX, chunkZ, false)) == null) {
                iter.remove();
                continue;
            } else if (loaders <= 0) {
                iter.remove();
            }
            for (Entity entity : chunk.getEntities().values()) {
                entity.scheduleUpdate();
            }
            int tickSpeed = 3;
            if (tickSpeed > 0) {
                if (this.useSections) {
                    for (ChunkSection section : ((Chunk) chunk).getSections()) {
                        if (!(section instanceof EmptyChunkSection)) {
                            int Y = section.getY();
                            this.updateLCG = this.updateLCG * 3 + 1013904223;
                            int k = this.updateLCG >> 2;
                            for (int i = 0; i < tickSpeed; ++i, k >>= 10) {
                                int x = k & 0x0f;
                                int y = k >> 8 & 0x0f;
                                int z = k >> 16 & 0x0f;
                                int fullId = section.getFullBlock(x, y, z);
                                int blockId = fullId >> 4;
                                if (randomTickBlocks[blockId]) {
                                    Block block = Block.get(fullId, this, chunkX * 16 + x, (Y << 4) + y, chunkZ * 16 + z);
                                    block.onUpdate(BLOCK_UPDATE_RANDOM);
                                }
                            }
                        }
                    }
                } else {
                    for (int Y = 0; Y < 8 && (Y < 3 || blockTest != 0); ++Y) {
                        blockTest = 0;
                        this.updateLCG = this.updateLCG * 3 + 1013904223;
                        int k = this.updateLCG >> 2;
                        for (int i = 0; i < tickSpeed; ++i, k >>= 10) {
                            int x = k & 0x0f;
                            int y = k >> 8 & 0x0f;
                            int z = k >> 16 & 0x0f;
                            int fullId = chunk.getFullBlock(x, y + (Y << 4), z);
                            int blockId = fullId >> 4;
                            blockTest |= fullId;
                            if (this.randomTickBlocks[blockId]) {
                                Block block = Block.get(fullId, this, x, y + (Y << 4), z);
                                block.onUpdate(BLOCK_UPDATE_RANDOM);
                            }
                        }
                    }
                }
            }
        }
    }
    if (this.clearChunksOnTick) {
        this.chunkTickList.clear();
    }
}
Also used : BlockEntity(cn.nukkit.blockentity.BlockEntity) Entity(cn.nukkit.entity.Entity) Long2ObjectMap(it.unimi.dsi.fastutil.longs.Long2ObjectMap) Chunk(cn.nukkit.level.format.Chunk) BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) FullChunk(cn.nukkit.level.format.FullChunk) EmptyChunkSection(cn.nukkit.level.format.generic.EmptyChunkSection) BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) FullChunk(cn.nukkit.level.format.FullChunk) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) ItemBlock(cn.nukkit.item.ItemBlock) Block(cn.nukkit.block.Block) EmptyChunkSection(cn.nukkit.level.format.generic.EmptyChunkSection) ChunkSection(cn.nukkit.level.format.ChunkSection)

Example 3 with EmptyChunkSection

use of cn.nukkit.level.format.generic.EmptyChunkSection 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());
    ListTag<CompoundTag> sectionList = new ListTag<>("Sections");
    for (cn.nukkit.level.format.ChunkSection section : this.getSections()) {
        if (section instanceof EmptyChunkSection) {
            continue;
        }
        CompoundTag s = new CompoundTag(null);
        s.putByte("Y", (section.getY()));
        s.putByteArray("Blocks", section.getIdArray());
        s.putByteArray("Data", section.getDataArray());
        s.putByteArray("BlockLight", section.getLightArray());
        s.putByteArray("SkyLight", section.getSkyLightArray());
        sectionList.add(s);
    }
    nbt.putList(sectionList);
    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);
    Set<BlockUpdateEntry> entries = this.provider.getLevel().getPendingBlockUpdates(this);
    if (entries != null) {
        ListTag<CompoundTag> tileTickTag = new ListTag<>("TileTicks");
        long totalTime = this.provider.getLevel().getCurrentTick();
        for (BlockUpdateEntry entry : entries) {
            CompoundTag entryNBT = new CompoundTag().putString("i", entry.block.getSaveId()).putInt("x", entry.pos.getFloorX()).putInt("y", entry.pos.getFloorY()).putInt("z", entry.pos.getFloorZ()).putInt("t", (int) (entry.delay - totalTime)).putInt("p", entry.priority);
            tileTickTag.add(entryNBT);
        }
        nbt.putList(tileTickTag);
    }
    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) IOException(java.io.IOException) EmptyChunkSection(cn.nukkit.level.format.generic.EmptyChunkSection) BlockEntity(cn.nukkit.blockentity.BlockEntity)

Aggregations

BlockEntity (cn.nukkit.blockentity.BlockEntity)3 Entity (cn.nukkit.entity.Entity)3 EmptyChunkSection (cn.nukkit.level.format.generic.EmptyChunkSection)3 Player (cn.nukkit.Player)2 IOException (java.io.IOException)2 Block (cn.nukkit.block.Block)1 ItemBlock (cn.nukkit.item.ItemBlock)1 Chunk (cn.nukkit.level.format.Chunk)1 ChunkSection (cn.nukkit.level.format.ChunkSection)1 FullChunk (cn.nukkit.level.format.FullChunk)1 BaseFullChunk (cn.nukkit.level.format.generic.BaseFullChunk)1 Long2ObjectMap (it.unimi.dsi.fastutil.longs.Long2ObjectMap)1 ThreadLocalRandom (java.util.concurrent.ThreadLocalRandom)1