Read the scenario info header. Contains information about configured
players and the scenario file.

@return void
775125
protected function readScenarioHeader()
    {
        $nextUnitId = $this->readHeader('l', 4);
        $this->position += 4;
        // Player names
        for ($i = 0; $i < 16; $i++) {
            $this->position += 256; // rtrim(readHeaderRaw(), \0)
        }
        // Player names (string table)
        for ($i = 0; $i < 16; $i++) {
            $this->position += 4; // int
        }
        for ($i = 0; $i < 16; $i++) {
            $this->position += 4; // bool isActive
            $this->position += 4; // bool isHuman
            $this->position += 4; // int civilization
            $this->position += 4; // const 0x00000004
        }
        $this->position += 5;

        $elapsedTime = $this->readHeader('f', 4);
        $nameLen = $this->readHeader('v', 2);
        $filename = $this->readHeaderRaw($nameLen);

        // These should be string IDs for messages?
        if ($this->version->isMgl) {
            $this->position += 20;
        } else {
            $this->position += 24;
        }

        $this->analysis->scenarioFilename = $filename;
    }
1114921
public function readConfig()
    {
        // by default, read local file: projectBase/config.php
        // in which only an array $config defined
        $config=[];
        if (file_exists($this->projectBase.'/config.php')) {
            require($this->projectBase . '/config.php');
        }
        $this->config=$config;
    }
126710
public function parseSteamID(): void
    {
        preg_match(
            '#^https?://steamcommunity.com/openid/id/([0-9]{17,25})#',
            $this->request->get('openid_claimed_id'),
            $matches
        );
        $this->steamId = is_numeric($matches[1]) ? $matches[1] : 0;
    }
1062514
private void readProjectHeader()
   {
      Table table = m_tables.get("DIR");
      MapRow row = table.find("");
      if (row != null)
      {
         setFields(PROJECT_FIELDS, row, m_projectFile.getProjectProperties());
         m_wbsFormat = new P3WbsFormat(row);
      }
   }
