Parse the server response parameters

@SuppressWarnings(PHPMD.CyclomaticComplexity)

@param \GameQ\Buffer $buffer

@return array
@throws \GameQ\Exception\Protocol
420017
protected function parseServerParameters(Buffer &$buffer)
    {

        // Init the parsed data array
        $parsed = [];

        // Read the number of parameters to parse
        $parameterSize = $buffer->readInt32Signed();

        // Iterate over the parameter size
        for ($i = 0; $i < $parameterSize; $i++) {
            // Read the type of return this is
            $dataType = $buffer->readInt8Signed();

            switch ($dataType) {
                // 32-bit int
                case 1:
                    $parsed[$i] = $buffer->readInt32Signed();
                    break;

                // 64-bit int
                case 2:
                    $parsed[$i] = $buffer->readInt64();
                    break;

                // Float
                case 3:
                    $parsed[$i] = $buffer->readFloat32();
                    break;

                // String
                case 4:
                    // The first 2 bytes are the string length
                    $strLength = $buffer->readInt16Signed();

                    // Read the above length from the buffer
                    $parsed[$i] = $buffer->read($strLength);

                    unset($strLength);
                    break;

                // Boolean
                case 5:
                    $parsed[$i] = (bool)$buffer->readInt8Signed();
                    break;

                // 8-bit int
                case 6:
                    $parsed[$i] = $buffer->readInt8Signed();
                    break;

                // 16-bit int
                case 7:
                    $parsed[$i] = $buffer->readInt16Signed();
                    break;

                // Array
                case 8:
                    // Not implemented
                    throw new Exception("StarMade array parsing is not implemented!");
            }
        }

        return $parsed;
    }
794014
protected function processPlayers(Buffer $buffer)
    {

        // Decode into items
        $items = $this->decode($buffer);

        // Set the result to a new result instance
        $result = new Result();

        // Number of data points per player
        $numTags = $items[1];

        // Grab the tags for each player
        $tags = array_slice($items, 2, $numTags);

        // Get the player count
        $playerCount = $items[$numTags + 2];

        // Iterate over the index until we run out of players
        for ($i = 0, $x = $numTags + 3; $i < $playerCount; $i++, $x += $numTags) {
            // Loop over the player tags and extract the info for that tag
            foreach ($tags as $index => $tag) {
                $result->addPlayer($tag, $items[($x + $index)]);
            }
        }

        return $result->fetch();
    }
109187
protected function output($buffer)
	{
		$buffer = $this->replaceInsertTags($buffer);
        $buffer = str_replace(array('{{request_token}}', '[{]', '[}]'), array(REQUEST_TOKEN, '{{', '}}'), $buffer);
        $buffer = str_replace('{{request_token}}', \RequestToken::get(), $buffer);

		if (is_array($buffer) || is_object($buffer))
		{
			$buffer = json_encode($buffer);
		}

		echo $buffer;
		exit;
	}
264228
public function appendProtocolHeader(Buffer $buffer)
    {
        $buffer->append('AMQP');
        $buffer->appendUint8(0);
        $buffer->appendUint8(0);
        $buffer->appendUint8(9);
        $buffer->appendUint8(1);
    }
295635
public function statements($buffer)
    {
        $result = $this->_createResult($buffer);
        
        while (strlen($result->buffer) > 0) {
            $this->_resetResult($result);
            
            if ($result->state == '<<<') {
                if (!$this->_initializeHeredoc($result)) {
                    continue;
                }
            }
            
            $rules = array(
                '_scanUse',
                '_scanEscapedChar',
                '_scanRegion',
                '_scanStateEntrant',
                '_scanWsp',
                '_scanChar'
            );
            
            foreach ($rules as $method) {
                if ($this->$method($result)) {
                    break;
                }
            }
            
            if ($result->stop) {
                break;
            }
        }
        
        if (!empty($result->statements) && trim($result->stmt) === '' && strlen($result->buffer) == 0) {
            $this->_combineStatements($result);
            $this->_prepareForDebug($result);
            return $result->statements;
        }
    }
