Improved region save and saving of chunks before population

This commit is contained in:
Shoghi Cervantes 2015-06-05 02:27:37 +02:00
parent d542dfc2ce
commit a53b041984
No known key found for this signature in database
GPG Key ID: 78464DB0A7837F89
2 changed files with 19 additions and 9 deletions

View File

@ -470,7 +470,7 @@ class Level implements ChunkManager, Metadatable{
* @return bool * @return bool
*/ */
public function getAutoSave(){ public function getAutoSave(){
return $this->autoSave === true; return $this->autoSave;
} }
/** /**
@ -922,7 +922,7 @@ class Level implements ChunkManager, Metadatable{
*/ */
public function save($force = false){ public function save($force = false){
if($this->getAutoSave() === false and $force === false){ if(!$this->getAutoSave() and !$force){
return false; return false;
} }
@ -2043,7 +2043,7 @@ class Level implements ChunkManager, Metadatable{
} }
unset($this->chunkPopulationQueue[$index]); unset($this->chunkPopulationQueue[$index]);
$chunk->setProvider($this->provider); $chunk->setProvider($this->provider);
$this->setChunk($x, $z, $chunk); $this->setChunk($x, $z, $chunk, false);
$chunk = $this->getChunk($x, $z, false); $chunk = $this->getChunk($x, $z, false);
if($chunk !== null and ($oldChunk === null or $oldChunk->isPopulated() === false) and $chunk->isPopulated() and $chunk->getProvider() !== null){ if($chunk !== null and ($oldChunk === null or $oldChunk->isPopulated() === false) and $chunk->isPopulated() and $chunk->getProvider() !== null){
$this->server->getPluginManager()->callEvent(new ChunkPopulateEvent($chunk)); $this->server->getPluginManager()->callEvent(new ChunkPopulateEvent($chunk));
@ -2056,7 +2056,10 @@ class Level implements ChunkManager, Metadatable{
unset($this->chunkGenerationQueue[$index]); unset($this->chunkGenerationQueue[$index]);
unset($this->chunkPopulationLock[$index]); unset($this->chunkPopulationLock[$index]);
$chunk->setProvider($this->provider); $chunk->setProvider($this->provider);
$this->setChunk($x, $z, $chunk); $this->setChunk($x, $z, $chunk, false);
}else{
$chunk->setProvider($this->provider);
$this->setChunk($x, $z, $chunk, false);
} }
Timings::$generationCallbackTimer->stopTiming(); Timings::$generationCallbackTimer->stopTiming();
} }
@ -2074,7 +2077,7 @@ class Level implements ChunkManager, Metadatable{
$index = Level::chunkHash($chunkX, $chunkZ); $index = Level::chunkHash($chunkX, $chunkZ);
$oldChunk = $this->getChunk($chunkX, $chunkZ, false); $oldChunk = $this->getChunk($chunkX, $chunkZ, false);
if($unload and $oldChunk !== null){ if($unload and $oldChunk !== null){
$this->unloadChunk($chunkX, $chunkZ, false); $this->unloadChunk($chunkX, $chunkZ, false, false);
$this->provider->setChunk($chunkX, $chunkZ, $chunk); $this->provider->setChunk($chunkX, $chunkZ, $chunk);
$this->chunks[$index] = $chunk; $this->chunks[$index] = $chunk;
@ -2378,7 +2381,7 @@ class Level implements ChunkManager, Metadatable{
unset($this->unloadQueue[Level::chunkHash($x, $z)]); unset($this->unloadQueue[Level::chunkHash($x, $z)]);
} }
public function unloadChunk($x, $z, $safe = true){ public function unloadChunk($x, $z, $safe = true, $trySave = true){
if(($safe === true and $this->isChunkInUse($x, $z))){ if(($safe === true and $this->isChunkInUse($x, $z))){
return false; return false;
} }
@ -2403,7 +2406,7 @@ class Level implements ChunkManager, Metadatable{
try{ try{
if($chunk !== null){ if($chunk !== null){
if($this->getAutoSave()){ if($trySave and $this->getAutoSave()){
$entities = 0; $entities = 0;
foreach($chunk->getEntities() as $e){ foreach($chunk->getEntities() as $e){
if($e instanceof Player){ if($e instanceof Player){
@ -2432,7 +2435,6 @@ class Level implements ChunkManager, Metadatable{
} }
unset($this->chunks[$index]); unset($this->chunks[$index]);
unset($this->usedChunks[$index]);
unset($this->chunkTickList[$index]); unset($this->chunkTickList[$index]);
unset($this->chunkCache[$index]); unset($this->chunkCache[$index]);

View File

@ -141,16 +141,24 @@ class RegionLoader{
} }
$sectors = (int) ceil(($length + 4) / 4096); $sectors = (int) ceil(($length + 4) / 4096);
$index = self::getChunkOffset($x, $z); $index = self::getChunkOffset($x, $z);
$indexChanged = false;
if($this->locationTable[$index][1] < $sectors){ if($this->locationTable[$index][1] < $sectors){
$this->locationTable[$index][0] = $this->lastSector + 1; $this->locationTable[$index][0] = $this->lastSector + 1;
$this->lastSector += $sectors; //The GC will clean this shift "later" $this->lastSector += $sectors; //The GC will clean this shift "later"
$indexChanged = true;
}elseif($this->locationTable[$index][1] != $sectors){
$indexChanged = true;
} }
$this->locationTable[$index][1] = $sectors; $this->locationTable[$index][1] = $sectors;
$this->locationTable[$index][2] = time(); $this->locationTable[$index][2] = time();
fseek($this->filePointer, $this->locationTable[$index][0] << 12); fseek($this->filePointer, $this->locationTable[$index][0] << 12);
fwrite($this->filePointer, str_pad(Binary::writeInt($length) . chr(self::COMPRESSION_ZLIB) . $chunkData, $sectors << 12, "\x00", STR_PAD_RIGHT)); fwrite($this->filePointer, str_pad(Binary::writeInt($length) . chr(self::COMPRESSION_ZLIB) . $chunkData, $sectors << 12, "\x00", STR_PAD_RIGHT));
$this->writeLocationIndex($index);
if($indexChanged){
$this->writeLocationIndex($index);
}
} }
public function removeChunk($x, $z){ public function removeChunk($x, $z){