Handle parsing extra player data

@param Buffer $buffer
@param Result $result
766666
protected function parsePlayersExtra(Buffer &$buffer, Result &$result)
    {
        // Iterate over the extra player info
        while (($id = $buffer->readInt8()) != 32) {
            $result->addPlayer('total_xp', $buffer->readFloat32());
            $result->addPlayer('teamname', $buffer->readString());
            $result->addPlayer('total_kills', $buffer->readInt32());
            $result->addPlayer('total_deaths', $buffer->readInt32());
        }

        // @todo: Add team stuff

        // Free some memory
        unset($id);
    }
545398
protected function processDetailsGoldSource(Buffer $buffer)
    {

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

        $result->add('address', $buffer->readString());
        $result->add('hostname', $buffer->readString());
        $result->add('map', $buffer->readString());
        $result->add('game_dir', $buffer->readString());
        $result->add('game_descr', $buffer->readString());
        $result->add('num_players', $buffer->readInt8());
        $result->add('max_players', $buffer->readInt8());
        $result->add('version', $buffer->readInt8());
        $result->add('dedicated', $buffer->read());
        $result->add('os', $buffer->read());
        $result->add('password', $buffer->readInt8());

        // Mod section
        $result->add('ismod', $buffer->readInt8());

        // We only run these if ismod is 1 (true)
        if ($result->get('ismod') == 1) {
            $result->add('mod_urlinfo', $buffer->readString());
            $result->add('mod_urldl', $buffer->readString());
            $buffer->skip();
            $result->add('mod_version', $buffer->readInt32Signed());
            $result->add('mod_size', $buffer->readInt32Signed());
            $result->add('mod_type', $buffer->readInt8());
            $result->add('mod_cldll', $buffer->readInt8());
        }

        $result->add('secure', $buffer->readInt8());
        $result->add('num_bots', $buffer->readInt8());

        unset($buffer);

        return $result->fetch();
    }
982745
protected static function parseBitString(&$data, &$result)
    {
        // Bitstring type
        $data = self::parseCommon($data, $bitstringData);
        $result[] = [
            'bit string (' . self::$len . ')',
            'UnsedBits:' . ord($bitstringData[0]) . ':' . ord($bitstringData[1]), ];
    }
1098501
protected function processDetails(Buffer $buffer)
    {

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

        $result->add('serverid', $buffer->readInt32()); // 0
        $result->add('serverip', $buffer->readPascalString(1)); // empty
        $result->add('gameport', $buffer->readInt32());
        $result->add('queryport', $buffer->readInt32()); // 0
        $result->add('servername', utf8_encode($buffer->readPascalString(1)));
        $result->add('mapname', utf8_encode($buffer->readPascalString(1)));
        $result->add('gametype', $buffer->readPascalString(1));
        $result->add('numplayers', $buffer->readInt32());
        $result->add('maxplayers', $buffer->readInt32());
        $result->add('ping', $buffer->readInt32()); // 0

        unset($buffer);

        return $result->fetch();
    }
93105
protected function processDetails(Buffer &$buffer, Result &$result)
    {
        parent::processDetails($buffer, $result);

        // Add in map
        $result->add('mapname', 'Panau');
        $result->add('dedicated', 'true');
    }
1286635
public function processResponse()
    {

        // Grab the result from the parent
        /** @type array $result */
        $result = parent::processResponse();

        // Move some stuff around
        $this->renameResult($result, 'OwningPlayerName', 'hostname');
        $this->renameResult($result, 'p1073741825', 'mapname');
        $this->renameResult($result, 'p1073741826', 'gametype');
        $this->renameResult($result, 'p1073741827', 'servername');
        $this->renameResult($result, 'p1073741828', 'custom_mutators');
        $this->renameResult($result, 'gamemode', 'open');
        $this->renameResult($result, 's32779', 'gamemode');
        $this->renameResult($result, 's0', 'bot_skill');
        $this->renameResult($result, 's6', 'pure_server');
        $this->renameResult($result, 's7', 'password');
        $this->renameResult($result, 's8', 'vs_bots');
        $this->renameResult($result, 's10', 'force_respawn');
        $this->renameResult($result, 'p268435704', 'frag_limit');
        $this->renameResult($result, 'p268435705', 'time_limit');
        $this->renameResult($result, 'p268435703', 'numbots');
        $this->renameResult($result, 'p268435717', 'stock_mutators');

        // Put custom mutators into an array
        if (isset($result['custom_mutators'])) {
            $result['custom_mutators'] = explode("\x1c", $result['custom_mutators']);
        }

        // Delete some unknown stuff
        $this->deleteResult($result, ['s1', 's9', 's11', 's12', 's13', 's14']);

        // Return the result
        return $result;
    }
