Some mcregion/anvil improvements, add type-hints and enable strict-types

This commit is contained in:
Dylan K. Taylor 2016-12-22 16:56:45 +00:00
parent 8bdfe0d297
commit 29c27993ad
4 changed files with 26 additions and 55 deletions

View File

@ -39,7 +39,7 @@ use pocketmine\utils\MainLogger;
class Anvil extends McRegion{ class Anvil extends McRegion{
public static function nbtSerialize(GenericChunk $chunk) : string{ public function nbtSerialize(GenericChunk $chunk) : string{
$nbt = new CompoundTag("Level", []); $nbt = new CompoundTag("Level", []);
$nbt->xPos = new IntTag("xPos", $chunk->getX()); $nbt->xPos = new IntTag("xPos", $chunk->getX());
$nbt->zPos = new IntTag("zPos", $chunk->getZ()); $nbt->zPos = new IntTag("zPos", $chunk->getZ());
@ -99,7 +99,7 @@ class Anvil extends McRegion{
return $writer->writeCompressed(ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL); return $writer->writeCompressed(ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL);
} }
public static function nbtDeserialize(string $data, LevelProvider $provider = null){ public function nbtDeserialize(string $data){
$nbt = new NBT(NBT::BIG_ENDIAN); $nbt = new NBT(NBT::BIG_ENDIAN);
try{ try{
$nbt->readCompressed($data, ZLIB_ENCODING_DEFLATE); $nbt->readCompressed($data, ZLIB_ENCODING_DEFLATE);
@ -136,7 +136,7 @@ class Anvil extends McRegion{
} }
$result = new GenericChunk( $result = new GenericChunk(
$provider, $this,
$chunk["xPos"], $chunk["xPos"],
$chunk["zPos"], $chunk["zPos"],
$subChunks, $subChunks,

View File

@ -19,41 +19,15 @@
* *
*/ */
declare(strict_types = 1);
namespace pocketmine\level\format\anvil; namespace pocketmine\level\format\anvil;
use pocketmine\level\format\LevelProvider; use pocketmine\level\format\LevelProvider;
use pocketmine\level\format\generic\GenericChunk;
class RegionLoader extends \pocketmine\level\format\mcregion\RegionLoader{ class RegionLoader extends \pocketmine\level\format\mcregion\RegionLoader{
public function __construct(LevelProvider $level, $regionX, $regionZ){ public function __construct(LevelProvider $level, int $regionX, int $regionZ){
$this->x = $regionX; parent::__construct($level, $regionX, $regionZ, "mca");
$this->z = $regionZ;
$this->levelProvider = $level;
$this->filePath = $this->levelProvider->getPath() . "region/r.$regionX.$regionZ.mca";
$exists = file_exists($this->filePath);
touch($this->filePath);
$this->filePointer = fopen($this->filePath, "r+b");
stream_set_read_buffer($this->filePointer, 1024 * 16); //16KB
stream_set_write_buffer($this->filePointer, 1024 * 16); //16KB
if(!$exists){
$this->createBlank();
}else{
$this->loadLocationTable();
}
$this->lastUsed = time();
}
protected function unserializeChunk($data){
return Anvil::nbtDeserialize($data, $this->levelProvider);
}
public function writeChunk(GenericChunk $chunk){
$this->lastUsed = time();
$chunkData = Anvil::nbtSerialize($chunk);
if($chunkData !== false){
$this->saveChunk($chunk->getX() - ($this->getX() * 32), $chunk->getZ() - ($this->getZ() * 32), $chunkData);
}
} }
} }

View File

@ -43,7 +43,7 @@ class McRegion extends BaseLevelProvider{
* *
* @return string * @return string
*/ */
public static function nbtSerialize(GenericChunk $chunk) : string{ public function nbtSerialize(GenericChunk $chunk) : string{
$nbt = new CompoundTag("Level", []); $nbt = new CompoundTag("Level", []);
$nbt->xPos = new IntTag("xPos", $chunk->getX()); $nbt->xPos = new IntTag("xPos", $chunk->getX());
$nbt->zPos = new IntTag("zPos", $chunk->getZ()); $nbt->zPos = new IntTag("zPos", $chunk->getZ());
@ -110,11 +110,10 @@ class McRegion extends BaseLevelProvider{
/** /**
* @param string $data * @param string $data
* @param LevelProvider $provider
* *
* @return GenericChunk|null * @return GenericChunk|null
*/ */
public static function nbtDeserialize(string $data, LevelProvider $provider = null){ public function nbtDeserialize(string $data){
$nbt = new NBT(NBT::BIG_ENDIAN); $nbt = new NBT(NBT::BIG_ENDIAN);
try{ try{
$nbt->readCompressed($data, ZLIB_ENCODING_DEFLATE); $nbt->readCompressed($data, ZLIB_ENCODING_DEFLATE);
@ -170,7 +169,7 @@ class McRegion extends BaseLevelProvider{
} }
$result = new GenericChunk( $result = new GenericChunk(
$provider, $this,
$chunk["xPos"], $chunk["xPos"],
$chunk["zPos"], $chunk["zPos"],
$subChunks, $subChunks,

View File

@ -19,6 +19,8 @@
* *
*/ */
declare(strict_types = 1);
namespace pocketmine\level\format\mcregion; namespace pocketmine\level\format\mcregion;
use pocketmine\level\format\generic\GenericChunk; use pocketmine\level\format\generic\GenericChunk;
@ -45,11 +47,11 @@ class RegionLoader{
public $lastUsed; public $lastUsed;
public function __construct(LevelProvider $level, $regionX, $regionZ){ public function __construct(LevelProvider $level, int $regionX, int $regionZ, string $fileExtension = "mcr"){
$this->x = $regionX; $this->x = $regionX;
$this->z = $regionZ; $this->z = $regionZ;
$this->levelProvider = $level; $this->levelProvider = $level;
$this->filePath = $this->levelProvider->getPath() . "region/r.$regionX.$regionZ.mcr"; $this->filePath = $this->levelProvider->getPath() . "region/r.$regionX.$regionZ.$fileExtension";
$exists = file_exists($this->filePath); $exists = file_exists($this->filePath);
if(!$exists){ if(!$exists){
touch($this->filePath); touch($this->filePath);
@ -73,11 +75,11 @@ class RegionLoader{
} }
} }
protected function isChunkGenerated($index){ protected function isChunkGenerated(int $index) : bool{
return !($this->locationTable[$index][0] === 0 or $this->locationTable[$index][1] === 0); return !($this->locationTable[$index][0] === 0 or $this->locationTable[$index][1] === 0);
} }
public function readChunk($x, $z){ public function readChunk(int $x, int $z){
$index = self::getChunkOffset($x, $z); $index = self::getChunkOffset($x, $z);
if($index < 0 or $index >= 4096){ if($index < 0 or $index >= 4096){
return null; return null;
@ -111,7 +113,7 @@ class RegionLoader{
return null; return null;
} }
$chunk = $this->unserializeChunk(fread($this->filePointer, $length - 1)); $chunk = $this->levelProvider->nbtDeserialize(fread($this->filePointer, $length - 1));
if($chunk instanceof GenericChunk){ if($chunk instanceof GenericChunk){
return $chunk; return $chunk;
}else{ }else{
@ -120,15 +122,11 @@ class RegionLoader{
} }
} }
protected function unserializeChunk($data){ public function chunkExists(int $x, int $z) : bool{
return McRegion::nbtDeserialize($data, $this->levelProvider);
}
public function chunkExists($x, $z){
return $this->isChunkGenerated(self::getChunkOffset($x, $z)); return $this->isChunkGenerated(self::getChunkOffset($x, $z));
} }
protected function saveChunk($x, $z, $chunkData){ protected function saveChunk(int $x, int $z, string $chunkData){
$length = strlen($chunkData) + 1; $length = strlen($chunkData) + 1;
if($length + 4 > self::MAX_SECTOR_LENGTH){ if($length + 4 > self::MAX_SECTOR_LENGTH){
throw new ChunkException("Chunk is too big! " . ($length + 4) . " > " . self::MAX_SECTOR_LENGTH); throw new ChunkException("Chunk is too big! " . ($length + 4) . " > " . self::MAX_SECTOR_LENGTH);
@ -155,7 +153,7 @@ class RegionLoader{
} }
} }
public function removeChunk($x, $z){ public function removeChunk(int $x, int $z){
$index = self::getChunkOffset($x, $z); $index = self::getChunkOffset($x, $z);
$this->locationTable[$index][0] = 0; $this->locationTable[$index][0] = 0;
$this->locationTable[$index][1] = 0; $this->locationTable[$index][1] = 0;
@ -163,13 +161,13 @@ class RegionLoader{
public function writeChunk(GenericChunk $chunk){ public function writeChunk(GenericChunk $chunk){
$this->lastUsed = time(); $this->lastUsed = time();
$chunkData = McRegion::nbtSerialize($chunk); $chunkData = $this->levelProvider->nbtSerialize($chunk);
if($chunkData !== false){ if($chunkData !== false){
$this->saveChunk($chunk->getX() - ($this->getX() * 32), $chunk->getZ() - ($this->getZ() * 32), $chunkData); $this->saveChunk($chunk->getX() - ($this->getX() * 32), $chunk->getZ() - ($this->getZ() * 32), $chunkData);
} }
} }
protected static function getChunkOffset($x, $z){ protected static function getChunkOffset(int $x, int $z) : int{
return $x + ($z << 5); return $x + ($z << 5);
} }
@ -179,7 +177,7 @@ class RegionLoader{
$this->levelProvider = null; $this->levelProvider = null;
} }
public function doSlowCleanUp(){ public function doSlowCleanUp() : int{
for($i = 0; $i < 1024; ++$i){ for($i = 0; $i < 1024; ++$i){
if($this->locationTable[$i][0] === 0 or $this->locationTable[$i][1] === 0){ if($this->locationTable[$i][0] === 0 or $this->locationTable[$i][1] === 0){
continue; continue;
@ -215,7 +213,7 @@ class RegionLoader{
return $n; return $n;
} }
private function cleanGarbage(){ private function cleanGarbage() : int{
$sectors = []; $sectors = [];
foreach($this->locationTable as $index => $data){ //Calculate file usage foreach($this->locationTable as $index => $data){ //Calculate file usage
if($data[0] === 0 or $data[1] === 0){ if($data[0] === 0 or $data[1] === 0){
@ -295,11 +293,11 @@ class RegionLoader{
$this->locationTable = array_fill(0, 1024, [0, 0, 0]); $this->locationTable = array_fill(0, 1024, [0, 0, 0]);
} }
public function getX(){ public function getX() : int{
return $this->x; return $this->x;
} }
public function getZ(){ public function getZ() : int{
return $this->z; return $this->z;
} }