156791
protected function processVersion(Buffer $buffer)
    {

        // Decode into items
        $items = $this->decode($buffer);

        // Set the result to a new result instance
        $result = new Result();

        $result->add('version', $items[2]);

        unset($buffer, $items);

        return $result->fetch();
    }
300735
public function parse($buffer)
    {
        // strip BOM (byte order marker)
        if (substr($buffer, 0, 3) === "\xef\xbb\xbf") {
            $buffer = substr($buffer, 3);
        }

        $this->buffer          = rtrim($buffer, "\x00..\x1f");
        $this->count           = 0;
        $this->env             = null;
        $this->inParens        = false;
        $this->eatWhiteDefault = true;

        $this->saveEncoding();
        $this->extractLineNumbers($buffer);

        $this->pushBlock(null); // root block
        $this->whitespace();
        $this->pushBlock(null);
        $this->popBlock();

        while ($this->parseChunk()) {
            ;
        }

        if ($this->count !== strlen($this->buffer)) {
            $this->throwParseError();
        }

        if (! empty($this->env->parent)) {
            $this->throwParseError('unclosed block');
        }

        if ($this->charset) {
            array_unshift($this->env->children, $this->charset);
        }

        $this->env->isRoot    = true;

        $this->restoreEncoding();

        return $this->env;
    }
185517
private function readMessages(string $buffer) : int
    {
        $emitted_messages = 0;
        $i = 0;
        while (($buffer[$i] ?? '') !== '') {
            $this->buffer .= $buffer[$i++];
            switch ($this->parsing_mode) {
                case self::PARSE_HEADERS:
                    if ($this->buffer === "\r\n") {
                        $this->parsing_mode = self::PARSE_BODY;
                        $this->content_length = (int)$this->headers['Content-Length'];
                        $this->buffer = '';
                    } elseif (substr($this->buffer, -2) === "\r\n") {
                        $parts = explode(':', $this->buffer);
                        $this->headers[$parts[0]] = trim($parts[1]);
                        $this->buffer = '';
                    }
                    break;
                case self::PARSE_BODY:
                    if (strlen($this->buffer) === $this->content_length) {
                        if (!$this->is_accepting_new_requests) {
                            // If we fork, don't read any bytes in the input buffer from the worker process.
                            $this->emitClose();
                            return $emitted_messages;
                        }
                        // MessageBody::parse can throw an Error, maybe log an error?
                        try {
                            $msg = new Message(MessageBody::parse($this->buffer), $this->headers);
                        } catch (Exception $_) {
                            $msg = null;
                        }
                        if ($msg) {
                            $emitted_messages++;
                            $this->emit('message', [$msg]);
                            /** @psalm-suppress DocblockTypeContradiction */
                            if (!$this->is_accepting_new_requests) {
                                // If we fork, don't read any bytes in the input buffer from the worker process.
                                $this->emitClose();
                                return $emitted_messages;
                            }
                        }
                        $this->parsing_mode = self::PARSE_HEADERS;
                        $this->headers = [];
                        $this->buffer = '';
                    }
                    break;
            }
        }
        return $emitted_messages;
    }