1325973
protected function processPlayer($data, $fieldCount, Result &$result)
    {

        // Split the items on the comma
        $items = explode(",", $data, $fieldCount);

        // Iterate over the items for this player
        foreach ($items as $item) {
            // Split the key=value pair
            list($key, $value) = explode("=", $item, 2);

            $result->addPlayer(strtolower($key), utf8_encode($value));
        }
    }
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;
    }
905666
protected function parse()
    {
        $this->media    = array();
        $this->extras   = array();
        $this->sheet->resetContents();
        $this->acceptBom();

        while ( ! empty( $this->buffer ) )
        {
            $this->acceptEntry();
        }

        $extraContent = '';

        foreach ( $this->extras as $media => $extra )
        {
            if ( empty( $media ) )
            {
                $extraContent .= $extra;
            }
            else
            {
                $extraContent .= "@media $media\n{\n$extra\n}\n";
            }

            $extraContent .= "\n";
        }

        $this->sheet->setExtraContent( $extraContent );
    }
275840
protected function writeBufferedOutput(BufferedOutput $buffer, $result)
    {
        if ($result === 0 && $buffer->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE) {
            return;
        }

        $this->io->write($buffer->fetch());
    }
1154505
protected function processChannels($data, Result &$result)
    {

        // Create a buffer
        $buffer = new Buffer($data);

        // The first line holds the column names, data returned is in column/row format
        $columns = explode("\t", trim($buffer->readString("\n")), 9);

        // Loop through the rows until we run out of information
        while ($buffer->getLength()) {
            // Grab the row, which is a tabbed list of items
            $row = trim($buffer->readString("\n"));

            // Explode and merge the data with the columns, then parse
            $data = array_combine($columns, explode("\t", $row, 9));

            foreach ($data as $key => $value) {
                // Now add the data to the result
                $result->addTeam($key, utf8_encode($value));
            }
        }

        unset($data, $buffer, $row, $columns, $key, $value);
    }
213663
protected function parseResults($result, array $extra_result_data = array())
    {
        $data = json_decode($result, true);
        $sms_data = array();

        // there was an error
        if (empty($data['sid']) || !empty($data['message'])) {
            return array_merge($this->getDefaults(), $extra_result_data, array(
                'status' => ResultInterface::STATUS_FAILED,
            ));
        }

        // get the id
        $sms_data['id'] = $data['sid'];

        // get the status
        switch ($data['status']) {
            case 'failed':
                $sms_data['status'] = ResultInterface::STATUS_FAILED;
                break;
            case 'received':
                $sms_data['status'] = ResultInterface::STATUS_DELIVERED;
                break;
            default:
                $sms_data['status'] = ResultInterface::STATUS_SENT;
                break;
        }

        return array_merge($this->getDefaults(), $extra_result_data, $sms_data);
    }