309300
protected function readWavHeader()
    {
        if (!is_resource($this->_fp)) {
            throw new WavFileException('No wav file open. Use openWav() first.');
        }

        // get actual file size
        $stat = fstat($this->_fp);
        $actualSize = $stat['size'];

        $this->_actualSize = $actualSize;


        // read the common header
        $header = fread($this->_fp, 36);  // minimum size of the wav header
        if (strlen($header) < 36) {
            throw new WavFormatException('Not wav format. Header too short.', 1);
        }


        // check "RIFF" header
        $RIFF = unpack('NChunkID/VChunkSize/NFormat', $header);

        if ($RIFF['ChunkID'] != 0x52494646) {  // "RIFF"
            throw new WavFormatException('Not wav format. "RIFF" signature missing.', 2);
        }

        if ($this->getIgnoreChunkSizes()) {
            $RIFF['ChunkSize'] = $actualSize - 8;
        } else if ($actualSize - 8 < $RIFF['ChunkSize']) {
            trigger_error('"RIFF" chunk size does not match actual file size. Found ' . $RIFF['ChunkSize'] . ', expected ' . ($actualSize - 8) . '.', E_USER_NOTICE);
            $RIFF['ChunkSize'] = $actualSize - 8;
        }

        if ($RIFF['Format'] != 0x57415645) {  // "WAVE"
            throw new WavFormatException('Not wav format. "RIFF" chunk format is not "WAVE".', 4);
        }

        $this->_chunkSize = $RIFF['ChunkSize'];


        // check common "fmt " subchunk
        $fmt = unpack('NSubchunkID/VSubchunkSize/vAudioFormat/vNumChannels/'
                     .'VSampleRate/VByteRate/vBlockAlign/vBitsPerSample',
                     substr($header, 12));

        if ($fmt['SubchunkID'] != 0x666d7420) {  // "fmt "
            throw new WavFormatException('Bad wav header. Expected "fmt " subchunk.', 11);
        }

        if ($fmt['SubchunkSize'] < 16) {
            throw new WavFormatException('Bad "fmt " subchunk size.', 12);
        }

        if (   $fmt['AudioFormat'] != self::WAVE_FORMAT_PCM
            && $fmt['AudioFormat'] != self::WAVE_FORMAT_IEEE_FLOAT
            && $fmt['AudioFormat'] != self::WAVE_FORMAT_EXTENSIBLE)
        {
            throw new WavFormatException('Unsupported audio format. Only PCM or IEEE FLOAT (EXTENSIBLE) audio is supported.', 13);
        }

        if ($fmt['NumChannels'] < 1 || $fmt['NumChannels'] > self::MAX_CHANNEL) {
            throw new WavFormatException('Invalid number of channels in "fmt " subchunk.', 14);
        }

        if ($fmt['SampleRate'] < 1 || $fmt['SampleRate'] > self::MAX_SAMPLERATE) {
            throw new WavFormatException('Invalid sample rate in "fmt " subchunk.', 15);
        }

        if (   ($fmt['AudioFormat'] == self::WAVE_FORMAT_PCM && !in_array($fmt['BitsPerSample'], array(8, 16, 24)))
            || ($fmt['AudioFormat'] == self::WAVE_FORMAT_IEEE_FLOAT && $fmt['BitsPerSample'] != 32)
            || ($fmt['AudioFormat'] == self::WAVE_FORMAT_EXTENSIBLE && !in_array($fmt['BitsPerSample'], array(8, 16, 24, 32))))
        {
            throw new WavFormatException('Only 8, 16 and 24-bit PCM and 32-bit IEEE FLOAT (EXTENSIBLE) audio is supported.', 16);
        }

        $blockAlign = $fmt['NumChannels'] * $fmt['BitsPerSample'] / 8;
        if ($blockAlign != $fmt['BlockAlign']) {
            trigger_error('Invalid block align in "fmt " subchunk. Found ' . $fmt['BlockAlign'] . ', expected ' . $blockAlign . '.', E_USER_NOTICE);
            $fmt['BlockAlign'] = $blockAlign;
        }

        $byteRate = $fmt['SampleRate'] * $blockAlign;
        if ($byteRate != $fmt['ByteRate']) {
            trigger_error('Invalid average byte rate in "fmt " subchunk. Found ' . $fmt['ByteRate'] . ', expected ' . $byteRate . '.', E_USER_NOTICE);
            $fmt['ByteRate'] = $byteRate;
        }

        $this->_fmtChunkSize  = $fmt['SubchunkSize'];
        $this->_audioFormat   = $fmt['AudioFormat'];
        $this->_numChannels   = $fmt['NumChannels'];
        $this->_sampleRate    = $fmt['SampleRate'];
        $this->_byteRate      = $fmt['ByteRate'];
        $this->_blockAlign    = $fmt['BlockAlign'];
        $this->_bitsPerSample = $fmt['BitsPerSample'];


        // read extended "fmt " subchunk data
        $extendedFmt = '';
        if ($fmt['SubchunkSize'] > 16) {
            // possibly handle malformed subchunk without a padding byte
            $extendedFmt = fread($this->_fp, $fmt['SubchunkSize'] - 16 + ($fmt['SubchunkSize'] & 1));  // also read padding byte
            if (strlen($extendedFmt) < $fmt['SubchunkSize'] - 16) {
                throw new WavFormatException('Not wav format. Header too short.', 1);
            }
        }


        // check extended "fmt " for EXTENSIBLE Audio Format
        if ($fmt['AudioFormat'] == self::WAVE_FORMAT_EXTENSIBLE) {
            if (strlen($extendedFmt) < 24) {
                throw new WavFormatException('Invalid EXTENSIBLE "fmt " subchunk size. Found ' . $fmt['SubchunkSize'] . ', expected at least 40.', 19);
            }

            $extensibleFmt = unpack('vSize/vValidBitsPerSample/VChannelMask/H32SubFormat', substr($extendedFmt, 0, 24));

            if (   $extensibleFmt['SubFormat'] != self::WAVE_SUBFORMAT_PCM
                && $extensibleFmt['SubFormat'] != self::WAVE_SUBFORMAT_IEEE_FLOAT)
            {
                throw new WavFormatException('Unsupported audio format. Only PCM or IEEE FLOAT (EXTENSIBLE) audio is supported.', 13);
            }

            if (   ($extensibleFmt['SubFormat'] == self::WAVE_SUBFORMAT_PCM && !in_array($fmt['BitsPerSample'], array(8, 16, 24)))
                || ($extensibleFmt['SubFormat'] == self::WAVE_SUBFORMAT_IEEE_FLOAT && $fmt['BitsPerSample'] != 32))
            {
                throw new WavFormatException('Only 8, 16 and 24-bit PCM and 32-bit IEEE FLOAT (EXTENSIBLE) audio is supported.', 16);
            }

            if ($extensibleFmt['Size'] != 22) {
                trigger_error('Invaid extension size in EXTENSIBLE "fmt " subchunk.', E_USER_NOTICE);
                $extensibleFmt['Size'] = 22;
            }

            if ($extensibleFmt['ValidBitsPerSample'] != $fmt['BitsPerSample']) {
                trigger_error('Invaid or unsupported valid bits per sample in EXTENSIBLE "fmt " subchunk.', E_USER_NOTICE);
                $extensibleFmt['ValidBitsPerSample'] = $fmt['BitsPerSample'];
            }

            if ($extensibleFmt['ChannelMask'] != 0) {
                // count number of set bits - Hamming weight
                $c = (int)$extensibleFmt['ChannelMask'];
                $n = 0;
                while ($c > 0) {
                    $n += $c & 1;
                    $c >>= 1;
                }
                if ($n != $fmt['NumChannels'] || (((int)$extensibleFmt['ChannelMask'] | self::SPEAKER_ALL) != self::SPEAKER_ALL)) {
                    trigger_error('Invalid channel mask in EXTENSIBLE "fmt " subchunk. The number of channels does not match the number of locations in the mask.', E_USER_NOTICE);
                    $extensibleFmt['ChannelMask'] = 0;
                }
            }

            $this->_fmtExtendedSize    = strlen($extendedFmt);
            $this->_validBitsPerSample = $extensibleFmt['ValidBitsPerSample'];
            $this->_channelMask        = $extensibleFmt['ChannelMask'];
            $this->_audioSubFormat     = $extensibleFmt['SubFormat'];

        } else {
            $this->_fmtExtendedSize    = strlen($extendedFmt);
            $this->_validBitsPerSample = $fmt['BitsPerSample'];
            $this->_channelMask        = 0;
            $this->_audioSubFormat     = null;
        }


        // read additional subchunks until "data" subchunk is found
        $factSubchunk = array();
        $dataSubchunk = array();

        while (!feof($this->_fp)) {
            $subchunkHeader = fread($this->_fp, 8);
            if (strlen($subchunkHeader) < 8) {
                throw new WavFormatException('Missing "data" subchunk.', 101);
            }

            $subchunk = unpack('NSubchunkID/VSubchunkSize', $subchunkHeader);

            if ($subchunk['SubchunkID'] == 0x66616374) {        // "fact"
                // possibly handle malformed subchunk without a padding byte
                $subchunkData = fread($this->_fp, $subchunk['SubchunkSize'] + ($subchunk['SubchunkSize'] & 1));  // also read padding byte
                if (strlen($subchunkData) < 4) {
                    throw new WavFormatException('Invalid "fact" subchunk.', 102);
                }

                $factParams = unpack('VSampleLength', substr($subchunkData, 0, 4));
                $factSubchunk = array_merge($subchunk, $factParams);

            } elseif ($subchunk['SubchunkID'] == 0x64617461) {  // "data"
                $dataSubchunk = $subchunk;

                break;

            } elseif ($subchunk['SubchunkID'] == 0x7761766C) {  // "wavl"
                throw new WavFormatException('Wave List Chunk ("wavl" subchunk) is not supported.', 106);
            } else {
                // skip all other (unknown) subchunks
                // possibly handle malformed subchunk without a padding byte
                if ( $subchunk['SubchunkSize'] < 0
                  || fseek($this->_fp, $subchunk['SubchunkSize'] + ($subchunk['SubchunkSize'] & 1), SEEK_CUR) !== 0) {  // also skip padding byte
                    throw new WavFormatException('Invalid subchunk (0x' . dechex($subchunk['SubchunkID']) . ') encountered.', 103);
                }
            }
        }

        if (empty($dataSubchunk)) {
            throw new WavFormatException('Missing "data" subchunk.', 101);
        }

        // check "data" subchunk
        $dataOffset = ftell($this->_fp);
        if ($this->getIgnoreChunkSizes()) {
            $dataSubchunk['SubchunkSize'] = $actualSize - $dataOffset;
        } elseif ($dataSubchunk['SubchunkSize'] < 0 || $actualSize - $dataOffset < $dataSubchunk['SubchunkSize']) {
            trigger_error("Invalid \"data\" subchunk size (found {$dataSubchunk['SubchunkSize']}.", E_USER_NOTICE);
            $dataSubchunk['SubchunkSize'] = $actualSize - $dataOffset;
        }

        $this->_dataOffset     = $dataOffset;
        $this->_dataSize       = $dataSubchunk['SubchunkSize'];
        $this->_dataSize_fp    = $dataSubchunk['SubchunkSize'];
        $this->_dataSize_valid = false;
        $this->_samples        = '';


        // check "fact" subchunk
        $numBlocks = (int)($dataSubchunk['SubchunkSize'] / $fmt['BlockAlign']);

        if (empty($factSubchunk)) {  // construct fake "fact" subchunk
            $factSubchunk = array('SubchunkSize' => 0, 'SampleLength' => $numBlocks);
        }

        if ($factSubchunk['SampleLength'] != $numBlocks) {
            trigger_error('Invalid sample length in "fact" subchunk.', E_USER_NOTICE);
            $factSubchunk['SampleLength'] = $numBlocks;
        }

        $this->_factChunkSize = $factSubchunk['SubchunkSize'];
        $this->_numBlocks     = $factSubchunk['SampleLength'];


        return $this;

    }