352512
protected static function decode_chunked( $buffer )
    {
        $length = 0;
        $new = '';

        // read chunk-size, chunk-extension (if any) and crlf
        // get the position of the linebreak
        $chunkend = strpos($buffer,"\r\n") + 2;
        $temp = substr($buffer,0,$chunkend);
        $chunk_size = hexdec( trim($temp) );
        $chunkstart = $chunkend;
        while($chunk_size > 0)
        {
            $chunkend = strpos($buffer, "\r\n", $chunkstart + $chunk_size);

            // just in case we got a broken connection
            if($chunkend == false)
            {
                $chunk = substr($buffer,$chunkstart);
                // append chunk-data to entity-body
                $new .= $chunk;
                $length += strlen($chunk);
                break;
            }

            // read chunk-data and crlf
            $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
            // append chunk-data to entity-body
            $new .= $chunk;
            // length := length + chunk-size
            $length += strlen($chunk);
            // read chunk-size and crlf
            $chunkstart = $chunkend + 2;

            $chunkend = strpos($buffer,"\r\n",$chunkstart)+2;
            if($chunkend == false)
            {
                break; //just in case we got a broken connection
            }
            $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
            $chunk_size = hexdec( trim($temp) );
            $chunkstart = $chunkend;
        }
        return $new;
    }
258138
protected function processStatus(Buffer $buffer)
    {
        // Set the result to a new result instance
        $result = new Result();

        // Defaults
        $result->add('dedicated', 1);

        // Now burn the challenge, version and size
        $buffer->skip(16);

        // Key / value pairs
        while ($buffer->getLength()) {
            $var = str_replace('si_', '', $buffer->readString());
            $val = $buffer->readString();
            if (empty($var) && empty($val)) {
                break;
            }
            // Add the server prop
            $result->add($var, $val);
        }
        // Now let's do the basic player info
        $this->parsePlayers($buffer, $result);

        // Now grab the rest of the server info
        $result->add('osmask', $buffer->readInt32());
        $result->add('ranked', $buffer->readInt8());
        $result->add('timeleft', $buffer->readInt32());
        $result->add('gamestate', $buffer->readInt8());
        $result->add('servertype', $buffer->readInt8());

        // 0: regular server
        if ($result->get('servertype') == 0) {
            $result->add('interested_clients', $buffer->readInt8());
        } else {
            // 1: tv server
            $result->add('connected_clients', $buffer->readInt32());
            $result->add('max_clients', $buffer->readInt32());
        }

        // Now let's parse the extended player info
        $this->parsePlayersExtra($buffer, $result);

        unset($buffer);

        return $result->fetch();
    }
365633
public function parse($payload)
    {
        if ($payload) {
            try {
                $flags = (defined('Symfony\Component\Yaml\Yaml::PARSE_DATETIME')) ? (SFYaml::PARSE_EXCEPTION_ON_INVALID_TYPE | SFYaml::PARSE_DATETIME) : true;
                return SFYaml::parse(trim(preg_replace('/\t+/', '', $payload)), $flags);
            } catch (\Exception $ex) {
                throw new ParserException('Failed To Parse YAML');
            }
        }

        return [];
    }
319734
function parseFrame(&$buffer)
    {
        //$this->log("PaserFrame. BufferLen=".strlen($buffer));
        //websocket
        $ws  = array();
        $ws['finish'] = false;

        $data_offset = 0;

        //fin:1 rsv1:1 rsv2:1 rsv3:1 opcode:4
        $handle        = ord($buffer[$data_offset]);
        $ws['fin']    = ($handle >> 7) & 0x1;
        $ws['rsv1']   = ($handle >> 6) & 0x1;
        $ws['rsv2']   = ($handle >> 5) & 0x1;
        $ws['rsv3']   = ($handle >> 4) & 0x1;
        $ws['opcode'] =  $handle       & 0xf;
        $data_offset ++;

        //mask:1 length:7
        $handle        = ord($buffer[$data_offset]);
        $ws['mask']    = ($handle >> 7) & 0x1;
        //0-125
        $ws['length']  =  $handle       & 0x7f;
        $length        =  &$ws['length'];
        $data_offset ++;

        //126 short
        if($length == 0x7e)
        {
            //2
            $handle = unpack('nl', substr($buffer, $data_offset, 2));
            $data_offset += 2;
            $length = $handle['l'];
        }
        //127 int64
        elseif($length > 0x7e)
        {
            //8
            $handle = unpack('N*l', substr($buffer, $data_offset, 8));
            $data_offset += 8;
            $length = $handle['l'];

            //超过最大允许的长度了
            if ($length > $this->max_frame_size)
            {
                $this->log('Message is too long.');
                return false;
            }
        }

        //mask-key: int32
        if (0x0 !== $ws['mask'])
        {
            $ws['mask'] = array_map('ord', str_split(substr($buffer, $data_offset, 4)));
            $data_offset += 4;
        }

        //把头去掉
        $buffer = substr($buffer, $data_offset);

        //数据长度为0的帧
        if (0 === $length)
        {
            $ws['finish'] = true;
            $ws['message'] = '';
            return $ws;
        }

        //完整的一个数据帧
        if (strlen($buffer) >= $length)
        {
            $ws['finish'] = true;
            $ws['data'] =  substr($buffer, 0, $length);
            $ws['message'] = $this->parseMessage($ws);
            //截取数据
            $buffer = substr($buffer, $length);
            return $ws;
        }
        //需要继续等待数据
        else
        {
            $ws['finish'] = false;
            $ws['data'] = $buffer;
            $buffer = "";
            return $ws;
        }
    }
