int x = chunk.getX(), z = chunk.getZ();
RegionFile region = cache.getRegionFile(dir, x, z);
int regionX = x & (REGION_SIZE - 1);
int regionZ = z & (REGION_SIZE - 1);
CompoundTag levelTags = new CompoundTag();
// core properties
levelTags.putInt("xPos", chunk.getX());
levelTags.putInt("zPos", chunk.getZ());
levelTags.putBool("TerrainPopulated", chunk.isPopulated());
levelTags.putLong("LastUpdate", 0);
// chunk sections
List<CompoundTag> sectionTags = new ArrayList<>();
GlowChunkSnapshot snapshot = chunk.getChunkSnapshot(true, true, false);
ChunkSection[] sections = snapshot.getRawSections();
for (byte i = 0; i < sections.length; ++i) {
ChunkSection sec = sections[i];
if (sec == null) continue;
CompoundTag sectionTag = new CompoundTag();
sectionTag.putByte("Y", i);
byte[] rawTypes = new byte[sec.types.length];
NibbleArray extTypes = null;
NibbleArray data = new NibbleArray(sec.types.length);
for (int j = 0; j < sec.types.length; j++) {
rawTypes[j] = (byte) ((sec.types[j] >> 4) & 0xFF);
byte extType = (byte) (sec.types[j] >> 12);
if (extType > 0) {
if (extTypes == null) {
extTypes = new NibbleArray(sec.types.length);
}
extTypes.set(j, extType);
}
data.set(j, (byte) (sec.types[j] & 0xF));
}
sectionTag.putByteArray("Blocks", rawTypes);
if (extTypes != null) {
sectionTag.putByteArray("Add", extTypes.getRawData());
}
sectionTag.putByteArray("Data", data.getRawData());
sectionTag.putByteArray("BlockLight", sec.blockLight.getRawData());
sectionTag.putByteArray("SkyLight", sec.skyLight.getRawData());
sectionTags.add(sectionTag);
}
levelTags.putCompoundList("Sections", sectionTags);
// height map and biomes
levelTags.putIntArray("HeightMap", snapshot.getRawHeightmap());
levelTags.putByteArray("Biomes", snapshot.getRawBiomes());
// entities
List<CompoundTag> entities = new ArrayList<>();
for (GlowEntity entity : chunk.getRawEntities()) {
if (!entity.shouldSave()) {
continue;
}
try {
CompoundTag tag = new CompoundTag();
EntityStorage.save(entity, tag);
entities.add(tag);
} catch (Exception e) {
GlowServer.logger.log(Level.WARNING, "Error saving " + entity + " in " + chunk, e);
}
}
levelTags.putCompoundList("Entities", entities);
// tile entities
List<CompoundTag> tileEntities = new ArrayList<>();
for (TileEntity entity : chunk.getRawTileEntities()) {
try {
CompoundTag tag = new CompoundTag();
entity.saveNbt(tag);
tileEntities.add(tag);
} catch (Exception ex) {
GlowServer.logger.log(Level.SEVERE, "Error saving tile entity at " + entity.getBlock(), ex);
}
}
levelTags.putCompoundList("TileEntities", tileEntities);
CompoundTag levelOut = new CompoundTag();
levelOut.putCompound("Level", levelTags);
try (NBTOutputStream nbt = new NBTOutputStream(region.getChunkDataOutputStream(regionX, regionZ), false)) {
nbt.writeTag(levelOut);
}
}