286104
protected function processPlayersAndTeams(Buffer &$buffer, Result &$result)
    {

        /*
         * Explode the data into groups. First is player, next is team (item_t)
         * Each group should be as follows:
         *
         * [0] => item_
         * [1] => information for item_
         * ...
         */
        $data = explode("\x00\x00", $buffer->getBuffer());

        // By default item_group is blank, this will be set for each loop thru the data
        $item_group = '';
        // By default the item_type is blank, this will be set on each loop
        $item_type = '';
        // Loop through all of the $data for information and pull it out into the result
        for ($x = 0; $x < count($data) - 1; $x++) {
            // Pull out the item
            $item = $data[$x];
            // If this is an empty item, move on
            if ($item == '' || $item == "\x00") {
                continue;
            }
            /*
            * Left as reference:
            *
            * Each block of player_ and team_t have preceding junk chars
            *
            * player_ is actually \x01player_
            * team_t is actually \x00\x02team_t
            *
            * Probably a by-product of the change to exploding the data from the original.
            *
            * For now we just strip out these characters
            */
            // Check to see if $item has a _ at the end, this is player info
            if (substr($item, -1) == '_') {
                // Set the item group
                $item_group = 'players';
                // Set the item type, rip off any trailing stuff and bad chars
                $item_type = rtrim(str_replace("\x01", '', $item), '_');
            } elseif (substr($item, -2) == '_t') {
                // Check to see if $item has a _t at the end, this is team info
                // Set the item group
                $item_group = 'teams';
                // Set the item type, rip off any trailing stuff and bad chars
                $item_type = rtrim(str_replace(["\x00", "\x02"], '', $item), '_t');
            } else {
                // We can assume it is data belonging to a previously defined item

                // Make a temp buffer so we have easier access to the data
                $buf_temp = new Buffer($item, Buffer::NUMBER_TYPE_BIGENDIAN);
                // Get the values
                while ($buf_temp->getLength()) {
                    // No value so break the loop, end of string
                    if (($val = $buf_temp->readString()) === '') {
                        break;
                    }
                    // Add the value to the proper item in the correct group
                    $result->addSub($item_group, $item_type, utf8_encode(trim($val)));
                }
                // Unset our buffer
                unset($buf_temp);
            }
        }
        // Free up some memory
        unset($data, $item, $item_group, $item_type, $val);
    }
935461
private static function parseRgbComponent($input, &$result)
    {
        if (preg_match('/^\\s*(\\d*(?:\\.\\d*)?)(%?)\\s*$/', $input, $matches)) {
            $result = floatval($matches[1]);
            
            if ($matches[2] === '%') {
                $result = 255 * $result / 100;
            }
            
            $result = (int)$result;
            
            if ($result < 0) $result = 0;
            if ($result > 255) $result = 255;
            
            return true;
        }
        return false;
    }
672949
protected function parseSendResults($result, array $extra_result_data = array())
    {
        $result = trim($result);

        $this->checkForUnrecoverableError($result);

        if (!$this->isMessageSent($result)) {
            return array_merge($this->getDefaults(), $extra_result_data);
        }

        // The message was successfully sent!
        $sms_data = array(
            'status' => ResultInterface::STATUS_SENT,
        );
        $arr = explode(' ', $result);
        if (3 === count($arr)) {
            // eg. OK 375055 UR:LO_5
            list($_, $ref) = explode(':', $arr[2]);
            $sms_data['id'] = $arr[1];
            $sms_data['user_ref'] = $ref;
        } elseif (2 === count($arr)) {
            // eg. OK 375056
            $sms_data['id'] = $arr[1];
        }

        return array_merge($this->getDefaults(), $extra_result_data, $sms_data);
    }
648879
protected function processRules(Buffer $buffer)
    {
        // Set the result to a new result instance
        $result = new Result();

        // Burn extra header
        $buffer->skip(1);

        // Read rules until we run out of buffer
        while ($buffer->getLength()) {
            $key = $buffer->readString();
            // Check for map
            if (strstr($key, "Map:")) {
                $result->addSub("maplist", "name", $buffer->readString());
            } else // Regular rule
            {
                $result->add($key, $buffer->readString());
            }
        }

        unset($buffer);

        return $result->fetch();
    }
1266000
public function sendResult($result)
    {
        if (@ob_get_length()) {
            @ob_end_clean();
        }
        if (isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false) {
            header('Content-Type: application/json; charset=' . APP_CHARSET, true);
        } else {
            header('Content-Type: text/plain; charset=' . APP_CHARSET, true);
        }
        echo json_encode($result);
        die();
    }