992409
public static function long(Buffer $buffer) : ?string
    {
        return is_array($hi = unpack('N', $buffer->read(4))) && is_array($lo = unpack('N', $buffer->read(4)))
            ? bcadd(bcmul(sprintf('%u', $hi[1]), '4294967296'), sprintf('%u', $lo[1]))
            : null
        ;
    }
1252396
public function consumeArray(Buffer $originalBuffer)
    {
        $buffer = $originalBuffer->consumeSlice($originalBuffer->consumeUint32());
        $data = [];
        while (!$buffer->isEmpty()) {
            $data[] = $this->consumeFieldValue($buffer);
        }
        return $data;
    }
1254526
public function handleQueryFromStream(string $buffer): string
    {
        $message = Decoder::decodeMessage($buffer);
        $this->dispatch(Events::QUERY_RECEIVE, new QueryReceiveEvent($message));

        $responseMessage = clone $message;
        $responseMessage->getHeader()
            ->setResponse(true)
            ->setRecursionAvailable($this->resolver->allowsRecursion())
            ->setAuthoritative($this->isAuthoritative($message->getQuestions()));

        try {
            $answers = $this->resolver->getAnswer($responseMessage->getQuestions());
            $responseMessage->setAnswers($answers);
            $this->needsAdditionalRecords($responseMessage);
            $this->dispatch(Events::QUERY_RESPONSE, new QueryResponseEvent($responseMessage));

            return Encoder::encodeMessage($responseMessage);
        } catch (UnsupportedTypeException $e) {
            $responseMessage
                    ->setAnswers([])
                    ->getHeader()->setRcode(Header::RCODE_NOT_IMPLEMENTED);
            $this->dispatch(Events::QUERY_RESPONSE, new QueryResponseEvent($responseMessage));

            return Encoder::encodeMessage($responseMessage);
        }
    }
108638
protected function processPlayers(Buffer $buffer)
    {

        // Set the result to a new result instance
        $result = new Result();

        // Get the number of players
        $result->add('numplayers', $buffer->readInt16());

        // Parse players
        while ($buffer->getLength()) {
            // Player id
            if (($id = $buffer->readInt16()) !== 0) {
                // Add the results
                $result->addPlayer('id', $id);
                $result->addPlayer('name', utf8_encode($buffer->readPascalString()));
            }
        }

        unset($buffer, $id);

        return $result->fetch();
    }
536716
function parseResponse($data)
    {
        if (empty($data)) {
            return [];
        }

        if (isset($data[0]) && count($data[0]) === $this->getKeysCount()) {
            $items = array_combine($data[0], $data[1]);

            return array_filter($items, [$this, 'notNil']);
        }

        throw new Exception('Error when evaluate lua script. Response is: ' . json_encode($data));
    }