Пример #1
0
 /**
  * Read the file header and lumps.
  *
  * @throws \Exception
  */
 private function readHeader()
 {
     // size = 4 (header) + 4 (version) + (64 * 32)
     $this->buffer = new ResourceBuffer($this->stream);
     $header = $this->buffer->read(4);
     if ($header != 'VBSP') {
         throw new BSPException('Invalid header!');
     }
     $this->version = $this->buffer->getInteger();
     $this->lumpHeader = [];
     for ($i = 0; $i < 64; $i++) {
         $this->lumpHeader[] = ['fileofs' => $this->buffer->getInteger(), 'filelen' => $this->buffer->getInteger(), 'version' => $this->buffer->getInteger(), 'fourCC' => $this->buffer->read(4)];
     }
 }
Пример #2
0
 /**
  * Load the archive.
  *
  * @throws VPKException
  * @throws \Exception
  * @throws \VLib\Buffer\BufferUnderflowException
  */
 private function load()
 {
     $this->multiChunk = strpos($this->path, '_dir') !== false;
     // Load it from our filesystem. This uses Flysystem to support remote files.
     $fh = $this->filesystem->readStream($this->path);
     if (!$fh) {
         throw new VPKException('Unable to open path ' . $this->path);
     }
     /**
      * Use a temporary buffer for the header data.
      */
     $buffer = new ResourceBuffer($fh);
     $sig = $buffer->getInteger();
     if ($sig !== 1437209140) {
         throw new VPKException('Invalid file signature.');
     }
     $this->version = $buffer->getInteger();
     switch ($this->version) {
         case 1:
             $headerSize = 12;
             break;
         case 2:
             $headerSize = 28;
             $buffer->skip(16);
             break;
         default:
             throw new VPKException('Invalid file version.');
     }
     $this->dictSize = $buffer->getInteger();
     $this->pathEntries = [];
     while ($type = $buffer->getString()) {
         while ($dir = $buffer->getString()) {
             while ($name = $buffer->getString()) {
                 $crc32 = $buffer->getInteger();
                 $preloadSize = $buffer->getShort();
                 $chunkIndex = $buffer->getShort();
                 $offset = $buffer->getInteger();
                 $size = $buffer->getInteger();
                 $term = $buffer->getShort();
                 if ($term !== 0xffff) {
                     throw new VPKException('Unexpected termination character.');
                 }
                 $preload = '';
                 if ($preloadSize > 0) {
                     $preload = $buffer->read($preloadSize);
                 }
                 if ($this->multiChunk) {
                     $entryName = sprintf('%s_%03d.vpk', $this->vpkName, $chunkIndex);
                     $entryName = $this->dir . '/' . $entryName;
                 } else {
                     $entryName = $this->file;
                     if ($this->version == 1) {
                         $offset += $headerSize + $this->dictSize;
                     }
                 }
                 $entry = new VPKEntry($this->filesystem, $entryName);
                 $entry->setType($type);
                 $entry->setName($name);
                 $entry->setDir($dir);
                 $entry->setCRC32($crc32);
                 $entry->setOffset($offset);
                 $entry->setSize($size);
                 $entry->setPreload($preload);
                 $this->pathEntries[$entry->getPath()] = $entry;
             }
         }
     }
 }