mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-13 01:09:44 +00:00
Improved Anvil live conversion speed
This commit is contained in:
parent
6fc7ee2775
commit
84d1f4596b
@ -66,7 +66,7 @@ class Anvil extends McRegion{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function requestChunkTask($x, $z){
|
public function requestChunkTask($x, $z){
|
||||||
return new ChunkRequestTask($this, $this->getLevel()->getId(), $x, $z);
|
return new ChunkRequestTask($this->getLevel(), $this->getChunk($x, $z, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,6 +152,83 @@ class Chunk extends BaseChunk{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $data
|
||||||
|
* @param LevelProvider $provider
|
||||||
|
*
|
||||||
|
* @return Chunk
|
||||||
|
*/
|
||||||
|
public static function fromFastBinary($data, LevelProvider $provider = null){
|
||||||
|
$nbt = new NBT(NBT::BIG_ENDIAN);
|
||||||
|
|
||||||
|
try{
|
||||||
|
$nbt->read($data);
|
||||||
|
$chunk = $nbt->getData();
|
||||||
|
|
||||||
|
if(!isset($chunk->Level) or !($chunk->Level instanceof Compound)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Chunk($provider instanceof LevelProvider ? $provider : Anvil::class, $chunk->Level);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toFastBinary(){
|
||||||
|
$nbt = clone $this->getNBT();
|
||||||
|
|
||||||
|
$nbt->xPos = new Int("xPos", $this->x);
|
||||||
|
$nbt->zPos = new Int("zPos", $this->z);
|
||||||
|
|
||||||
|
$nbt->Sections = new Enum("Sections", []);
|
||||||
|
$nbt->Sections->setTagType(NBT::TAG_Compound);
|
||||||
|
foreach($this->getSections() as $section){
|
||||||
|
if($section instanceof EmptyChunkSection){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$nbt->Sections[$section->getY()] = new Compound(null, [
|
||||||
|
"Y" => new Byte("Y", $section->getY()),
|
||||||
|
"Blocks" => new ByteArray("Blocks", $section->getIdArray()),
|
||||||
|
"Data" => new ByteArray("Data", $section->getDataArray()),
|
||||||
|
"BlockLight" => new ByteArray("BlockLight", $section->getLightArray()),
|
||||||
|
"SkyLight" => new ByteArray("SkyLight", $section->getSkyLightArray())
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$nbt->Biomes = new ByteArray("Biomes", $this->getBiomeIdArray());
|
||||||
|
$nbt->BiomeColors = new IntArray("BiomeColors", $this->getBiomeColorArray());
|
||||||
|
|
||||||
|
$nbt->HeightMap = new IntArray("HeightMap", $this->getHeightMapArray());
|
||||||
|
|
||||||
|
$entities = [];
|
||||||
|
|
||||||
|
foreach($this->getEntities() as $entity){
|
||||||
|
if(!($entity instanceof Player) and !$entity->closed){
|
||||||
|
$entity->saveNBT();
|
||||||
|
$entities[] = $entity->namedtag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$nbt->Entities = new Enum("Entities", $entities);
|
||||||
|
$nbt->Entities->setTagType(NBT::TAG_Compound);
|
||||||
|
|
||||||
|
|
||||||
|
$tiles = [];
|
||||||
|
foreach($this->getTiles() as $tile){
|
||||||
|
$tile->saveNBT();
|
||||||
|
$tiles[] = $tile->namedtag;
|
||||||
|
}
|
||||||
|
|
||||||
|
$nbt->TileEntities = new Enum("TileEntities", $tiles);
|
||||||
|
$nbt->TileEntities->setTagType(NBT::TAG_Compound);
|
||||||
|
$writer = new NBT(NBT::BIG_ENDIAN);
|
||||||
|
$nbt->setName("Level");
|
||||||
|
$writer->setData(new Compound("", ["Level" => $nbt]));
|
||||||
|
|
||||||
|
return $writer->write();
|
||||||
|
}
|
||||||
|
|
||||||
public function toBinary(){
|
public function toBinary(){
|
||||||
$nbt = clone $this->getNBT();
|
$nbt = clone $this->getNBT();
|
||||||
|
|
||||||
|
@ -32,30 +32,19 @@ use pocketmine\utils\ChunkException;
|
|||||||
class ChunkRequestTask extends AsyncTask{
|
class ChunkRequestTask extends AsyncTask{
|
||||||
|
|
||||||
protected $levelId;
|
protected $levelId;
|
||||||
|
|
||||||
|
protected $chunk;
|
||||||
protected $chunkX;
|
protected $chunkX;
|
||||||
protected $chunkZ;
|
protected $chunkZ;
|
||||||
|
|
||||||
/** @var \pocketmine\level\format\ChunkSection[] */
|
|
||||||
protected $sections;
|
|
||||||
/** @var string[256] */
|
|
||||||
protected $biomeIds;
|
|
||||||
/** @var int[] */
|
|
||||||
protected $biomeColors;
|
|
||||||
|
|
||||||
protected $tiles;
|
protected $tiles;
|
||||||
|
|
||||||
public function __construct(Anvil $level, $levelId, $chunkX, $chunkZ){
|
public function __construct(Level $level, Chunk $chunk){
|
||||||
$this->levelId = $levelId;
|
$this->levelId = $level->getId();
|
||||||
$this->chunkX = $chunkX;
|
|
||||||
$this->chunkZ = $chunkZ;
|
|
||||||
$chunk = $level->getChunk($chunkX, $chunkZ, false);
|
|
||||||
if(!($chunk instanceof Chunk)){
|
|
||||||
throw new ChunkException("Invalid Chunk sent");
|
|
||||||
}
|
|
||||||
$this->biomeIds = $chunk->getBiomeIdArray();
|
|
||||||
$this->biomeColors = $chunk->getBiomeColorArray();
|
|
||||||
|
|
||||||
$this->sections = $chunk->getSections();
|
$this->chunk = $chunk->toFastBinary();
|
||||||
|
$this->chunkX = $chunk->getX();
|
||||||
|
$this->chunkZ = $chunk->getZ();
|
||||||
|
|
||||||
$tiles = "";
|
$tiles = "";
|
||||||
$nbt = new NBT(NBT::LITTLE_ENDIAN);
|
$nbt = new NBT(NBT::LITTLE_ENDIAN);
|
||||||
@ -67,26 +56,22 @@ class ChunkRequestTask extends AsyncTask{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->tiles = $tiles;
|
$this->tiles = $tiles;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onRun(){
|
public function onRun(){
|
||||||
|
|
||||||
|
$chunk = Chunk::fromFastBinary($this->chunk);
|
||||||
|
$ids = $chunk->getBlockIdArray();
|
||||||
|
$meta = $chunk->getBlockDataArray();
|
||||||
|
$blockLight = $chunk->getBlockLightArray();
|
||||||
|
$skyLight = $chunk->getBlockSkyLightArray();
|
||||||
|
|
||||||
|
|
||||||
$orderedIds = "";
|
$orderedIds = "";
|
||||||
$orderedData = "";
|
$orderedData = "";
|
||||||
$orderedSkyLight = "";
|
$orderedSkyLight = "";
|
||||||
$orderedLight = "";
|
$orderedLight = "";
|
||||||
|
|
||||||
$ids = "";
|
|
||||||
$meta = "";
|
|
||||||
$blockLight = "";
|
|
||||||
$skyLight = "";
|
|
||||||
|
|
||||||
foreach($this->sections as $section){
|
|
||||||
$ids .= $section->getIdArray();
|
|
||||||
$meta .= $section->getDataArray();
|
|
||||||
$blockLight .= $section->getLightArray();
|
|
||||||
$skyLight .= $section->getSkyLightArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
for($x = 0; $x < 16; ++$x){
|
for($x = 0; $x < 16; ++$x){
|
||||||
for($z = 0; $z < 16; ++$z){
|
for($z = 0; $z < 16; ++$z){
|
||||||
@ -97,16 +82,16 @@ class ChunkRequestTask extends AsyncTask{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$biomeColors = pack("N*", ...$this->biomeColors);
|
$biomeColors = pack("N*", ...$chunk->getBiomeColorArray());
|
||||||
|
|
||||||
$ordered = $orderedIds . $orderedData . $orderedSkyLight . $orderedLight . $this->biomeIds . $biomeColors . $this->tiles;
|
$ordered = $orderedIds . $orderedData . $orderedSkyLight . $orderedLight . $chunk->getBiomeIdArray() . $biomeColors . $this->tiles;
|
||||||
|
|
||||||
$this->setResult($ordered, false);
|
$this->setResult($ordered, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getColumn(&$data, $x, $z){
|
public function getColumn($data, $x, $z){
|
||||||
$i = ($z << 4) + $x;
|
|
||||||
$column = "";
|
$column = "";
|
||||||
|
$i = ($z << 4) + $x;
|
||||||
for($y = 0; $y < 128; ++$y){
|
for($y = 0; $y < 128; ++$y){
|
||||||
$column .= $data{($y << 8) + $i};
|
$column .= $data{($y << 8) + $i};
|
||||||
}
|
}
|
||||||
@ -114,9 +99,9 @@ class ChunkRequestTask extends AsyncTask{
|
|||||||
return $column;
|
return $column;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHalfColumn(&$data, $x, $z){
|
public function getHalfColumn($data, $x, $z){
|
||||||
$i = ($z << 3) + ($x >> 1);
|
|
||||||
$column = "";
|
$column = "";
|
||||||
|
$i = ($z << 3) + ($x >> 1);
|
||||||
if(($x & 1) === 0){
|
if(($x & 1) === 0){
|
||||||
for($y = 0; $y < 128; $y += 2){
|
for($y = 0; $y < 128; $y += 2){
|
||||||
$column .= ($data{($y << 7) + $i} & "\x0f") | chr((ord($data{(($y + 1) << 7) + $i}) & 0x0f) << 4);
|
$column .= ($data{($y << 7) + $i} & "\x0f") | chr((ord($data{(($y + 1) << 7) + $i}) & 0x0f) << 4);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user