Example #1
0
        public async Task <HashResponseContent> RequestHashesAsync(HashRequestContent request)
        {
            int retry = 3;

            do
            {
                try
                {
                    return(await InternalRequestHashesAsync(request).ConfigureAwait(false));
                }
                catch (HasherException hashEx)
                {
                    throw hashEx;
                }
                catch (TimeoutException)
                {
                    throw new HasherException("Pokefamer Hasher server might down - timeout out");
                }
                catch (Exception ex)
                {
                    APIConfiguration.Logger.LogDebug(ex.Message);
                }
                finally
                {
                    retry--;
                }
                await Task.Delay(1000).ConfigureAwait(false);
            } while (retry > 0);

            throw new HasherException("Pokefamer Hash API server might be down");
        }
Example #2
0
        private HashResponseContent InternalRequestHashes(HashRequestContent request)
        {
            using (var client = new System.Net.Http.HttpClient())
            {
                client.BaseAddress = _baseAddress;
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                client.DefaultRequestHeaders.Add("X-AuthToken", this.apiKey);

                var content = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json");
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                var response = client.PostAsync(_endpoint, content).Result;

                switch (response.StatusCode)
                {
                case HttpStatusCode.OK:     //200
                    AuthTokenExpiration  = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc).AddSeconds(Convert.ToUInt32(((String[])response.Headers.GetValues("X-AuthTokenExpiration"))[0])).ToLocalTime();
                    MaxRequestCount      = Convert.ToUInt16(((string[])response.Headers.GetValues("X-MaxRequestCount"))[0]);
                    RatePeriodEnd        = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc).AddSeconds(Convert.ToUInt32(((String[])response.Headers.GetValues("X-RatePeriodEnd"))[0])).ToLocalTime();
                    RateRequestRemaining = Convert.ToUInt16(((string[])response.Headers.GetValues("X-RateRequestsRemaining"))[0]);
                    RateLimitSeconds     = Convert.ToUInt16(((string[])response.Headers.GetValues("X-RateLimitSeconds"))[0]);
                    var remainingSeconds = (DateTime.Now - RatePeriodEnd).TotalSeconds * -1;

                    Logger.Debug($"{RateRequestRemaining}/{MaxRequestCount} requests remaining for the next {remainingSeconds} seconds. Key expires on: {AuthTokenExpiration}");
                    if ((AuthTokenExpiration - DateTime.Now).TotalDays <= 3)
                    {
                        if (ExpirationCounter-- == 0)
                        {
                            ExpirationCounter = 1000;
                            Logger.ColoredConsoleWrite(ConsoleColor.Red, $"Attention! Your key is expiring in {(AuthTokenExpiration - DateTime.Now).Days} days and {(AuthTokenExpiration - DateTime.Now).Hours} hours! Expiration date: {AuthTokenExpiration}", LogLevel.Warning);
                        }
                    }
                    ;
                    return(JsonConvert.DeserializeObject <HashResponseContent>(response.Content.ReadAsStringAsync().Result));

                case HttpStatusCode.BadRequest:     // 400
                    var responseText = response.Content.ReadAsStringAsync().Result;
                    throw new HasherException($"[HashService] 400: Your key is probably expired! {responseText}");

                case HttpStatusCode.Unauthorized:     // 401
                    Shared.KeyCollection.removeKey(this.apiKey);
                    throw new HasherException("[HashService] 401: Your PF-Hashkey you provided is incorrect (or not valid anymore). ");

                case (HttpStatusCode)429:     // To many requests
                    responseText = response.Content.ReadAsStringAsync().Result;
                    throw new HasherException($"[HashService] 429: Your request has been limited (Message : {responseText})");

                case HttpStatusCode.ServiceUnavailable:
                    responseText = response.Content.ReadAsStringAsync().Result;
                    throw new HasherException($"[HashService] 503: It seems PokeFarmer server {_baseAddress}{_endpoint} is unavailable (Message : {responseText}) ");

                default:
                    RandomHelper.RandomSleep(10000, 11000);
                    throw new HasherException($"[HashService] Unknown: Pokefamer Hash API ({_baseAddress}{_endpoint}) might down!");
                }
            }
        }
