private static async Task <ResponseEnvelope> PerformRemoteProcedureCall <TRequest>(this System.Net.Http.HttpClient client, string url, RequestEnvelope requestEnvelope, int tries = 0) where TRequest : IMessage <TRequest> { //Encode payload and put in envelope, then send var data = requestEnvelope.ToByteString(); var result = await client.PostAsync(url, new ByteArrayContent(data.ToByteArray())).ConfigureAwait(false); //Decode message var responseData = await result.Content.ReadAsByteArrayAsync().ConfigureAwait(false); var codedStream = new CodedInputStream(responseData); var decodedResponse = new ResponseEnvelope(); decodedResponse.MergeFrom(codedStream); Logger.Debug("requestEnvelope: " + strRequestEnvelope(requestEnvelope)); Logger.Debug("decodedResponse: " + strResponseEnvelope(decodedResponse)); if (tries < 8) { if (decodedResponse.StatusCode == ResponseEnvelope.Types.StatusCode.InvalidAuthToken) { RandomHelper.RandomSleep(600); return(PerformRemoteProcedureCall <TRequest>(client, url, requestEnvelope, ++tries).Result); } if (decodedResponse.StatusCode == ResponseEnvelope.Types.StatusCode.Redirect && requestEnvelope.Requests.Count == 1) { RandomHelper.RandomSleep(600); return(PerformRemoteProcedureCall <TRequest>(client, url, requestEnvelope, ++tries).Result); } } return(decodedResponse); }
/// <summary> /// Called when <see cref="RestSharp"/> recieves a response envelope async. /// </summary> /// <param name="envelope">Response envelope recieved.</param> public void OnResponse(IRestResponse response) { ResponseEnvelope resEnv = new ResponseEnvelope(); //At this point we've got a response //Probably a response envelope if (response.RawBytes != null && response.RawBytes.Length != 0) { resEnv.MergeFrom(response.RawBytes); decoratedFuture.OnResponse(resEnv); } //TODO: Handle exceptions }
public static async Task <ResponseEnvelope> PostProto(this HttpClient client, string url, IMessage request) { //Encode payload and put in envelop, then send var data = request.ToByteString(); var result = await client.PostAsync(url, new ByteArrayContent(data.ToByteArray())); //Decode message var responseData = await result.Content.ReadAsByteArrayAsync(); var codedStream = new CodedInputStream(responseData); var decodedResponse = new ResponseEnvelope(); decodedResponse.MergeFrom(codedStream); return(decodedResponse); }
public async Task <ResponseEnvelope> PostProto <TRequest>(string url, RequestEnvelope requestEnvelope) where TRequest : IMessage <TRequest> { //Encode payload and put in envelop, then send var data = requestEnvelope.ToByteString(); var result = await PostAsync(url, new ByteArrayContent(data.ToByteArray())); //Decode message var responseData = await result.Content.ReadAsByteArrayAsync(); var codedStream = new CodedInputStream(responseData); var decodedResponse = new ResponseEnvelope(); decodedResponse.MergeFrom(codedStream); return(decodedResponse); }
private static async Task <ResponseEnvelope> PerformRemoteProcedureCall <TRequest>(this System.Net.Http.HttpClient client, string url, RequestEnvelope requestEnvelope) where TRequest : IMessage <TRequest> { //Encode payload and put in envelop, then send var data = requestEnvelope.ToByteString(); var result = await client.PostAsync(url, new ByteArrayContent(data.ToByteArray())); //Decode message var responseData = await result.Content.ReadAsByteArrayAsync(); var codedStream = new CodedInputStream(responseData); var decodedResponse = new ResponseEnvelope(); decodedResponse.MergeFrom(codedStream); return(decodedResponse); }
public static async Task <ResponseEnvelope> PostProto <TRequest>(this System.Net.Http.HttpClient client, string url, RequestEnvelope requestEnvelope) where TRequest : IMessage <TRequest> { //Encode payload and put in envelop, then send var data = requestEnvelope.ToByteString(); var result = await client.PostAsync(url, new ByteArrayContent(data.ToByteArray())); if (result.StatusCode == System.Net.HttpStatusCode.Forbidden) { throw new IPBannedException("IP Address is banned"); } //Decode message var responseData = await result.Content.ReadAsByteArrayAsync(); var codedStream = new CodedInputStream(responseData); var decodedResponse = new ResponseEnvelope(); decodedResponse.MergeFrom(codedStream); return(decodedResponse); }
public static async Task <ResponseEnvelope> PostProto <TRequest>(this System.Net.Http.HttpClient client, string url, RequestEnvelope requestEnvelope) where TRequest : IMessage <TRequest> { HttpResponseMessage result = null; for (int i = 0; i < 3; i++) { try { //Encode payload and put in envelop, then send if (requestEnvelope == null) { return(new ResponseEnvelope()); } var data = requestEnvelope.ToByteString(); result = await client.PostAsync(url, new ByteArrayContent(data.ToByteArray())); break; } catch { // ignored } } if (result != null) { //Decode message var responseData = await result.Content.ReadAsByteArrayAsync(); var codedStream = new CodedInputStream(responseData); var decodedResponse = new ResponseEnvelope(); decodedResponse.MergeFrom(codedStream); return(decodedResponse); } return(new ResponseEnvelope()); }
public async Task <ResponseEnvelope> PostProto <TRequest>(string url, RequestEnvelope requestEnvelope) where TRequest : IMessage <TRequest> { // robertmclaws: Let's be pro-active about token failures, instead of reactive. if (AccessToken == null || AccessToken.IsExpired) { await Login.DoLogin(); } //Encode payload and put in envelop, then send var data = requestEnvelope.ToByteString(); var result = await PostAsync(url, new ByteArrayContent(data.ToByteArray())); //Decode message var responseData = await result.Content.ReadAsByteArrayAsync(); var codedStream = new CodedInputStream(responseData); var decodedResponse = new ResponseEnvelope(); decodedResponse.MergeFrom(codedStream); return(decodedResponse); }
private static async Task <ResponseEnvelope> PerformRemoteProcedureCall <TRequest>(this System.Net.Http.HttpClient client, Client apiClient, RequestEnvelope requestEnvelope) where TRequest : IMessage <TRequest> { // Check killswitch from url before making API calls. if (!apiClient.Settings.UseLegacyAPI) { if (apiClient.CheckCurrentVersionOutdated()) { throw new MinimumClientVersionException(apiClient.CurrentApiEmulationVersion, apiClient.MinimumClientVersion); } } //Encode payload and put in envelop, then send var data = requestEnvelope.ToByteString(); var result = await client.PostAsync(apiClient.ApiUrl, new ByteArrayContent(data.ToByteArray())).ConfigureAwait(false); //Decode message var responseData = await result.Content.ReadAsByteArrayAsync().ConfigureAwait(false); var codedStream = new CodedInputStream(responseData); ResponseEnvelope serverResponse = new ResponseEnvelope(); serverResponse.MergeFrom(codedStream); // Process Platform8Response CommonRequest.ProcessPlatform8Response(apiClient, serverResponse); if (!string.IsNullOrEmpty(serverResponse.ApiUrl)) { apiClient.ApiUrl = "https://" + serverResponse.ApiUrl + "/rpc"; } if (serverResponse.AuthTicket != null) { if (serverResponse.AuthTicket.ExpireTimestampMs > (ulong)Utils.GetTime(true)) { apiClient.AuthTicket = serverResponse.AuthTicket; } else { // Expired auth ticket. apiClient.AuthTicket = null; } } switch (serverResponse.StatusCode) { case ResponseEnvelope.Types.StatusCode.InvalidAuthToken: await apiClient.RequestBuilder.RegenerateRequestEnvelopeWithNewAccessToken(requestEnvelope).ConfigureAwait(false); return(await PerformRemoteProcedureCall <TRequest>(client, apiClient, requestEnvelope).ConfigureAwait(false)); case ResponseEnvelope.Types.StatusCode.Redirect: // 53 means that the api_endpoint was not correctly set, should be at this point, though, so redo the request return(await PerformRemoteProcedureCall <TRequest>(client, apiClient, requestEnvelope).ConfigureAwait(false)); case ResponseEnvelope.Types.StatusCode.BadRequest: // Your account may be banned! please try from the official client. throw new APIBadRequestException("BAD REQUEST \r\n" + JsonConvert.SerializeObject(requestEnvelope)); case ResponseEnvelope.Types.StatusCode.Unknown: break; case ResponseEnvelope.Types.StatusCode.Ok: break; case ResponseEnvelope.Types.StatusCode.OkRpcUrlInResponse: break; case ResponseEnvelope.Types.StatusCode.InvalidRequest: break; case ResponseEnvelope.Types.StatusCode.InvalidPlatformRequest: break; case ResponseEnvelope.Types.StatusCode.SessionInvalidated: throw new SessionInvalidatedException("SESSION INVALIDATED EXCEPTION"); default: throw new ArgumentOutOfRangeException(); } return(serverResponse); }
/// <summary> /// /// </summary> /// <param name="url"></param> /// <param name="payload"></param> /// <param name="retryPolicy"></param> /// <param name="token"></param> /// <param name="attemptCount"></param> /// <param name="redirectCount"></param> /// <returns></returns> internal async Task <ResponseEnvelope> PostProto(string url, ByteArrayContent payload, RetryPolicy retryPolicy, CancellationToken token, int attemptCount = 0, int redirectCount = 0) { // robertmclaws: If someone wants us to be done, we're done. if (token.IsCancellationRequested) { Logger.Write("The request was cancelled. (PostProto cancellation check)"); return(null); } attemptCount++; // robertmclaws: If we've exceeded the maximum number of attempts, we're done. if (attemptCount > retryPolicy.MaxFailureAttempts) { Logger.Write("The request exceeded the number of retries allowed and has been cancelled."); return(null); } if (redirectCount > retryPolicy.MaxRedirectAttempts) { Logger.Write("The request exceeded the number of redirect attempts allowed and has been cancelled."); return(null); } // robertmclaws: We're gonna keep going, so let's be pro-active about token failures, instead of reactive. if (AuthenticatedUser == null || AuthenticatedUser.IsExpired) { // @robertmclaws: Calling "Authenticate" cancels all current requests and fires off a complex login routine. // More than likely, we just want to refresh the tokens. await CurrentProvider.GetAuthenticatedUser().ConfigureAwait(false); } var result = await PostAsync(url, payload, token); var response = new ResponseEnvelope(); var responseData = await result.Content.ReadAsByteArrayAsync(); using (var codedStream = new CodedInputStream(responseData)) { response.MergeFrom(codedStream); } switch ((StatusCodes)response.StatusCode) { case StatusCodes.ValidResponse: if (response.AuthTicket != null) { Logger.Write("Received a new AuthTicket from the Api!"); AuthenticatedUser.AuthTicket = response.AuthTicket; // robertmclaws to do: See if we need to clone the AccessToken so we don't have a threading violation. RaiseAuthenticatedUserUpdated(AuthenticatedUser); } return(response); case StatusCodes.AccessDenied: Logger.Write("Account has been banned. Our condolences for your loss."); CancelCurrentRequests(); //RequestQueue.CompleteAdding(); // robertmclaws to do: Allow you to stop adding events to the queue, and re-initialize the queue if needed. throw new AccountLockedException(); case StatusCodes.Redirect: if (!Regex.IsMatch(response.ApiUrl, "pgorelease\\.nianticlabs\\.com\\/plfe\\/\\d+")) { throw new Exception($"Received an incorrect API url '{response.ApiUrl}', status code was '{response.StatusCode}'."); } ApiUrl = $"https://{response.ApiUrl}/rpc"; Logger.Write($"Received an updated API url = {ApiUrl}"); // robertmclaws to do: Check to see if redirects should count against the RetryPolicy. await Task.Delay(retryPolicy.DelayInSeconds * 1000); redirectCount++; return(await PostProto(response.ApiUrl, payload, retryPolicy, token, attemptCount, redirectCount)); case StatusCodes.InvalidToken: Logger.Write("Received StatusCode 102, reauthenticating."); AuthenticatedUser?.Expire(); // robertmclaws: trigger a retry here. We'll automatically try to log in again on the next request. await Task.Delay(retryPolicy.DelayInSeconds * 1000); return(await PostProto(response.ApiUrl, payload, retryPolicy, token, attemptCount, redirectCount)); case StatusCodes.ServerOverloaded: // Per @wallycz, on code 52, wait 11 seconds before sending the request again. Logger.Write("Server says to slow the hell down. Try again in 11 sec."); await Task.Delay(11000); return(await PostProto(response.ApiUrl, payload, retryPolicy, token, attemptCount, redirectCount)); default: Logger.Write($"Unknown status code: {response.StatusCode}"); break; } return(response); }
private static async Task <ResponseEnvelope> PerformRemoteProcedureCall <TRequest>(this System.Net.Http.HttpClient client, Client apiClient, RequestEnvelope requestEnvelope) where TRequest : IMessage <TRequest> { // Check killswitch from url before making API calls. if (!apiClient.Settings.UseLegacyAPI) { if (apiClient.CheckCurrentVersionOutdated()) { throw new MinimumClientVersionException(apiClient.CurrentApiEmulationVersion, apiClient.MinimumClientVersion); } } //Encode payload and put in envelop, then send var data = requestEnvelope.ToByteString(); var result = await client.PostAsync(apiClient.ApiUrl, new ByteArrayContent(data.ToByteArray())); //Decode message var responseData = await result.Content.ReadAsByteArrayAsync(); var codedStream = new CodedInputStream(responseData); ResponseEnvelope serverResponse = new ResponseEnvelope(); serverResponse.MergeFrom(codedStream); if (!string.IsNullOrEmpty(serverResponse.ApiUrl)) { apiClient.ApiUrl = "https://" + serverResponse.ApiUrl + "/rpc"; } if (serverResponse.AuthTicket != null) { apiClient.AccessToken.AuthTicket = serverResponse.AuthTicket; } switch (serverResponse.StatusCode) { case ResponseEnvelope.Types.StatusCode.InvalidAuthToken: apiClient.AccessToken.Expire(); await Rpc.Login.Reauthenticate(apiClient); Rpc.Login.SaveAccessToken(apiClient.AccessToken); throw new AccessTokenExpiredException(); case ResponseEnvelope.Types.StatusCode.Redirect: // 53 means that the api_endpoint was not correctly set, should be at this point, though, so redo the request return(await PerformRemoteProcedureCall <TRequest>(client, apiClient, requestEnvelope)); case ResponseEnvelope.Types.StatusCode.BadRequest: // Your account may be banned! please try from the official client. throw new LoginFailedException("Your account may be banned! please try from the official client."); case ResponseEnvelope.Types.StatusCode.Unknown: break; case ResponseEnvelope.Types.StatusCode.Ok: break; case ResponseEnvelope.Types.StatusCode.OkRpcUrlInResponse: break; case ResponseEnvelope.Types.StatusCode.InvalidRequest: break; case ResponseEnvelope.Types.StatusCode.InvalidPlatformRequest: break; case ResponseEnvelope.Types.StatusCode.SessionInvalidated: break; default: throw new ArgumentOutOfRangeException(); } return(serverResponse); }