718185
protected function readConfig()
    {
        if ($this->loaded == false) {
            $this->config = $this->loader->getDatas();
            $this->loaded = true;
        }

        return $this;
    }
923287
protected function extractHeaderData()
    {
        // Set defaults
        $this->version = 0;
        $this->type = Type::UNKNOWN;
        $this->releaseTime = 0;

        // Parse the beginning of the file
        foreach ($this->getDataSets() as $dataSet) {
            if ($dataSet->getPattern() === self::HEADER_PATTERN) {
                $result = $this->parseHeaderDataSet($dataSet);
                $this->version = $result['version'];
                $this->releaseTime = $result['released'];
                $this->type = $result['type'];
                break;
            }
        }
    }
650925
private function read()
    {
        flock($this->file, LOCK_SH);
        rewind($this->file);
        $content = fgets($this->file);
        flock($this->file, LOCK_UN);

        $this->records = unserialize($content);
    }
1362198
protected function read()
    {
        $handle = fopen($this->config['path'], "r");

        if (!$handle)
            throw new ImportException('Unable to open file, or file not exist');

        if (!$this->import->CheckIfFileIsCML($this->config['path'])) {
            throw new ImportException('File is not valid');
        }

        $this->xml->DropTemporaryTables();
        $this->xml->CreateTemporaryTables();
        $this->xml->ReadXMLToDatabase($handle, $this->session, $this->config['interval']);
        $this->xml->IndexTemporaryTables();
    }