Example #3
0
        public HashResponseContent RequestHashes(HashRequestContent request)
        {
            int  retry         = 3;
            int  cyclingRetrys = 40;
            bool changeKey;

            do
            {
                changeKey = false;
                try
                {
                    if (!NoValidKey)
                    {
                        return(InternalRequestHashes(request));
                    }
                }
                catch (HasherException hashEx)
                {
                    changeKey = true;
                    cyclingRetrys--;
                    Logger.Write(hashEx.Message);
                    if (cyclingRetrys < 0)
                    {
                        throw hashEx;
                    }
                }
                catch (Exception ex)
                {
                    Logger.ColoredConsoleWrite(ConsoleColor.Red, "Error: PokeHashHasher.cs - RequestHashes()");
                    Logger.ColoredConsoleWrite(ConsoleColor.Red, ex.Message);
                }
                if (changeKey)
                {
                    var nextKey = Shared.KeyCollection.nextKey();
                    if (nextKey != "")
                    {
                        this.apiKey = nextKey;
                        Logger.Debug("Changing KEY to: " + this.apiKey.Substring(0, 5));
                    }
                    else
                    {
                        NoValidKey = true;
                        Logger.ColoredConsoleWrite(ConsoleColor.Red, "Error: PokeHashHasher.cs - NO VALID KEY FOUND - STOPPING");
                        System.Console.ReadKey();
                        Environment.Exit(-1);
                    }
                    RandomHelper.RandomSleep(250, 300);
                }
                else
                {
                    RandomHelper.RandomSleep(1000, 1100);
                    retry--;
                }
            } while (retry > 0);

            throw new HasherException("[HasherExeption] Default: pokefamer Hash API server might down");
        }
Example #4
0
        public async Task <HashResponseContent> RequestHashesAsync(HashRequestContent request)
        {
            var hashed = new HashResponseContent()
            {
                LocationAuthHash = Utils.GenerateLocation1(request.AuthTicket, request.Latitude, request.Longitude, request.Altitude),
                LocationHash     = Utils.GenerateLocation2(request.Latitude, request.Longitude, request.Altitude),
                RequestHashes    = new List <long>()
            };

            foreach (var req in request.Requests)
            {
                hashed.RequestHashes.Add((long)Utils.GenerateRequestHash(request.AuthTicket, req));
            }

            return(hashed);
        }
Example #5
0
        public static string[] GetInformation(string apiKey)
        {
            var result = new [] { "", "" };
            var client = new System.Net.Http.HttpClient();

            Resources.Api.SetAPIKeyHashServerURL(apiKey);
            _baseAddress = Resources.Api.HashServerInfo.URL;

            client.BaseAddress = _baseAddress;
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Add("X-AuthToken", apiKey);

            var hashRequest = new HashRequestContent();

            var content = new StringContent(JsonConvert.SerializeObject(hashRequest), Encoding.UTF8, "application/json");

            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            HttpResponseMessage response = null;

            try {
                response = client.PostAsync(Resources.Api.EndPoint, content).Result;
            } catch (Exception) {
                //client.BaseAddress = _baseAddress2;
                //response = client.PostAsync(Resources.Api.EndPoint, content).Result;
            }
            try {
                var AuthTokenExpiration  = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc).AddSeconds(Convert.ToUInt32(((String[])response.Headers.GetValues("X-AuthTokenExpiration"))[0])).ToLocalTime();
                var MaxRequestCount      = Convert.ToUInt16(((string[])response.Headers.GetValues("X-MaxRequestCount"))[0]);
                var RatePeriodEnd        = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc).AddSeconds(Convert.ToUInt32(((String[])response.Headers.GetValues("X-RatePeriodEnd"))[0])).ToLocalTime();
                var RateRequestRemaining = Convert.ToUInt16(((string[])response.Headers.GetValues("X-RateRequestsRemaining"))[0]);
                var RateLimitSeconds     = Convert.ToUInt16(((string[])response.Headers.GetValues("X-RateLimitSeconds"))[0]);
                var remainingSeconds     = (DateTime.Now - RatePeriodEnd).TotalSeconds * -1;
                Logger.Info($"{apiKey} : {RateRequestRemaining}/{MaxRequestCount} requests remaining for the next {remainingSeconds} seconds. Key expires on: {AuthTokenExpiration}");
                result[0] = MaxRequestCount.ToString();
                result[1] = AuthTokenExpiration.ToString("dd/MM/yyyy HH:mm:ss");
            } catch (Exception) {
                result[1] = response.StatusCode.ToString();
            }

            return(result);
        }
