Implemented partial chunk saving on LevelDB (#3078)

This commit is contained in:
Dylan T
2019-08-07 17:39:36 +01:00
committed by GitHub
parent 9598af7683
commit c533f6a0bd
6 changed files with 79 additions and 48 deletions

View File

@ -416,7 +416,9 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
$chunk->setGenerated();
$chunk->setPopulated();
$chunk->setChanged($hasBeenUpgraded); //trigger rewriting chunk to disk if it was converted from an older format
if($hasBeenUpgraded){
$chunk->setDirty(); //trigger rewriting chunk to disk if it was converted from an older format
}
return $chunk;
}
@ -431,39 +433,43 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
$write = new \LevelDBWriteBatch();
$write->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION));
$subChunks = $chunk->getSubChunks();
foreach($subChunks as $y => $subChunk){
$key = $index . self::TAG_SUBCHUNK_PREFIX . chr($y);
if($subChunk->isEmpty(false)){ //MCPE doesn't save light anymore as of 1.1
$write->delete($key);
}else{
$subStream = new BinaryStream();
$subStream->putByte(self::CURRENT_LEVEL_SUBCHUNK_VERSION);
if($chunk->getDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN)){
$subChunks = $chunk->getSubChunks();
foreach($subChunks as $y => $subChunk){
$key = $index . self::TAG_SUBCHUNK_PREFIX . chr($y);
if($subChunk->isEmpty(false)){ //MCPE doesn't save light anymore as of 1.1
$write->delete($key);
}else{
$subStream = new BinaryStream();
$subStream->putByte(self::CURRENT_LEVEL_SUBCHUNK_VERSION);
$layers = $subChunk->getBlockLayers();
$subStream->putByte(count($layers));
foreach($layers as $blocks){
$subStream->putByte($blocks->getBitsPerBlock() << 1);
$subStream->put($blocks->getWordArray());
$layers = $subChunk->getBlockLayers();
$subStream->putByte(count($layers));
foreach($layers as $blocks){
$subStream->putByte($blocks->getBitsPerBlock() << 1);
$subStream->put($blocks->getWordArray());
$palette = $blocks->getPalette();
$subStream->putLInt(count($palette));
$tags = [];
foreach($palette as $p){
$tags[] = new TreeRoot(CompoundTag::create()
->setString("name", $idMap[$p >> 4] ?? "minecraft:info_update")
->setInt("oldid", $p >> 4) //PM only (debugging), vanilla doesn't have this
->setShort("val", $p & 0xf));
$palette = $blocks->getPalette();
$subStream->putLInt(count($palette));
$tags = [];
foreach($palette as $p){
$tags[] = new TreeRoot(CompoundTag::create()
->setString("name", $idMap[$p >> 4] ?? "minecraft:info_update")
->setInt("oldid", $p >> 4) //PM only (debugging), vanilla doesn't have this
->setShort("val", $p & 0xf));
}
$subStream->put((new LittleEndianNbtSerializer())->writeMultiple($tags));
}
$subStream->put((new LittleEndianNbtSerializer())->writeMultiple($tags));
$write->put($key, $subStream->getBuffer());
}
$write->put($key, $subStream->getBuffer());
}
}
$write->put($index . self::TAG_DATA_2D, str_repeat("\x00", 512) . $chunk->getBiomeIdArray());
if($chunk->getDirtyFlag(Chunk::DIRTY_FLAG_BIOMES)){
$write->put($index . self::TAG_DATA_2D, str_repeat("\x00", 512) . $chunk->getBiomeIdArray());
}
//TODO: use this properly
$write->put($index . self::TAG_STATE_FINALISATION, chr(self::FINALISATION_DONE));