示例#1
0
 /**
  * @param Session $session
  * @param RequestEnvelope $env
  * @param Request[] $reqs
  * @throws Exception
  */
 public static function sign(Session $session, RequestEnvelope $env, $reqs)
 {
     if (!$session->hasAuthTicket()) {
         return;
     }
     $location = $session->getLocation();
     $rawTicket = $session->getAuthTicket()->toBinary();
     $microTime = MicroTime::get();
     $protoSignature = new ProtoSignature();
     $protoSignature->setTimestampSinceStart($microTime - $session->getStartMicroTime());
     // TODO: LocationFix
     // TODO: AndroidGpsInfo
     // TODO: SensorInfo
     // TODO: DeviceInfo
     // TODO: ActivityStatus
     $protoSignature->setLocationHash1(self::generateLocation1($rawTicket, $location));
     $protoSignature->setLocationHash2(self::generateLocation2($location));
     $protoSignature->setSessionHash($session->getSessionHash());
     $protoSignature->setTimestamp($microTime);
     foreach ($reqs as $req) {
         $protoSignature->addRequestHash(self::generateRequestHash($rawTicket, $req->toProto()->toStream()->getContents()));
     }
     $protoSignature->setUnknown25(9.909701338899655E+18);
     $uk6 = new Unknown6();
     $uk6->setRequestType(6);
     $uk2 = new Unknown2();
     $enc = Encrypt::encrypt($protoSignature->toStream()->getContents(), random_bytes(32));
     $uk2->setEncryptedSignature($enc);
     $uk6->setUnknown2($uk2);
     $env->setUnknown6($uk6);
     $session->getLogger()->debug("Signed request: " . strlen($enc) . " bytes");
 }
示例#2
0
 /**
  * @param Request[] $reqs
  * @param bool|false $createEndpoint
  * @param bool|false $redo
  * @throws Exception
  */
 public function execute($reqs, $createEndpoint = false, $redo = true)
 {
     $reqTypes = [];
     foreach ($reqs as $req) {
         $reqTypes[] = get_class($req);
     }
     $this->logger->info("Execute " . implode(", ", $reqTypes));
     $env = new RequestEnvelope();
     $env->setStatusCode(2);
     $env->setRequestId($this->getRPCId());
     $location = $this->session->getLocation();
     $env->setLatitude($location->getLatitude());
     $env->setLongitude($location->getLongitude());
     $env->setAltitude($location->getAltitude());
     if ($this->session->hasAuthTicket() && $this->session->getAuthTicket()->isValid()) {
         $this->logger->debug("Existing auth ticket");
         $env->setAuthTicket($this->session->getAuthTicket()->toProto());
     } else {
         if (!$this->session->hasToken()) {
             $this->session->authenticate();
         }
         $this->session->setEndpoint(null);
         $this->logger->debug("Auth with token");
         $info = new AuthInfo();
         $info->setProvider($this->session->getType()->getProvider());
         $token = new JWT();
         $token->setContents($this->session->getToken());
         $token->setUnknown2(59);
         $info->setToken($token);
         $env->setAuthInfo($info);
     }
     $env->setUnknown12(989);
     foreach ($reqs as $req) {
         $env->addRequests($req->toProto());
     }
     $URL = $this->session->hasEndpoint() ? $this->session->getEndpoint() : self::APIURL;
     Signature::sign($this->session, $env, $reqs);
     $resp = $this->client->post($URL, ["body" => $env->toStream()->getContents()]);
     $respEnv = new ResponseEnvelope($resp->getBody()->getContents());
     if ($respEnv->hasAuthTicket()) {
         $ticket = new AuthTicket($respEnv->getAuthTicket());
         $this->logger->info("Received auth ticket, expires in " . $ticket->getTimeToExpire() . "s");
         $this->session->setAuthTicket($ticket);
     }
     if ($respEnv->hasApiUrl()) {
         $endpoint = $respEnv->getApiUrl();
         $this->logger->info("Received API endpoint " . $endpoint);
         $this->session->setEndpoint("https://" . $endpoint . "/rpc");
     }
     $statusCode = $respEnv->getStatusCode();
     $this->logger->debug("Status code " . $statusCode);
     if ($statusCode == 102) {
         // Some auth problem
         throw new Exception("Received status code 102: invalid auth");
     } elseif ($statusCode == 53) {
         // Wrong endpoint
         if ($redo) {
             sleep(3);
             $this->execute($reqs, $createEndpoint, false);
             return;
         } else {
             throw new Exception("Received status code 53: wrong endpoint");
         }
     } elseif ($statusCode == 3) {
         // Possible ban
         throw new Exception("Received status code 3: account possibly banned");
     }
     if (!$respEnv->hasReturnsList()) {
         throw new Exception("No responses given");
     }
     $returns = $respEnv->getReturnsList();
     $countResponses = $returns->count();
     if ($countResponses != count($reqs)) {
         throw new Exception("Invalid responses found");
     }
     $responses = [];
     foreach ($returns as $return) {
         $responses[] = $return;
     }
     array_map(function (Request $req, $response) {
         $req->setRawResponse($response);
     }, $reqs, $responses);
 }
 /**
  * Is a setup for the request
  *
  * @param RequestEnvelope $requestEnvelope
  */
 private function resetBuilder(RequestEnvelope &$requestEnvelope)
 {
     $requestEnvelope->setStatusCode(2);
     $requestEnvelope->setRequestId($this->getRequestId());
     if ($this->lastAuthTicket != null && $this->lastAuthTicket->getExpireTimestampMs() > 0 && $this->lastAuthTicket->getExpireTimestampMs() > round(microtime(true) * 1000)) {
         $requestEnvelope->setAuthTicket($this->lastAuthTicket);
     } else {
         $authInfo = new RequestEnvelope_AuthInfo();
         $authInfo->setProvider($this->PokemonGoAPI->getUserProvider());
         $authToken = new RequestEnvelope_AuthInfo_JWT();
         $authToken->setContents($this->userAuthToken);
         $authToken->setUnknown2(59);
         $authInfo->setToken($authToken);
         $requestEnvelope->setAuthInfo($authInfo);
     }
     $requestEnvelope->setUnknown12(989);
     $requestEnvelope->setLatitude($this->PokemonGoAPI->getLatitude());
     $requestEnvelope->setLongitude($this->PokemonGoAPI->getLongitude());
     $requestEnvelope->setAltitude($this->PokemonGoAPI->getAltitude());
 }