Search in sources :

Example 1 with RequestEnvelope

use of POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass.RequestEnvelope in project PokeGOAPI-Java by Grover-c13.

the class RequestHandler method sendInternal.

/**
 * Sends an already built request envelope
 *
 * @param serverResponse the response to append to
 * @param requests list of ServerRequests to be sent
 * @param platformRequests list of ServerPlatformRequests to be sent
 * @param builder the request envelope builder
 * @throws RequestFailedException if this message fails to send
 */
private ServerResponse sendInternal(ServerResponse serverResponse, ServerRequest[] requests, ServerPlatformRequest[] platformRequests, RequestEnvelope.Builder builder) throws RequestFailedException {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    RequestEnvelope request = builder.build();
    try {
        request.writeTo(stream);
    } catch (IOException e) {
        Log.wtf(TAG, "Failed to write request to bytearray ouput stream. This should never happen", e);
    }
    RequestBody body = RequestBody.create(BINARY_MEDIA, stream.toByteArray());
    okhttp3.Request httpRequest = new okhttp3.Request.Builder().url(apiEndpoint).post(body).build();
    try (Response response = client.newCall(httpRequest).execute()) {
        if (response.code() != 200) {
            throw new RequestFailedException("Got a unexpected http code : " + response.code());
        }
        ResponseEnvelope responseEnvelope;
        try (InputStream content = response.body().byteStream()) {
            responseEnvelope = ResponseEnvelope.parseFrom(content);
        } catch (IOException e) {
            // retrieved garbage from the server
            throw new RequestFailedException("Received malformed response : " + e);
        }
        if (responseEnvelope.getApiUrl() != null && responseEnvelope.getApiUrl().length() > 0) {
            apiEndpoint = "https://" + responseEnvelope.getApiUrl() + "/rpc";
        }
        if (responseEnvelope.hasAuthTicket()) {
            authTicket = responseEnvelope.getAuthTicket();
        }
        StatusCode statusCode = responseEnvelope.getStatusCode();
        if (requests.length > 0) {
            for (int i = 0; i < responseEnvelope.getReturnsCount(); i++) {
                ByteString returned = responseEnvelope.getReturns(i);
                ServerRequest serverRequest = requests[i];
                if (returned != null) {
                    serverResponse.addResponse(serverRequest.type, returned);
                    if (serverRequest.type == RequestType.GET_PLAYER) {
                        if (GetPlayerResponse.parseFrom(returned).getBanned()) {
                            throw new BannedException("Cannot send request, your account has been banned!");
                        }
                    }
                } else {
                    throw new RequestFailedException("Received empty response from server");
                }
            }
        }
        for (int i = 0; i < responseEnvelope.getPlatformReturnsCount(); i++) {
            PlatformResponse platformResponse = responseEnvelope.getPlatformReturns(i);
            ByteString returned = platformResponse.getResponse();
            if (returned != null) {
                serverResponse.addResponse(platformResponse.getType(), returned);
            }
        }
        if (statusCode != StatusCode.OK && statusCode != StatusCode.OK_RPC_URL_IN_RESPONSE) {
            if (statusCode == StatusCode.INVALID_AUTH_TOKEN) {
                try {
                    authTicket = null;
                    api.getAuthInfo(true);
                    return sendInternal(serverResponse, requests, platformRequests);
                } catch (LoginFailedException | InvalidCredentialsException e) {
                    throw new RequestFailedException("Failed to refresh auth token!", e);
                } catch (RequestFailedException e) {
                    throw new RequestFailedException("Failed to send request with refreshed auth token!", e);
                }
            } else if (statusCode == StatusCode.REDIRECT) {
                // API_ENDPOINT was not correctly set, should be at this point, though, so redo the request
                return sendInternal(serverResponse, requests, platformRequests, builder);
            } else if (statusCode == StatusCode.BAD_REQUEST) {
                if (api.playerProfile.banned) {
                    throw new BannedException("Cannot send request, your account has been banned!");
                } else {
                    throw new BadRequestException("A bad request was sent!");
                }
            } else {
                throw new RequestFailedException("Failed to send request: " + statusCode);
            }
        }
    } catch (IOException e) {
        throw new RequestFailedException(e);
    } catch (RequestFailedException e) {
        throw e;
    }
    return serverResponse;
}
Also used : InputStream(java.io.InputStream) ByteString(com.google.protobuf.ByteString) PlatformRequest(POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass.RequestEnvelope.PlatformRequest) Request(POGOProtos.Networking.Requests.RequestOuterClass.Request) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) StatusCode(POGOProtos.Networking.Envelopes.ResponseEnvelopeOuterClass.ResponseEnvelope.StatusCode) PlatformResponse(POGOProtos.Networking.Envelopes.ResponseEnvelopeOuterClass.ResponseEnvelope.PlatformResponse) Response(okhttp3.Response) GetPlayerResponse(POGOProtos.Networking.Responses.GetPlayerResponseOuterClass.GetPlayerResponse) ResponseEnvelope(POGOProtos.Networking.Envelopes.ResponseEnvelopeOuterClass.ResponseEnvelope) LoginFailedException(com.pokegoapi.exceptions.request.LoginFailedException) RequestFailedException(com.pokegoapi.exceptions.request.RequestFailedException) InvalidCredentialsException(com.pokegoapi.exceptions.request.InvalidCredentialsException) BannedException(com.pokegoapi.exceptions.request.BannedException) RequestEnvelope(POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass.RequestEnvelope) BadRequestException(com.pokegoapi.exceptions.request.BadRequestException) PlatformResponse(POGOProtos.Networking.Envelopes.ResponseEnvelopeOuterClass.ResponseEnvelope.PlatformResponse) RequestBody(okhttp3.RequestBody)