Example #6
0
        private async Task <HashResponseContent> InternalRequestHashesAsync(HashRequestContent request)
        {
            string key = GetAPIKey();

            var maskedKey = key.Substring(0, 4) + "".PadLeft(key.Length - 8, 'X') + key.Substring(key.Length - 4, 4);

            // NOTE: This is really bad. Don't create new HttpClient's all the time.
            // Use a single client per-thread if you need one.
            using (var client = new System.Net.Http.HttpClient())
            {
                // The URL to the hashing server.
                // Do not include "api/v1/hash" unless you know why you're doing it, and want to modify this code.
                client.BaseAddress = new Uri(PokeHashURL);

                // By default, all requests (and this example) are in JSON.
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                // Set the X-AuthToken to the key you purchased from Bossland GmbH
                client.DefaultRequestHeaders.Add("X-AuthToken", key);

                var content = new StringContent(JsonConvert.SerializeObject(request), Encoding.ASCII, "application/json");
                // An odd bug with HttpClient. You need to set the content type again.
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                Stopwatch           watcher  = new Stopwatch();
                HttpResponseMessage response = null;
                watcher.Start();
                Stat stat = new Stat()
                {
                    Timestamp = DateTime.Now
                };
                try
                {
                    response = await client.PostAsync(apiEndPoint, content).ConfigureAwait(false);
                }
                catch (Exception)
                {
                    try
                    {
                        client.BaseAddress = new Uri(PokeHashURL2);
                        response           = await client.PostAsync(apiEndPoint, content).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                finally
                {
                    watcher.Stop();

                    // Need to check for null response.
                    if (response == null)
                    {
                        throw new HasherException($"Hash API server ({client.BaseAddress}{apiEndPoint}) might down!");
                    }

                    fullStats.APICalles++;
                    fullStats.TotalTimes += watcher.ElapsedMilliseconds;

                    stat.ResponseTime = watcher.ElapsedMilliseconds;
                    statistics.Add(stat);
                    statistics.RemoveAll(x => x.Timestamp < DateTime.Now.AddMinutes(-1));
                    if (statistics.Count > 0)
                    {
                        lastPrintVerbose = DateTime.Now;
                        double agv = statistics.Sum(x => x.ResponseTime) / statistics.Count;
                        fullStats.Last60MinAPICalles  = statistics.Count;
                        fullStats.Last60MinAPIAvgTime = agv;
                        fullStats.Fastest             = fullStats.Fastest == 0 ? watcher.ElapsedMilliseconds : Math.Min(fullStats.Fastest, watcher.ElapsedMilliseconds);
                        fullStats.Slowest             = Math.Max(fullStats.Slowest, watcher.ElapsedMilliseconds);
                        fullStats.MaskedAPIKey        = maskedKey;
                    }
#pragma warning disable IDE0018 // Inline variable declaration - Build.Bat Error Happens if We Do
                    int maxRequestCount = 0;
                    IEnumerable <string> headers;
                    IEnumerable <string> requestRemains;
                    if (response.Headers.TryGetValues("X-MaxRequestCount", out headers))
                    {
                        // Get the rate-limit period ends at timestamp in seconds.
                        maxRequestCount = Convert.ToInt32(headers.First());
                    }

                    if (response.Headers.TryGetValues("X-AuthTokenExpiration", out headers))
                    {
                        uint secondsToExpiration = 0;
                        secondsToExpiration = Convert.ToUInt32(headers.First());
                        fullStats.Expired   = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
                                              .AddSeconds(secondsToExpiration).ToLocalTime().ToString("yyyy/MM/dd HH:mm:ss");
                    }

                    if (response.Headers.TryGetValues("X-RateRequestsRemaining", out requestRemains))
                    {
                        // Get the rate-limit period ends at timestamp in seconds.
                        int requestRemain = Convert.ToInt32(requestRemains.First());
                        fullStats.HealthyRate = (double)(requestRemain) / maxRequestCount;
                        UpdateRate(key, requestRemain);
                    }
                    APIConfiguration.Logger.HashStatusUpdate(fullStats);
#pragma warning restore IDE0018 // Inline variable declaration - Build.Bat Error Happens if We Do
                }

                // TODO: Fix this up with proper retry-after when we get rate limited.
                switch (response.StatusCode)
                {
                // All good. Return the hashes back to the caller. :D
                case HttpStatusCode.OK:
                    return(JsonConvert.DeserializeObject <HashResponseContent>(await response.Content.ReadAsStringAsync().ConfigureAwait(false)));

                // Returned when something in your request is "invalid". Also when X-AuthToken is not set.
                // See the error message for why it is bad.
                case HttpStatusCode.BadRequest:
                    string responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                    if (responseText.Contains("Unauthorized"))
                    {
                        APIConfiguration.Logger.LogDebug($"Unauthorized : {key}  ");
                        if (apiKeys.Count() > 1)
                        {
                            apiKeys.RemoveAll(x => x.Key == key);
                            return(await RequestHashesAsync(request).ConfigureAwait(false));
                        }
                        throw new HasherException($"Your API Key: {maskedKey} is incorrect or expired, please check auth.json (Pokefamer Message : {responseText})");
                    }
                    Console.WriteLine($"Bad request sent to the hashing server! {responseText}");

                    break;

                // This error code is returned when your "key" is not in a valid state. (Expired, invalid, etc)
                case HttpStatusCode.Unauthorized:
                    APIConfiguration.Logger.LogDebug($"Unauthorized : {key}  ");
                    if (apiKeys.Count() > 1)
                    {
                        apiKeys.RemoveAll(x => x.Key == key);
                        return(await RequestHashesAsync(request).ConfigureAwait(false));
                    }

                    throw new HasherException($"You are not authorized to use this service.  Please check that your API key {maskedKey} is correct.");

                // This error code is returned when you have exhausted your current "hashes per second" value
                // You should queue up your requests, and retry in a second.
                case (HttpStatusCode)429:
                    APIConfiguration.Logger.LogInfo($"Your request has been limited. {await response.Content.ReadAsStringAsync().ConfigureAwait(false)}");
                    if (apiKeys.Count() > 1)
                    {
                        return(await RequestHashesAsync(request).ConfigureAwait(false));
                    }

                    long ratePeriodEndsAtTimestamp;
                    IEnumerable <string> ratePeriodEndHeaderValues;
                    if (response.Headers.TryGetValues("X-RatePeriodEnd", out ratePeriodEndHeaderValues))
                    {
                        // Get the rate-limit period ends at timestamp in seconds.
                        ratePeriodEndsAtTimestamp = Convert.ToInt64(ratePeriodEndHeaderValues.First());
                    }
                    else
                    {
                        // If for some reason we couldn't get the timestamp, just default to 2 second wait.
                        ratePeriodEndsAtTimestamp = Utils.GetTime(false) + 2;
                    }

                    long timeToWaitInSeconds = ratePeriodEndsAtTimestamp - Utils.GetTime(false);

                    if (timeToWaitInSeconds > 0)
                    {
                        await Task.Delay((int)(timeToWaitInSeconds * 1000)).ConfigureAwait(false);      // Wait until next rate-limit period begins.
                    }
                    return(await RequestHashesAsync(request).ConfigureAwait(false));

                default:
                    throw new HasherException($"Hash API server ({client.BaseAddress}{apiEndPoint}) might down!");
                }
            }

            return(null);
        }
        public async Task <HashResponseContent> RequestHashesAsync(HashRequestContent request)
        {
            // This value will determine which version of hashing you receive.
            // Currently supported versions:
            // v119 -> Pogo iOS 1.19
            // v121 -> Pogo iOS 1.21
            const string endpoint = "api/v122/hash";

            // NOTE: This is really bad. Don't create new HttpClient's all the time.
            // Use a single client per-thread if you need one.
            using (var client = new System.Net.Http.HttpClient())
            {
                // The URL to the hashing server.
                // Do not include "api/v1/hash" unless you know why you're doing it, and want to modify this code.
                client.BaseAddress = new Uri("http://pokehash.buddyauth.com/");

                // By default, all requests (and this example) are in JSON.
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                // Set the X-AuthToken to the key you purchased from Bossland GmbH
                client.DefaultRequestHeaders.Add("X-AuthToken", this.apiKey);

                var content = new StringContent(JsonConvert.SerializeObject(request), Encoding.ASCII, "application/json");
                // An odd bug with HttpClient. You need to set the content type again.
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                var response = await client.PostAsync(endpoint, content);

                // TODO: Fix this up with proper retry-after when we get rate limited.
                switch (response.StatusCode)
                {
                // All good. Return the hashes back to the caller. :D
                case HttpStatusCode.OK:
                    return(JsonConvert.DeserializeObject <HashResponseContent>(await response.Content.ReadAsStringAsync()));

                // Returned when something in your request is "invalid". Also when X-AuthToken is not set.
                // See the error message for why it is bad.
                case HttpStatusCode.BadRequest:
                    Console.WriteLine($"Bad request sent to the hashing server! {await response.Content.ReadAsStringAsync()}");
                    break;

                // This error code is returned when your "key" is not in a valid state. (Expired, invalid, etc)
                case HttpStatusCode.Unauthorized:
                    Console.WriteLine("You are not authorized to use this service. please check you api key correct");
                    Console.ReadKey();
                    Environment.Exit(0);     //TODO need logic layer to handle this error , maybe validation when first start
                    break;

                // This error code is returned when you have exhausted your current "hashes per second" value
                // You should queue up your requests, and retry in a second.
                case (HttpStatusCode)429:
                    Console.WriteLine($"Your request has been limited. {await response.Content.ReadAsStringAsync()}");
                    await Task.Delay(2 * 1000);      //stop for 2 sec

                    return(await RequestHashesAsync(request));

                    break;
                }
            }

            return(null);
        }