Implemented saving modified chunks

This commit is contained in:
Shoghi Cervantes 2014-10-15 11:42:58 +02:00
parent b71a4701d9
commit e3a9db5d8f
5 changed files with 57 additions and 10 deletions

View File

@ -677,10 +677,12 @@ class Level implements ChunkManager, Metadatable{
} }
public function saveChunks(){ public function saveChunks(){
//TODO: only save changed chunks
foreach($this->chunks as $chunk){ foreach($this->chunks as $chunk){
if($chunk->hasChanged()){
$this->provider->setChunk($chunk->getX(), $chunk->getZ(), $chunk); $this->provider->setChunk($chunk->getX(), $chunk->getZ(), $chunk);
$this->provider->saveChunk($chunk->getX(), $chunk->getZ()); $this->provider->saveChunk($chunk->getX(), $chunk->getZ());
$chunk->setChanged(false);
}
} }
} }
@ -1545,10 +1547,8 @@ class Level implements ChunkManager, Metadatable{
public function getChunk($x, $z, $create = false){ public function getChunk($x, $z, $create = false){
if(isset($this->chunks[$index = "$x:$z"])){ if(isset($this->chunks[$index = "$x:$z"])){
return $this->chunks[$index]; return $this->chunks[$index];
}elseif(($chunk = $this->provider->getChunk($x, $z, $create)) instanceof FullChunk){ }elseif($this->loadChunk($x, $z, $create) and $this->chunks[$index] instanceof FullChunk){
$this->chunks[$index] = $chunk; return $this->chunks[$index];
$chunk->initChunk();
return $chunk;
} }
return null; return null;
@ -1589,6 +1589,7 @@ class Level implements ChunkManager, Metadatable{
$this->provider->setChunk($x, $z, $chunk); $this->provider->setChunk($x, $z, $chunk);
$this->chunks[$index] = $chunk; $this->chunks[$index] = $chunk;
} }
$chunk->setChanged();
} }
/** /**
@ -1805,6 +1806,7 @@ class Level implements ChunkManager, Metadatable{
$chunk = $this->provider->getChunk($x, $z, $generate); $chunk = $this->provider->getChunk($x, $z, $generate);
if($chunk instanceof FullChunk){ if($chunk instanceof FullChunk){
$this->chunks[$index] = $chunk; $this->chunks[$index] = $chunk;
$chunk->initChunk();
}else{ }else{
$this->timings->syncChunkLoadTimer->startTiming(); $this->timings->syncChunkLoadTimer->startTiming();
$this->provider->loadChunk($x, $z, $generate); $this->provider->loadChunk($x, $z, $generate);
@ -1812,6 +1814,7 @@ class Level implements ChunkManager, Metadatable{
if(($chunk = $this->provider->getChunk($x, $z)) instanceof FullChunk){ if(($chunk = $this->provider->getChunk($x, $z)) instanceof FullChunk){
$this->chunks[$index] = $chunk; $this->chunks[$index] = $chunk;
$chunk->initChunk();
}else{ }else{
return false; return false;
} }
@ -1845,6 +1848,8 @@ class Level implements ChunkManager, Metadatable{
return false; return false;
} }
$this->timings->doChunkUnload->startTiming();
$index = "$x:$z"; $index = "$x:$z";
$chunk = $this->getChunk($x, $z); $chunk = $this->getChunk($x, $z);
@ -1856,9 +1861,7 @@ class Level implements ChunkManager, Metadatable{
} }
} }
$this->timings->doChunkUnload->startTiming(); if($chunk instanceof FullChunk and $chunk->hasChanged() and $this->getAutoSave()){
if($chunk instanceof FullChunk and $this->getAutoSave()){
$this->provider->setChunk($x, $z, $chunk); $this->provider->setChunk($x, $z, $chunk);
$this->provider->saveChunk($x, $z); $this->provider->saveChunk($x, $z);
} }

View File

@ -270,6 +270,16 @@ interface FullChunk{
public function toBinary(); public function toBinary();
/**
* @return boolean
*/
public function hasChanged();
/**
* @param bool $changed
*/
public function setChanged($changed = true);
/** /**
* @param string $data * @param string $data
* @param LevelProvider $provider * @param LevelProvider $provider

View File

@ -103,6 +103,7 @@ abstract class BaseChunk extends BaseFullChunk implements Chunk{
public function setBlock($x, $y, $z, $blockId = null, $meta = null){ public function setBlock($x, $y, $z, $blockId = null, $meta = null){
try{ try{
$this->hasChanged = true;
return $this->sections[$y >> 4]->setBlock($x, $y & 0x0f, $z, $blockId & 0xff, $meta & 0x0f); return $this->sections[$y >> 4]->setBlock($x, $y & 0x0f, $z, $blockId & 0xff, $meta & 0x0f);
}catch(\Exception $e){ }catch(\Exception $e){
$level = $this->getProvider(); $level = $this->getProvider();
@ -118,6 +119,7 @@ abstract class BaseChunk extends BaseFullChunk implements Chunk{
public function setBlockId($x, $y, $z, $id){ public function setBlockId($x, $y, $z, $id){
try{ try{
$this->sections[$y >> 4]->setBlockId($x, $y & 0x0f, $z, $id); $this->sections[$y >> 4]->setBlockId($x, $y & 0x0f, $z, $id);
$this->hasChanged = true;
}catch(\Exception $e){ }catch(\Exception $e){
$level = $this->getProvider(); $level = $this->getProvider();
$this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y)); $this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y));
@ -132,6 +134,7 @@ abstract class BaseChunk extends BaseFullChunk implements Chunk{
public function setBlockData($x, $y, $z, $data){ public function setBlockData($x, $y, $z, $data){
try{ try{
$this->sections[$y >> 4]->setBlockData($x, $y & 0x0f, $z, $data); $this->sections[$y >> 4]->setBlockData($x, $y & 0x0f, $z, $data);
$this->hasChanged = true;
}catch(\Exception $e){ }catch(\Exception $e){
$level = $this->getProvider(); $level = $this->getProvider();
$this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y)); $this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y));
@ -146,6 +149,7 @@ abstract class BaseChunk extends BaseFullChunk implements Chunk{
public function setBlockSkyLight($x, $y, $z, $data){ public function setBlockSkyLight($x, $y, $z, $data){
try{ try{
$this->sections[$y >> 4]->getBlockSkyLight($x, $y & 0x0f, $z, $data); $this->sections[$y >> 4]->getBlockSkyLight($x, $y & 0x0f, $z, $data);
$this->hasChanged = true;
}catch(\Exception $e){ }catch(\Exception $e){
$level = $this->getProvider(); $level = $this->getProvider();
$this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y)); $this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y));
@ -160,6 +164,7 @@ abstract class BaseChunk extends BaseFullChunk implements Chunk{
public function setBlockLight($x, $y, $z, $data){ public function setBlockLight($x, $y, $z, $data){
try{ try{
$this->sections[$y >> 4]->getBlockSkyLight($x, $y & 0x0f, $z, $data); $this->sections[$y >> 4]->getBlockSkyLight($x, $y & 0x0f, $z, $data);
$this->hasChanged = true;
}catch(\Exception $e){ }catch(\Exception $e){
$level = $this->getProvider(); $level = $this->getProvider();
$this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y)); $this->setInternalSection($Y = $y >> 4, $level::createChunkSection($Y));
@ -217,10 +222,12 @@ abstract class BaseChunk extends BaseFullChunk implements Chunk{
}else{ }else{
$this->sections[(int) $fY] = $section; $this->sections[(int) $fY] = $section;
} }
$this->hasChanged = true;
} }
private function setInternalSection($fY, ChunkSection $section){ private function setInternalSection($fY, ChunkSection $section){
$this->sections[(int) $fY] = $section; $this->sections[(int) $fY] = $section;
$this->hasChanged = true;
} }
public function load($generate = true){ public function load($generate = true){

View File

@ -67,6 +67,8 @@ abstract class BaseFullChunk implements FullChunk{
protected $x; protected $x;
protected $z; protected $z;
protected $hasChanged = false;
/** /**
* @param LevelProvider $provider * @param LevelProvider $provider
* @param int $x * @param int $x
@ -155,9 +157,12 @@ abstract class BaseFullChunk implements FullChunk{
} }
} }
} }
$this->getProvider()->getLevel()->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); $this->getProvider()->getLevel()->timings->syncChunkLoadTileEntitiesTimer->stopTiming();
$this->NBTentities = null; $this->NBTentities = null;
$this->NBTtiles = null; $this->NBTtiles = null;
$this->hasChanged = false;
} }
} }
@ -202,6 +207,7 @@ abstract class BaseFullChunk implements FullChunk{
} }
public function setBiomeId($x, $z, $biomeId){ public function setBiomeId($x, $z, $biomeId){
$this->hasChanged = true;
$this->biomeIds{($z << 4) + $x} = chr($biomeId); $this->biomeIds{($z << 4) + $x} = chr($biomeId);
} }
@ -212,6 +218,7 @@ abstract class BaseFullChunk implements FullChunk{
} }
public function setBiomeColor($x, $z, $R, $G, $B){ public function setBiomeColor($x, $z, $R, $G, $B){
$this->hasChanged = true;
$this->biomeColors[($z << 4) + $x] = 0 | (($R & 0xFF) << 16) | (($G & 0xFF) << 8) | ($B & 0xFF); $this->biomeColors[($z << 4) + $x] = 0 | (($R & 0xFF) << 16) | (($G & 0xFF) << 8) | ($B & 0xFF);
} }
@ -228,18 +235,22 @@ abstract class BaseFullChunk implements FullChunk{
public function addEntity(Entity $entity){ public function addEntity(Entity $entity){
$this->entities[$entity->getID()] = $entity; $this->entities[$entity->getID()] = $entity;
$this->hasChanged = true;
} }
public function removeEntity(Entity $entity){ public function removeEntity(Entity $entity){
unset($this->entities[$entity->getID()]); unset($this->entities[$entity->getID()]);
$this->hasChanged = true;
} }
public function addTile(Tile $tile){ public function addTile(Tile $tile){
$this->tiles[$tile->getID()] = $tile; $this->tiles[$tile->getID()] = $tile;
$this->hasChanged = true;
} }
public function removeTile(Tile $tile){ public function removeTile(Tile $tile){
unset($this->tiles[$tile->getID()]); unset($this->tiles[$tile->getID()]);
$this->hasChanged = true;
} }
public function getEntities(){ public function getEntities(){
@ -310,4 +321,12 @@ abstract class BaseFullChunk implements FullChunk{
return $this->biomeColors; return $this->biomeColors;
} }
public function hasChanged(){
return $this->hasChanged;
}
public function setChanged($changed = true){
$this->hasChanged = (bool) $changed;
}
} }

View File

@ -93,6 +93,7 @@ class Chunk extends BaseFullChunk{
public function setBlockId($x, $y, $z, $id){ public function setBlockId($x, $y, $z, $id){
$this->blocks{($x << 11) + ($z << 7) + $y} = chr($id); $this->blocks{($x << 11) + ($z << 7) + $y} = chr($id);
$this->hasChanged = true;
} }
public function getBlockData($x, $y, $z){ public function getBlockData($x, $y, $z){
@ -112,6 +113,7 @@ class Chunk extends BaseFullChunk{
}else{ }else{
$this->data{$i} = chr((($data & 0x0f) << 4) | ($old_m & 0x0f)); $this->data{$i} = chr((($data & 0x0f) << 4) | ($old_m & 0x0f));
} }
$this->hasChanged = true;
} }
public function getBlock($x, $y, $z, &$blockId, &$meta = null){ public function getBlock($x, $y, $z, &$blockId, &$meta = null){
@ -154,6 +156,10 @@ class Chunk extends BaseFullChunk{
} }
} }
if($changed){
$this->hasChanged = true;
}
return $changed; return $changed;
} }
@ -174,6 +180,7 @@ class Chunk extends BaseFullChunk{
}else{ }else{
$this->skyLight{$i} = chr((($level & 0x0f) << 4) | ($old_sl & 0x0f)); $this->skyLight{$i} = chr((($level & 0x0f) << 4) | ($old_sl & 0x0f));
} }
$this->hasChanged = true;
} }
public function getBlockLight($x, $y, $z){ public function getBlockLight($x, $y, $z){
@ -193,6 +200,7 @@ class Chunk extends BaseFullChunk{
}else{ }else{
$this->blockLight{$i} = chr((($level & 0x0f) << 4) | ($old_l & 0x0f)); $this->blockLight{$i} = chr((($level & 0x0f) << 4) | ($old_l & 0x0f));
} }
$this->hasChanged = true;
} }
public function getBlockIdColumn($x, $z){ public function getBlockIdColumn($x, $z){