public static fromBinary ( string $data, pocketmine\level\format\LevelProvider $provider = null ) : |
||
$data | string | |
$provider | pocketmine\level\format\LevelProvider | |
return |
public function readChunk($x, $z, $generate = true, $forward = false) { $index = self::getChunkOffset($x, $z); if ($index < 0 or $index >= 4096) { //Regenerate chunk due to corruption $this->locationTable[$index][0] = 0; $this->locationTable[$index][1] = 1; } if (!$this->isChunkGenerated($index)) { if ($generate === true) { //Allocate space $this->locationTable[$index][0] = ++$this->lastSector; $this->locationTable[$index][1] = 1; fseek($this->filePointer, $this->locationTable[$index][0] << 12); fwrite($this->filePointer, str_pad(Binary::writeInt(-1) . chr(self::COMPRESSION_ZLIB), 4096, "", STR_PAD_RIGHT)); $this->writeLocationIndex($index); } else { return false; } } fseek($this->filePointer, $this->locationTable[$index][0] << 12); $length = Binary::readInt(fread($this->filePointer, 4)); $compression = ord(fgetc($this->filePointer)); if ($length <= 0) { //Not yet generated $this->generateChunk($x, $z); fseek($this->filePointer, $this->locationTable[$index][0] << 12); $length = Binary::readInt(fread($this->filePointer, 4)); $compression = ord(fgetc($this->filePointer)); } if ($length > $this->locationTable[$index][1] << 12) { //Invalid chunk, bigger than defined number of sectors MainLogger::getLogger()->error("Corrupted chunk detected"); $this->locationTable[$index][1] = $length >> 12; $this->writeLocationIndex($index); } elseif ($compression !== self::COMPRESSION_ZLIB and $compression !== self::COMPRESSION_GZIP) { MainLogger::getLogger()->error("Invalid compression type"); return false; } $chunk = Chunk::fromBinary(fread($this->filePointer, $length - 1), $this->levelProvider); if ($chunk instanceof Chunk) { return $chunk; } elseif ($forward === false) { MainLogger::getLogger()->error("Corrupted chunk detected"); $this->generateChunk($x, $z); return $this->readChunk($x, $z, $generate, true); } else { return null; } }
protected function unserializeChunk($data) { return Chunk::fromBinary($data, $this->levelProvider); }
public function readChunk($x, $z, $generate = true, $forward = false) { $index = self::getChunkOffset($x, $z); if ($index < 0 or $index >= 4096) { return null; } $this->lastUsed = time(); if (!$this->isChunkGenerated($index)) { if ($generate === true) { //Allocate space $this->locationTable[$index][0] = ++$this->lastSector; $this->locationTable[$index][1] = 1; fseek($this->filePointer, $this->locationTable[$index][0] << 12); fwrite($this->filePointer, str_pad(pack("N", -1) . chr(self::COMPRESSION_ZLIB), 4096, "", STR_PAD_RIGHT)); $this->writeLocationIndex($index); } else { return null; } } fseek($this->filePointer, $this->locationTable[$index][0] << 12); $length = PHP_INT_SIZE === 8 ? unpack("N", fread($this->filePointer, 4))[1] << 32 >> 32 : unpack("N", fread($this->filePointer, 4))[1]; $compression = ord(fgetc($this->filePointer)); if ($length <= 0 or $length >= self::MAX_SECTOR_LENGTH) { //Not yet generated / corrupted if ($length >= self::MAX_SECTOR_LENGTH) { $this->locationTable[$index][0] = ++$this->lastSector; $this->locationTable[$index][1] = 1; MainLogger::getLogger()->error("Corrupted chunk header detected"); } $this->generateChunk($x, $z); fseek($this->filePointer, $this->locationTable[$index][0] << 12); $length = PHP_INT_SIZE === 8 ? unpack("N", fread($this->filePointer, 4))[1] << 32 >> 32 : unpack("N", fread($this->filePointer, 4))[1]; $compression = ord(fgetc($this->filePointer)); } if ($length > $this->locationTable[$index][1] << 12) { //Invalid chunk, bigger than defined number of sectors MainLogger::getLogger()->error("Corrupted bigger chunk detected"); $this->locationTable[$index][1] = $length >> 12; $this->writeLocationIndex($index); } elseif ($compression !== self::COMPRESSION_ZLIB and $compression !== self::COMPRESSION_GZIP) { MainLogger::getLogger()->error("Invalid compression type"); return null; } $chunk = Chunk::fromBinary(fread($this->filePointer, $length - 1), $this->levelProvider); if ($chunk instanceof Chunk) { return $chunk; } elseif ($forward === false) { MainLogger::getLogger()->error("Corrupted chunk detected"); $this->generateChunk($x, $z); return $this->readChunk($x, $z, $generate, true); } else { return null; } }