430056
private function prepareDisplay()
    {

        \OWeb\manage\Events::getInstance()->sendEvent('PrepareContent_Start@OWeb\manage\Template');

        //We save the content so that if there is an error we don't show half displayed codes
        ob_start();
        try {
            \OWeb\manage\Controller::getInstance()->display();
        } catch (\Exception $e) {
            \OWeb\manage\Events::getInstance()->sendEvent('PrepareContent_Fail@OWeb\manage\Template');
            ob_end_clean();
            ob_start();
            $ctr = \OWeb\manage\Controller::getInstance()->loadException($e);
            $ctr->addParams("exception", $e);
            \OWeb\manage\Controller::getInstance()->display();
        }

        \OWeb\manage\Events::getInstance()->sendEvent('PrepareContent_Succ@OWeb\manage\Template');

        $this->content = ob_get_contents();

        \OWeb\manage\Events::getInstance()->sendEvent('PrepareContent_End@OWeb\manage\Template');

        ob_end_clean();

        //$this->content_heads = \OWeb\manage\Headers::getInstance()->toString();
       // \OWeb\manage\Headers::getInstance()->reset();
    }
238779
private function _readSpContainer()
	{
		$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
		$recordData = substr($this->_data, $this->_pos + 8, $length);

		// add spContainer to spgrContainer
		$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();
		$this->_object->addChild($spContainer);

		// move stream pointer to next record
		$this->_pos += 8 + $length;

		// record is a container, read contents
		$reader = new PHPExcel_Reader_Excel5_Escher($spContainer);
		$escher = $reader->load($recordData);
	}
