Added API to allow flagging an entity not to be saved to disk when its chunk is saved (#1452)

This commit is contained in:
Dylan K. Taylor 2017-10-11 16:09:08 +01:00 committed by GitHub
parent 7b1bfc0520
commit be2d134994
6 changed files with 55 additions and 20 deletions

View File

@ -3415,6 +3415,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return [];
}
public function canSaveWithChunk() : bool{
return false;
}
public function setCanSaveWithChunk(bool $value) : void{
throw new \BadMethodCallException("Players can't be saved with chunks");
}
/**
* Handles player data saving
*

View File

@ -337,6 +337,9 @@ abstract class Entity extends Location implements Metadatable{
/** @var bool */
protected $isStatic = false;
/** @var bool */
private $savedWithChunk = true;
/** @var bool */
public $isCollided = false;
/** @var bool */
@ -764,6 +767,24 @@ abstract class Entity extends Location implements Metadatable{
return false;
}
/**
* Returns whether this entity will be saved when its chunk is unloaded.
* @return bool
*/
public function canSaveWithChunk() : bool{
return $this->savedWithChunk;
}
/**
* Sets whether this entity will be saved when its chunk is unloaded. This can be used to prevent the entity being
* saved to disk.
*
* @param bool $value
*/
public function setCanSaveWithChunk(bool $value) : void{
$this->savedWithChunk = $value;
}
/**
* Returns the short save name
*

View File

@ -509,32 +509,38 @@ class LevelDB extends BaseLevelProvider{
//TODO: use this properly
$this->db->put($index . self::TAG_STATE_FINALISATION, chr(self::FINALISATION_DONE));
$this->writeTags($chunk->getTiles(), $index . self::TAG_BLOCK_ENTITY);
$this->writeTags(array_filter($chunk->getEntities(), function(Entity $entity) : bool{
return !($entity instanceof Player);
}), $index . self::TAG_ENTITY);
/** @var CompoundTag[] $tiles */
$tiles = [];
foreach($chunk->getTiles() as $tile){
if(!$tile->isClosed()){
$tile->saveNBT();
$tiles[] = $tile->namedtag;
}
}
$this->writeTags($tiles, $index . self::TAG_BLOCK_ENTITY);
/** @var CompoundTag[] $entities */
$entities = [];
foreach($chunk->getEntities() as $entity){
if($entity->canSaveWithChunk() and !$entity->isClosed()){
$entity->saveNBT();
$entities[] = $entity->namedtag;
}
}
$this->writeTags($entities, $index . self::TAG_ENTITY);
$this->db->delete($index . self::TAG_DATA_2D_LEGACY);
$this->db->delete($index . self::TAG_LEGACY_TERRAIN);
}
/**
* @param Entity[]|Tile[] $targets
* @param string $index
* @param CompoundTag[] $targets
* @param string $index
*/
private function writeTags(array $targets, string $index){
$nbt = new NBT(NBT::LITTLE_ENDIAN);
$out = [];
/** @var Entity|Tile $target */
foreach($targets as $target){
if(!$target->isClosed()){
$target->saveNBT();
$out[] = $target->namedtag;
}
}
if(!empty($targets)){
$nbt->setData($out);
$nbt = new NBT(NBT::LITTLE_ENDIAN);
$nbt->setData($targets);
$this->db->put($index, $nbt->write());
}else{
$this->db->delete($index);

View File

@ -70,7 +70,7 @@ class Anvil extends McRegion{
$entities = [];
foreach($chunk->getEntities() as $entity){
if(!($entity instanceof Player) and !$entity->isClosed()){
if($entity->canSaveWithChunk() and !$entity->isClosed()){
$entity->saveNBT();
$entities[] = $entity->namedtag;
}

View File

@ -89,7 +89,7 @@ class McRegion extends BaseLevelProvider{
$entities = [];
foreach($chunk->getEntities() as $entity){
if(!($entity instanceof Player) and !$entity->isClosed()){
if($entity->canSaveWithChunk() and !$entity->isClosed()){
$entity->saveNBT();
$entities[] = $entity->namedtag;
}

View File

@ -74,7 +74,7 @@ class PMAnvil extends Anvil{
$entities = [];
foreach($chunk->getEntities() as $entity){
if(!($entity instanceof Player) and !$entity->isClosed()){
if($entity->canSaveWithChunk() and !$entity->isClosed()){
$entity->saveNBT();
$entities[] = $entity->namedtag;
}