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);
}
}
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();
}
}
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);
}
}
Aggregations