mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-30 23:29:54 +00:00
Added cache for tile spawn compounds
avoids expensive repetetive NBT writes on chunk sends when the tile hasn't been changed
This commit is contained in:
parent
52d0ad8a61
commit
48fefae920
@ -29,7 +29,6 @@ namespace pocketmine\level\format;
|
|||||||
use pocketmine\block\BlockFactory;
|
use pocketmine\block\BlockFactory;
|
||||||
use pocketmine\entity\Entity;
|
use pocketmine\entity\Entity;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\nbt\NBT;
|
|
||||||
use pocketmine\nbt\tag\CompoundTag;
|
use pocketmine\nbt\tag\CompoundTag;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\tile\Spawnable;
|
use pocketmine\tile\Spawnable;
|
||||||
@ -939,16 +938,10 @@ class Chunk{
|
|||||||
}
|
}
|
||||||
$result .= $extraData->getBuffer();
|
$result .= $extraData->getBuffer();
|
||||||
|
|
||||||
if(count($this->tiles) > 0){
|
foreach($this->tiles as $tile){
|
||||||
$nbt = new NBT(NBT::LITTLE_ENDIAN);
|
if($tile instanceof Spawnable){
|
||||||
$list = [];
|
$result .= $tile->getSerializedSpawnCompound();
|
||||||
foreach($this->tiles as $tile){
|
|
||||||
if($tile instanceof Spawnable){
|
|
||||||
$list[] = $tile->getSpawnCompound();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$nbt->setData($list);
|
|
||||||
$result .= $nbt->write(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
@ -25,7 +25,6 @@ namespace pocketmine\level\format\io;
|
|||||||
|
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\nbt\NBT;
|
|
||||||
use pocketmine\network\mcpe\protocol\BatchPacket;
|
use pocketmine\network\mcpe\protocol\BatchPacket;
|
||||||
use pocketmine\network\mcpe\protocol\FullChunkDataPacket;
|
use pocketmine\network\mcpe\protocol\FullChunkDataPacket;
|
||||||
use pocketmine\scheduler\AsyncTask;
|
use pocketmine\scheduler\AsyncTask;
|
||||||
@ -54,11 +53,9 @@ class ChunkRequestTask extends AsyncTask{
|
|||||||
|
|
||||||
//TODO: serialize tiles with chunks
|
//TODO: serialize tiles with chunks
|
||||||
$tiles = "";
|
$tiles = "";
|
||||||
$nbt = new NBT(NBT::LITTLE_ENDIAN);
|
|
||||||
foreach($chunk->getTiles() as $tile){
|
foreach($chunk->getTiles() as $tile){
|
||||||
if($tile instanceof Spawnable){
|
if($tile instanceof Spawnable){
|
||||||
$nbt->setData($tile->getSpawnCompound());
|
$tiles .= $tile->getSerializedSpawnCompound();
|
||||||
$tiles .= $nbt->write(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,15 +30,17 @@ use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
|
|||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
abstract class Spawnable extends Tile{
|
abstract class Spawnable extends Tile{
|
||||||
|
/** @var string|null */
|
||||||
|
private $spawnCompoundCache = null;
|
||||||
|
/** @var NBT|null */
|
||||||
|
private static $nbtWriter = null;
|
||||||
|
|
||||||
public function createSpawnPacket() : BlockEntityDataPacket{
|
public function createSpawnPacket() : BlockEntityDataPacket{
|
||||||
$nbt = new NBT(NBT::LITTLE_ENDIAN);
|
|
||||||
$nbt->setData($this->getSpawnCompound());
|
|
||||||
$pk = new BlockEntityDataPacket();
|
$pk = new BlockEntityDataPacket();
|
||||||
$pk->x = $this->x;
|
$pk->x = $this->x;
|
||||||
$pk->y = $this->y;
|
$pk->y = $this->y;
|
||||||
$pk->z = $this->z;
|
$pk->z = $this->z;
|
||||||
$pk->namedtag = $nbt->write(true);
|
$pk->namedtag = $this->getSerializedSpawnCompound();
|
||||||
|
|
||||||
return $pk;
|
return $pk;
|
||||||
}
|
}
|
||||||
@ -67,7 +69,12 @@ abstract class Spawnable extends Tile{
|
|||||||
$this->level->addChunkPacket($this->chunk->getX(), $this->chunk->getZ(), $pk);
|
$this->level->addChunkPacket($this->chunk->getX(), $this->chunk->getZ(), $pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs actions needed when the tile is modified, such as clearing caches and respawning the tile to players.
|
||||||
|
* WARNING: This MUST be called to clear spawn-compound and chunk caches when the tile's spawn compound has changed!
|
||||||
|
*/
|
||||||
protected function onChanged() : void{
|
protected function onChanged() : void{
|
||||||
|
$this->spawnCompoundCache = null;
|
||||||
$this->spawnToAll();
|
$this->spawnToAll();
|
||||||
|
|
||||||
if($this->chunk !== null){
|
if($this->chunk !== null){
|
||||||
@ -76,6 +83,25 @@ abstract class Spawnable extends Tile{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns encoded NBT (varint, little-endian) used to spawn this tile to clients. Uses cache where possible,
|
||||||
|
* populates cache if it is null.
|
||||||
|
*
|
||||||
|
* @return string encoded NBT
|
||||||
|
*/
|
||||||
|
final public function getSerializedSpawnCompound() : string{
|
||||||
|
if($this->spawnCompoundCache === null){
|
||||||
|
if(self::$nbtWriter === null){
|
||||||
|
self::$nbtWriter = new NBT(NBT::LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
self::$nbtWriter->setData($this->getSpawnCompound());
|
||||||
|
$this->spawnCompoundCache = self::$nbtWriter->write(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->spawnCompoundCache;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return CompoundTag
|
* @return CompoundTag
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user