public function onRun() { $chunk = Chunk::fromFastBinary($this->chunk); $extraData = new BinaryStream(); $extraData->putLInt(count($chunk->getBlockExtraDataArray())); foreach ($chunk->getBlockExtraDataArray() as $key => $value) { $extraData->putLInt($key); $extraData->putLShort($value); } $ordered = $chunk->getBlockIdArray() . $chunk->getBlockDataArray() . $chunk->getBlockSkyLightArray() . $chunk->getBlockLightArray() . pack("C*", ...$chunk->getHeightMapArray()) . pack("N*", ...$chunk->getBiomeColorArray()) . $extraData->getBuffer() . $this->tiles; $this->setResult($ordered, false); }
public function onRun() { $chunk = Chunk::fromFastBinary($this->chunk); $ids = $chunk->getBlockIdArray(); $meta = $chunk->getBlockDataArray(); $blockLight = $chunk->getBlockLightArray(); $skyLight = $chunk->getBlockSkyLightArray(); $orderedIds = ""; $orderedData = ""; $orderedSkyLight = ""; $orderedLight = ""; for ($x = 0; $x < 16; ++$x) { for ($z = 0; $z < 16; ++$z) { $orderedIds .= $this->getColumn($ids, $x, $z); $orderedData .= $this->getHalfColumn($meta, $x, $z); $orderedSkyLight .= $this->getHalfColumn($skyLight, $x, $z); $orderedLight .= $this->getHalfColumn($blockLight, $x, $z); } } $biomeColors = pack("N*", ...$chunk->getBiomeColorArray()); $ordered = $orderedIds . $orderedData . $orderedSkyLight . $orderedLight . $chunk->getBiomeIdArray() . $biomeColors . $this->tiles; $this->setResult($ordered, false); }
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) { //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; } }
public function getEmptyChunk($chunkX, $chunkZ) { return Chunk::getEmptyChunk($chunkX, $chunkZ, $this); }
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; } }