810610
private function analyzeExtended()
    {
        $existObjectSeparator = pack('c*', 0x0B, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00);

        $pack = $this->rec->getResourcePack();

        list ($mapSizeX, $mapSizeY) = $this->analysis->mapSize;

        $version = $this->version;
        $players = $this->analysis->players;
        $playersByIndex = [];
        foreach ($players as $p) {
            $playersByIndex[$p->index] = $p;
        }

        // Add GAIA
        $numPlayers = $this->analysis->numPlayers + 1;
        $gaia = new Player($this->rec);
        $gaia->name = 'GAIA';

        // Player -1 is GAIA.
        $playersWithGaia = $players;
        array_unshift($playersWithGaia, $gaia);
        foreach ($playersWithGaia as $player) {
            // Co-op partners do not have an info block.
            if ($player->isCoopPartner()) {
                $coopMain = $player->getCoopMain();
                $player->civId = $coopMain->civId;
                $player->colorId = $coopMain->colorId;
                $player->team = $coopMain->team;
                continue;
            }

            if ($version->isTrial) {
                $this->position += 4;
            }
            $this->position += $numPlayers + 43;

            // skip playername
            $playerNameLen = $this->readHeader('v', 2);
            $this->position += $playerNameLen;

            $this->position += 1; // always 22?
            $numResources = $this->readHeader('l', 4);
            $this->position += 1; // always 33?
            $resourcesEnd = $this->position + 4 * $numResources;

            // Interesting resources
            $food = $this->readHeader('f', 4);
            $wood = $this->readHeader('f', 4);
            $stone = $this->readHeader('f', 4);
            $gold = $this->readHeader('f', 4);
            // headroom = (house capacity - population)
            $headroom = $this->readHeader('f', 4);
            $this->position += 4;
            // Post-Imperial Age = Imperial Age here
            $startingAge = $this->readHeader('f', 4);
            $this->position += 4 * 4;
            $population = $this->readHeader('f', 4);
            $this->position += 25 * 4;
            $civilianPop = $this->readHeader('f', 4);
            $this->position += 2 * 4;
            $militaryPop = $this->readHeader('f', 4);

            $this->position = $resourcesEnd;
            $this->position += 1; // 1 byte

            $initCameraX = $this->readHeader('f', 4);
            $initCameraY = $this->readHeader('f', 4);
            if ($version->isMgx) {
                $this->position += 9;
            } else {
                $this->position += 5;
            }
            $civilization = ord($this->header[$this->position++]);
            if (!$civilization) {
                $civilization = 1;
            }
            $this->position += 3;
            $playerColor = ord($this->header[$this->position++]);

            if ($player->civId === -1) {
                $player->civId = $civilization;
            }
            $player->colorId = $playerColor;
            $player->initialState->position = [round($initCameraX), round($initCameraY)];
            $player->initialState->food = round($food);
            $player->initialState->wood = round($wood);
            $player->initialState->stone = round($stone);
            $player->initialState->gold = round($gold);
            $player->initialState->startingAge = round($startingAge);
            $player->initialState->houseCapacity = round($headroom) + round($population);
            $player->initialState->population = round($population);
            $player->initialState->civilianPop = round($civilianPop);
            $player->initialState->militaryPop = round($militaryPop);
            $player->initialState->extraPop = $player->initialState->population -
                ($player->initialState->civilianPop + $player->initialState->militaryPop);

            if ($version->isTrial) {
                $this->position += 4;
            }
            $this->position += $numPlayers + 70;
            $this->position += $version->isMgx ? 792 : 756;
            $this->position += $version->isMgx ? 41249 : 34277;
            $this->position += $mapSizeX * $mapSizeY;

            // getting exist_object_pos
            $existObjectPos = strpos($this->header, $existObjectSeparator, $this->position);
            if ($existObjectPos === false) {
                throw new \Exception('Could not find existObjectSeparator');
            } else {
                $this->position = $existObjectPos + strlen($existObjectSeparator);
            }

            $objects = $this->read(PlayerObjectsListAnalyzer::class, [
                'players' => array_merge([
                    0 => $gaia,
                ], $playersByIndex),
            ]);

            foreach ($objects->gaiaObjects as &$object) {
                $this->gaiaObjects[] = $object;
            }
            foreach ($objects->playerObjects as &$object) {
                $this->playerObjects[] = $object;
            }
        }

        return (object) [
            'gaia' => $players[0],
            'players' => array_slice($players, 1),
            'gaiaObjects' => $this->gaiaObjects,
            'playerObjects' => $this->playerObjects,
        ];
    }