Example 2 with RequestEnvelope

use of POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass.RequestEnvelope in project PokeGOAPI-Java by Grover-c13.

the class Signature method setSignature.

/**
 * Given a fully built request, set the signature correctly.
 *
 * @param api the api
 * @param builder the RequestEnvelope builder
 * @throws RequestFailedException if an invalid request is sent
 */
public static void setSignature(PokemonGo api, RequestEnvelope.Builder builder) throws RequestFailedException {
    boolean usePtr8 = false;
    byte[][] requestData = new byte[builder.getRequestsCount()][];
    for (int i = 0; i < builder.getRequestsCount(); i++) {
        requestData[i] = builder.getRequests(i).toByteArray();
        RequestType requestType = builder.getRequests(i).getRequestType();
        if (requestType == RequestType.GET_PLAYER) {
            usePtr8 |= api.firstGP;
            api.firstGP = false;
        } else if (requestType == RequestType.GET_MAP_OBJECTS) {
            usePtr8 |= !api.firstGMO;
            api.firstGMO = false;
        }
    }
    double latitude = api.latitude;
    double longitude = api.longitude;
    double accuracy = api.accuracy;
    if (Double.isNaN(latitude)) {
        latitude = 0.0;
    }
    if (Double.isNaN(longitude)) {
        longitude = 0.0;
    }
    if (Double.isNaN(accuracy)) {
        accuracy = 0.0;
    }
    byte[] authTicket;
    if (builder.hasAuthTicket()) {
        authTicket = builder.getAuthTicket().toByteArray();
    } else {
        authTicket = builder.getAuthInfo().toByteArray();
    }
    long currentTimeMillis = api.currentTimeMillis();
    byte[] sessionHash = api.sessionHash;
    HashProvider provider = api.hashProvider;
    Hash hash = provider.provide(currentTimeMillis, latitude, longitude, accuracy, authTicket, sessionHash, requestData);
    long timeSinceStart = currentTimeMillis - api.startTime;
    SignatureOuterClass.Signature.Builder signatureBuilder = SignatureOuterClass.Signature.newBuilder().setLocationHash1(hash.locationAuthHash).setLocationHash2(hash.locationHash).setSessionHash(ByteString.copyFrom(sessionHash)).setTimestamp(currentTimeMillis).setTimestampSinceStart(timeSinceStart).setDeviceInfo(api.getDeviceInfo()).addAllLocationFix(LocationFixes.getDefault(api, builder, currentTimeMillis, RANDOM)).setActivityStatus(api.getActivitySignature(RANDOM)).setUnknown25(provider.getUNK25()).setUnknown27(// Currently random, generation is unknown
    RANDOM.nextInt(59000) + 1000);
    final SignatureOuterClass.Signature.SensorInfo sensorInfo = SensorInfo.getDefault(api, currentTimeMillis, RANDOM);
    if (sensorInfo != null)
        signatureBuilder.addSensorInfo(sensorInfo);
    List<Long> requestHashes = hash.requestHashes;
    for (int i = 0; i < builder.getRequestsCount(); i++) signatureBuilder.addRequestHash(requestHashes.get(i));
    Crypto crypto = new Crypto();
    SignatureOuterClass.Signature signature = signatureBuilder.build();
    byte[] signatureByteArray = signature.toByteArray();
    byte[] encrypted = crypto.encrypt(signatureByteArray, timeSinceStart);
    ByteString signatureBytes = SendEncryptedSignatureRequest.newBuilder().setEncryptedSignature(ByteString.copyFrom(encrypted)).build().toByteString();
    RequestEnvelope.PlatformRequest signatureRequest = RequestEnvelope.PlatformRequest.newBuilder().setType(PlatformRequestType.SEND_ENCRYPTED_SIGNATURE).setRequestMessage(signatureBytes).build();
    builder.addPlatformRequests(signatureRequest);
    if (usePtr8) {
        ByteString ptr8 = UnknownPtr8RequestOuterClass.UnknownPtr8Request.newBuilder().setMessage("15c79df0558009a4242518d2ab65de2a59e09499").build().toByteString();
        builder.addPlatformRequests(RequestEnvelope.PlatformRequest.newBuilder().setType(PlatformRequestType.UNKNOWN_PTR_8).setRequestMessage(ptr8).build());
    }
}
Also used : ByteString(com.google.protobuf.ByteString) Hash(com.pokegoapi.util.hash.Hash) Crypto(com.pokegoapi.util.hash.crypto.Crypto) HashProvider(com.pokegoapi.util.hash.HashProvider) SignatureOuterClass(POGOProtos.Networking.Envelopes.SignatureOuterClass) RequestEnvelope(POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass.RequestEnvelope) RequestType(POGOProtos.Networking.Requests.RequestTypeOuterClass.RequestType) PlatformRequestType(POGOProtos.Networking.Platform.PlatformRequestTypeOuterClass.PlatformRequestType)

