waylaidwanderer/PHP-SteamCommunity

What I need do to obtain confirmations?

Closed this issue · 5 comments

v0rix commented

Hi, I try to get confirmations but I don't have success.

What I need do before fetchConfirmations? I need use startMobileSession() or something like this?

Regards

Show your code

v0rix commented

I put the functions that I use in only one class:

class MobileAuth
{

    private static $codeTranslations = [50, 51, 52, 53, 54, 55, 56, 57, 66, 67, 68, 70, 71, 72, 74, 75, 77, 78, 80, 81, 82, 84, 86, 87, 88, 89];
    private static $codeTranslationsLength = 26;
    static $DEFAULT_MOBILE_COOKIES = ['mobileClientVersion' => '0 (2.1.3)', 'mobileClient' => 'android', 'Steam_Language' => 'english', 'dob' => ''];

    private $deviceId;
    private $sharedSecret;
    private $identitySecret;
    private $steamid;

    public function Inicializar($device, $shared, $identity, $steamid)
    {
        $this->deviceId = $device;
        $this->sharedSecret = $shared;
        $this->identitySecret = $identity;
        $this->steamid = $steamid;
    }

    public function ObtenerDevice()
    {
        return $this->deviceId;
    }

    public function ObtenerShared()
    {
        return $this->sharedSecret;
    }

    public function ObtenerIdentity()
    {
        return $this->identitySecret;
    }

    public function ObtenerSteamId()
    {
        return $this->steamid;
    }

    // GUARD CODE
    // ======================

    public function generateSteamGuardCode()
    {
        return $this->generateSteamGuardCodeForTime($this->GetSteamTime());
    }

    public function generateSteamGuardCodeForTime($time)
    {
        if (empty($this->sharedSecret)) {
            return '';
        }

        $sharedSecret = base64_decode($this->sharedSecret);
        $timeHash = pack('N*', 0) . pack('N*', floor($time / 30));
        $hmac = unpack('C*', pack('H*', hash_hmac('sha1', $timeHash, $sharedSecret, false)));
        $hashedData = [];
        $modeIndex = 0;
        foreach ($hmac as $value) {
            $hashedData[$modeIndex] = $this->intToByte($value);
            $modeIndex++;
        }
        $b = $this->intToByte(($hashedData[19] & 0xF));
        $codePoint = ($hashedData[$b] & 0x7F) << 24 | ($hashedData[$b+1] & 0xFF) << 16 | ($hashedData[$b+2] & 0xFF) << 8 | ($hashedData[$b+3] & 0xFF);
        $code = '';
        for ($i = 0; $i < 5; ++$i) {
            $code .= chr(self::$codeTranslations[$codePoint % self::$codeTranslationsLength]);
            $codePoint /= self::$codeTranslationsLength;
        }
        return $code;
    }
    private function intToByte($int)
    {
        return $int & (0xff);
    }

    // STEAM TIME
    // ==================================

    public function GetSteamTime()
    {
        return time() + $this->GetTimeDifference();
    }

    public function GetTimeDifference()
    {
        try 
        {
            $response = $this->cURL('http://api.steampowered.com/ITwoFactorService/QueryTime/v0001', null, ['steamid' => 0]);
            $json = json_decode($response, true);
            if (isset($json['response']) && isset($json['response']['server_time'])) 
            {
                return (int)$json['response']['server_time'] - time();
            }
        } 
        catch (\Exception $ex) 
        {

        }
        return 0;
    }

    private function buildCookie($cookie) 
    {
        $out = "";
        foreach ($cookie as $k => $c) {
            $out .= "{$k}={$c}; ";
        }
        return $out;
    }

    // Confirmaciones
    // =======================================

    public function fetchConfirmations()
    {
        $url = $this->generateConfirmationUrl();
        $confirmations = [];
        $response = '';

        try 
        {
            $response = $this->cURL($url);
        } catch (\Exception $ex) {
            return $confirmations;
        }

        if (strpos($response, '<div>Nothing to confirm</div>') === false) 
        {
            $confIdRegex = '/data-confid="(\d+)"/';
            $confKeyRegex = '/data-key="(\d+)"/';
            $confDescRegex = '/<div>((Confirm|Trade with|Sell -) .+)<\/div>/';
            preg_match_all($confIdRegex, $response, $confIdMatches);
            preg_match_all($confKeyRegex, $response, $confKeyMatches);
            preg_match_all($confDescRegex, $response, $confDescMatches);
            if (count($confIdMatches[1]) > 0 && count($confKeyMatches[1]) > 0 && count($confDescMatches) > 0) {
                for ($i = 0; $i < count($confIdMatches[1]); $i++) {
                    $confId = $confIdMatches[1][$i];
                    $confKey = $confKeyMatches[1][$i];
                    $confDesc = $confDescMatches[1][$i];
                    $confirmations[] = new Confirmation($confId, $confKey, $confDesc);
                }
            } 
            else 
            {
                echo 'Error en Confirmar';
            }
        }

        return $confirmations;
    }

    public function generateConfirmationUrl($tag = 'conf')
    {
        return 'https://steamcommunity.com/mobileconf/conf?' . $this->generateConfirmationQueryParams($tag);
    }

    public function generateConfirmationQueryParams($tag)
    {
        $time = $this->GetSteamTime();
        return 'p=' . $this->ObtenerDevice() . '&a=' . $this->ObtenerSteamId() . '&k=' . $this->_generateConfirmationHashForTime($time, $tag) . '&t=' . $time . '&m=android&tag=' . $tag;
    }

    private function _generateConfirmationHashForTime($time, $tag)
    {
        $identitySecret = base64_decode($this->ObtenerIdentity());
        $array = $tag ? substr($tag, 0, 32) : '';

        for ($i = 8; $i > 0; $i--) 
        {
            $array = chr($time & 0xFF) . $array;
            $time >>= 8;
        }

        $code = hash_hmac("sha1", $array, $identitySecret, true);
        return base64_encode($code);
    }

    // cURL
    // ============================

    public function cURL($url, $ref = null, $postData = null)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        /*if (!empty($this->rootDir)) {
            curl_setopt($ch, CURLOPT_COOKIEFILE, $this->_getCookieFilePath());
            curl_setopt($ch, CURLOPT_COOKIEJAR, $this->_getCookieFilePath());
        }*/
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        //if ($this->mobile) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, ["X-Requested-With: com.valvesoftware.android.steam.community"]);
            curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; Google Nexus 4 - 4.1.1 - API 16 - 768x1280 Build/JRO03S) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30");
            curl_setopt($ch, CURLOPT_COOKIE, $this->buildCookie(self::$DEFAULT_MOBILE_COOKIES));
        /*} else {
            curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0');
        }*/
        if (isset($ref)) 
        {
            curl_setopt($ch, CURLOPT_REFERER, $ref);
        }

        if (isset($postData)) 
        {
            curl_setopt($ch, CURLOPT_POST, true);
            $postStr = "";
            foreach ($postData as $key => $value) 
            {
                if ($postStr)
                    $postStr .= "&";
                $postStr .= $key . "=" . $value;
            }
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postStr);
        }

        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }
}`

Then, I use:

$mobile = new MobileAuth(); $mobile->Inicializar("xxxx", "xxxxx", "xxxxx", "xxxx"); var_dump($mobile->fetchConfirmations());

This looks like edited version. Please use original library and try again

v0rix commented

Yes, I edited because I don't want use all the library, I only need the confirmations. For this reason I need know what function add for make the confirmations work.

I think that is the COOKIEFILES and COOKIEJAR in cURL. This cookies are the session cookies?

This is not an issue with the library and does not belong here.