719725
protected function onRead()
    {
        start:
        if ($this->state === static::STATE_STANDBY) { // outside of packet
            while (($l = $this->readline()) !== null) {
                if ($l === '') {
                    continue;
                }
                $char = $l{0};
                $val = mb_orig_substr($l, 1);
                if ($char === ':') { // inline integer
                    $this->pushValue((int)$val);
                    goto start;
                } elseif (($char === '+') || ($char === '-')) { // inline string
                    $this->error = $char === '-';
                    $this->pushValue($val);
                    goto start;
                } elseif ($char === '*') { // defines number of elements of incoming array
                    $length = (int)$val;
                    if ($length <= 0) {
                        $this->pushValue([]);
                        goto start;
                    }

                    $ptr = [];

                    if (is_array($this->ptr)) {
                        $this->ptr[] =& $ptr;
                    }

                    $this->ptr =& $ptr;
                    $this->stack[] = [&$ptr, $length];
                    $this->levelLength = $length;
                    unset($ptr);

                    goto start;
                } elseif ($char === '$') { // defines size of the data block
                    if ($l{1} === '-') {
                        $this->pushValue(null);
                        goto start;
                    }
                    $this->valueLength = (int)$val;
                    if ($this->valueLength + 2 > $this->pool->maxAllowedPacket) {
                        $this->log('max-allowed-packet (' . $this->pool->config->maxallowedpacket->getHumanValue() . ') exceed, aborting connection');
                        $this->finish();
                        return;
                    }
                    $this->setWatermark($this->valueLength + 2);
                    $this->state = static::STATE_BINARY; // binary data block
                    break; // stop reading line-by-line
                }
            }
        }

        if ($this->state === static::STATE_BINARY) { // inside of binary data block
            if ($this->getInputLength() < $this->valueLength + 2) {
                return; //we do not have a whole packet
            }
            $value = $this->read($this->valueLength);
            if ($this->read(2) !== $this->EOL) {
                $this->finish();
                return;
            }
            $this->state = static::STATE_STANDBY;
            $this->setWatermark(3);
            $this->pushValue($value);
            goto start;
        }
    }
178736
public function parseInfo(): void
    {
        if (is_null($this->steamId)) {
            return;
        }

        if (empty(Config::get('steam-auth.api_key'))) {
            throw new RuntimeException('The Steam API key has not been specified.');
        }

        $response = $this->guzzleClient->request(
            'GET',
            sprintf(self::STEAM_INFO_URL, Config::get('steam-auth.api_key'), $this->steamId)
        );
        $json = json_decode($response->getBody(), true);

        $this->steamInfo = new SteamInfo($json['response']['players'][0]);
    }
332490
public function read($file)
    {
        $this->filePath = $file;
        $this->config = parse_ini_file($this->filePath);
    }
266563
protected function showInformation(): void
    {
        $swOpts    = $this->swooleSettings;
        $settings  = $this->serverSettings;
        $panelData = [
            'System Info'    => [
                'PHP Version'    => PHP_VERSION,
                'Operate System' => PHP_OS,
            ],
            'Swoole Info'    => [
                'version'   => SWOOLE_VERSION,
                'coroutine' => class_exists(Coroutine::class, false),
            ],
            'Swoole Config'  => [
                'dispatch_mode'   => $swOpts['dispatch_mode'],
                'worker_num'      => $swOpts['worker_num'],
                'task_worker_num' => $swOpts['task_worker_num'],
                'max_request'     => $swOpts['max_request'],
            ],
            'Main Server'    => [
                'type'  => $settings['type'],
                'mode'  => $settings['mode'],
                'host'  => $settings['host'],
                'port'  => $settings['port'],
                'class' => static::class,
            ],
            'Project Config' => [
                'name'        => $this->name,
                'path'        => $this->config['rootPath'],
                'auto_reload' => $this->config['auto_reload'],
                'pidFile'     => $this->config['pidFile'],
            ],
            'Server Log'     => $this->config['log'],
        ];

        // 'Server Information'
        Show::mList($panelData, [
            'ucfirst' => false,
        ]);
        // Show::panel($panelData, 'Server Information');
    }
774525
protected function read()
    {
        if ($this->exists()) {
            $id = shmop_open($this->id, "a", 0, 0);
            if (!$id) {
                return false;
            }

            $data = shmop_read($id, 0, shmop_size($id));
            if (!$data) {
                return false;
            }

            $data = $this->unpack($data);
            shmop_close($id);

            return $data;
        }

        return false;
    }