Aggregations

RequestEnvelope (POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass.RequestEnvelope)2 ByteString (com.google.protobuf.ByteString)2 PlatformRequest (POGOProtos.Networking.Envelopes.RequestEnvelopeOuterClass.RequestEnvelope.PlatformRequest)1 ResponseEnvelope (POGOProtos.Networking.Envelopes.ResponseEnvelopeOuterClass.ResponseEnvelope)1 PlatformResponse (POGOProtos.Networking.Envelopes.ResponseEnvelopeOuterClass.ResponseEnvelope.PlatformResponse)1 StatusCode (POGOProtos.Networking.Envelopes.ResponseEnvelopeOuterClass.ResponseEnvelope.StatusCode)1 SignatureOuterClass (POGOProtos.Networking.Envelopes.SignatureOuterClass)1 PlatformRequestType (POGOProtos.Networking.Platform.PlatformRequestTypeOuterClass.PlatformRequestType)1 Request (POGOProtos.Networking.Requests.RequestOuterClass.Request)1 RequestType (POGOProtos.Networking.Requests.RequestTypeOuterClass.RequestType)1 GetPlayerResponse (POGOProtos.Networking.Responses.GetPlayerResponseOuterClass.GetPlayerResponse)1 BadRequestException (com.pokegoapi.exceptions.request.BadRequestException)1 BannedException (com.pokegoapi.exceptions.request.BannedException)1 InvalidCredentialsException (com.pokegoapi.exceptions.request.InvalidCredentialsException)1 LoginFailedException (com.pokegoapi.exceptions.request.LoginFailedException)1 RequestFailedException (com.pokegoapi.exceptions.request.RequestFailedException)1 Hash (com.pokegoapi.util.hash.Hash)1 HashProvider (com.pokegoapi.util.hash.HashProvider)1 Crypto (com.pokegoapi.util.hash.crypto.Crypto)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1