Fixes, Improvements and new things ;-)

Spegeli [2016-07-22 03:28:06]
Fixes, Improvements and new things ;-)
Filename
PokemonGo.RocketAPI.Console/App.config
PokemonGo.RocketAPI.Console/Settings.cs
PokemonGo.RocketAPI.Logic/Inventory.cs
PokemonGo.RocketAPI.Logic/Logic.cs
PokemonGo.RocketAPI/Client.cs
PokemonGo.RocketAPI/Helpers/RandomHelper.cs
PokemonGo.RocketAPI/Login/GoogleLogin.cs
PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
diff --git a/PokemonGo.RocketAPI.Console/App.config b/PokemonGo.RocketAPI.Console/App.config
index 325154e..1b3985e 100644
--- a/PokemonGo.RocketAPI.Console/App.config
+++ b/PokemonGo.RocketAPI.Console/App.config
@@ -1,42 +1,39 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-    <configSections>
-        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
-            <section name="PokemonGo.RocketAPI.Console.UserSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
-            <section name="PokemonGo.RocketAPI.Console.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
-        </sectionGroup>
-    </configSections>
-    <startup>
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
-    </startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-  <userSettings>
-    <PokemonGo.RocketAPI.Console.UserSettings>
-        <setting name="GoogleRefreshToken" serializeAs="String">
-            <value />
-        </setting>
-        <setting name="AuthType" serializeAs="String">
-            <value>Ptc</value>
-        </setting>
-        <setting name="PtcUsername" serializeAs="String">
-            <value>username</value>
-        </setting>
-        <setting name="PtcPassword" serializeAs="String">
-            <value>pw</value>
-        </setting>
-        <setting name="DefaultLatitude" serializeAs="String">
-            <value>0</value>
-        </setting>
-        <setting name="DefaultLongitude" serializeAs="String">
-            <value>0</value>
-        </setting>
-    </PokemonGo.RocketAPI.Console.UserSettings>
-  </userSettings>
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+    <configSections>
+        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
+            <section name="PokemonGo.RocketAPI.Console.UserSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+            <section name="PokemonGo.RocketAPI.Console.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+        </sectionGroup>
+    </configSections>
+    <startup>
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+    </startup>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+  <userSettings>
+    <PokemonGo.RocketAPI.Console.UserSettings>
+        <setting name="AuthType" serializeAs="String">
+            <value>Google</value>
+        </setting>
+        <setting name="PtcUsername" serializeAs="String">
+            <value>username</value>
+        </setting>
+        <setting name="PtcPassword" serializeAs="String">
+            <value>password</value>
+        </setting>
+        <setting name="DefaultLatitude" serializeAs="String">
+            <value>0</value>
+        </setting>
+        <setting name="DefaultLongitude" serializeAs="String">
+            <value>0</value>
+        </setting>
+    </PokemonGo.RocketAPI.Console.UserSettings>
+  </userSettings>
 </configuration>
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Console/Settings.cs b/PokemonGo.RocketAPI.Console/Settings.cs
index ed27a27..236daa4 100644
--- a/PokemonGo.RocketAPI.Console/Settings.cs
+++ b/PokemonGo.RocketAPI.Console/Settings.cs
@@ -30,6 +30,7 @@ namespace PokemonGo.RocketAPI.Console
                     new KeyValuePair<ItemId, int>(ItemId.ItemHyperPotion, 5),
                     new KeyValuePair<ItemId, int>(ItemId.ItemMaxPotion, 5),
                     new KeyValuePair<ItemId, int>(ItemId.ItemRevive, 5),
+                    new KeyValuePair<ItemId, int>(ItemId.ItemMaxRevive, 5),
                     new KeyValuePair<ItemId, int>(ItemId.ItemRazzBerry, 5)
                 };
             }
diff --git a/PokemonGo.RocketAPI.Logic/Inventory.cs b/PokemonGo.RocketAPI.Logic/Inventory.cs
index f25cd63..9e3f67b 100644
--- a/PokemonGo.RocketAPI.Logic/Inventory.cs
+++ b/PokemonGo.RocketAPI.Logic/Inventory.cs
@@ -61,7 +61,10 @@ namespace PokemonGo.RocketAPI.Logic
                 {
                     var settings = pokemonSettings.Single(x => x.PokemonId == pokemon.Key);
                     var familyCandy = pokemonFamilies.Single(x => settings.FamilyId == x.FamilyId);
-                    var amountToSkip = (familyCandy.Candy + settings.CandyToEvolve - 1)/settings.CandyToEvolve;
+                    var amountToSkip = (familyCandy.Candy + settings.CandyToEvolve - 1)/settings.CandyToEvolve;
+
+                    if (settings.EvolutionIds.Count == 0)
+                        continue;

                     results.AddRange(pokemonList.Where(x => x.PokemonId == pokemon.Key && x.Favorite == 0)
                         .OrderByDescending(x => x.Cp)
diff --git a/PokemonGo.RocketAPI.Logic/Logic.cs b/PokemonGo.RocketAPI.Logic/Logic.cs
index 308fa2c..193bd60 100644
--- a/PokemonGo.RocketAPI.Logic/Logic.cs
+++ b/PokemonGo.RocketAPI.Logic/Logic.cs
@@ -8,6 +8,7 @@ using PokemonGo.RocketAPI.Enums;
 using PokemonGo.RocketAPI.Extensions;
 using PokemonGo.RocketAPI.GeneratedCode;
 using PokemonGo.RocketAPI.Logic.Utils;
+using PokemonGo.RocketAPI.Helpers;

 namespace PokemonGo.RocketAPI.Logic
 {
@@ -28,6 +29,14 @@ namespace PokemonGo.RocketAPI.Logic

         public async void Execute()
         {
+            if (_clientSettings.DefaultLatitude == 0 || _clientSettings.DefaultLongitude == 0)
+            {
+                Logger.Error($"Please change first Latitude and/or Longitude because currently your using default values!");
+                Logger.Error($"Window will be auto closed in 15 seconds!");
+                await Task.Delay(15000);
+                System.Environment.Exit(1);
+            }
+
             Logger.Normal(ConsoleColor.DarkGreen, $"Starting Execute on login server: {_clientSettings.AuthType}");

             if (_clientSettings.AuthType == AuthType.Ptc)
@@ -79,7 +88,6 @@ namespace PokemonGo.RocketAPI.Logic
             foreach (var pokeStop in pokeStops)
             {
                 await ExecuteCatchAllNearbyPokemons(client);
-                await TransferDuplicatePokemon(true);

                 var update = await client.UpdatePlayerLocation(pokeStop.Latitude, pokeStop.Longitude);
                 var fortInfo = await client.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
@@ -91,9 +99,11 @@ namespace PokemonGo.RocketAPI.Logic
                 Logger.Normal(ConsoleColor.Cyan, $"Using Pokestop: {fortInfo.Name}");
                 Logger.Normal(ConsoleColor.Cyan, $"Received XP: {fortSearch.ExperienceAwarded}, Gems: { fortSearch.GemsAwarded}, Eggs: {fortSearch.PokemonDataEgg} Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}");

-                await Task.Delay(8000);
+                await RandomHelper.RandomDelay(500, 1000);
+                await RecycleItems();
+
+                await RandomHelper.RandomDelay(7500,8500);
             }
-            await RecycleItems();
         }

         private async Task ExecuteCatchAllNearbyPokemons(Client client)
@@ -108,6 +118,7 @@ namespace PokemonGo.RocketAPI.Logic
                 var update = await client.UpdatePlayerLocation(pokemon.Latitude, pokemon.Longitude);
                 var encounterPokemonResponse = await client.EncounterPokemon(pokemon.EncounterId, pokemon.SpawnpointId);
                 var pokemonCP = encounterPokemonResponse?.WildPokemon?.PokemonData?.Cp;
+                var berry = await GetBestBerry(pokemonCP);
                 var pokeball = await GetBestBall(pokemonCP);
                 if (pokeball == MiscEnums.Item.ITEM_UNKNOWN)
                 {
@@ -119,21 +130,33 @@ namespace PokemonGo.RocketAPI.Logic
                 CatchPokemonResponse caughtPokemonResponse;
                 do
                 {
-                    if (encounterPokemonResponse?.CaptureProbability.CaptureProbability_.First() < 0.4)
-                        await UseBerry(pokemon.EncounterId, pokemon.SpawnpointId);
+                    if (berry != AllEnum.ItemId.ItemUnknown && encounterPokemonResponse?.CaptureProbability.CaptureProbability_.First() < 0.4)
+                    {
+                        var useRaspberry = await _client.UseCaptureItem(pokemon.EncounterId, pokemon.SpawnpointId, berry);
+                        Logger.Normal($"Use Rasperry {berry}");
+                        await RandomHelper.RandomDelay(500, 1000);
+                    }
+
                     caughtPokemonResponse = await client.CatchPokemon(pokemon.EncounterId, pokemon.SpawnpointId, pokemon.Latitude, pokemon.Longitude, pokeball);
                     balls_used++;
                 }
                 while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed);

-                foreach (int xp in caughtPokemonResponse.Scores.Xp)
-                    _stats.addExperience(xp);
                 if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
+                {
+                    foreach (int xp in caughtPokemonResponse.Scores.Xp)
+                        _stats.addExperience(xp);
                     _stats.increasePokemons();
+                }
+
                 _stats.updateConsoleTitle();

                 Logger.Normal(ConsoleColor.Yellow, caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess ? $"We caught a {pokemon.PokemonId} with CP {encounterPokemonResponse?.WildPokemon?.PokemonData?.Cp}, used {balls_used} x {pokeball} and received XP {caughtPokemonResponse.Scores.Xp.Sum()}" : $"{pokemon.PokemonId} with CP {encounterPokemonResponse?.WildPokemon?.PokemonData?.Cp} got away while using a {pokeball}..");
-                await Task.Delay(5000);
+
+                await RandomHelper.RandomDelay(500, 1000);
+                await TransferDuplicatePokemon(true);
+
+                await RandomHelper.RandomDelay(2500, 5000);
             }
         }

@@ -164,7 +187,7 @@ namespace PokemonGo.RocketAPI.Logic

         private async Task TransferDuplicatePokemon(bool keepPokemonsThatCanEvolve = false)
         {
-            var duplicatePokemons = await _inventory.GetDuplicatePokemonToTransfer();
+            var duplicatePokemons = await _inventory.GetDuplicatePokemonToTransfer(keepPokemonsThatCanEvolve);
             if (duplicatePokemons != null && duplicatePokemons.Any())
                 Logger.Normal(ConsoleColor.DarkYellow, $"Transfering duplicate Pokemon");

@@ -183,7 +206,7 @@ namespace PokemonGo.RocketAPI.Logic
             foreach (var item in items)
             {
                 var transfer = await _client.RecycleItem((AllEnum.ItemId)item.Item_, item.Count);
-                Logger.Normal($"Recycled {item.Count}x {(AllEnum.ItemId)item.Item_}");
+                Logger.Normal(ConsoleColor.DarkBlue, $"Recycled {item.Count}x {(AllEnum.ItemId)item.Item_}");

                 _stats.addItemsRemoved(item.Count);
                 _stats.updateConsoleTitle();
@@ -223,20 +246,46 @@ namespace PokemonGo.RocketAPI.Logic
             if (masterBallsCount > 0)
                 return MiscEnums.Item.ITEM_MASTER_BALL;

-            return MiscEnums.Item.ITEM_UNKNOWN; // returning null to notify handler
+            return MiscEnums.Item.ITEM_UNKNOWN;
         }

-        public async Task UseBerry(ulong encounterId, string spawnPointId)
+        private async Task<AllEnum.ItemId> GetBestBerry(int? pokemonCp)
         {
-            var inventoryBalls = await _inventory.GetItems();
-            var berry = inventoryBalls.Where(p => (ItemId)p.Item_ == ItemId.ItemRazzBerry).FirstOrDefault();
-
-            if (berry == null)
-                return;
-
-            var useRaspberry = await _client.UseCaptureItem(encounterId, AllEnum.ItemId.ItemRazzBerry, spawnPointId);
-            Logger.Normal($"Use Rasperry. Remaining: {berry.Count}");
-            await Task.Delay(3000);
+            var razzBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_RAZZ_BERRY);
+            var blukBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_BLUK_BERRY);
+            var nanabBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_NANAB_BERRY);
+            var weparBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_WEPAR_BERRY);
+            var pinapBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_PINAP_BERRY);
+
+            if (pinapBerryCount > 0 && pokemonCp >= 1000)
+                return AllEnum.ItemId.ItemPinapBerry;
+            else if (weparBerryCount > 0 && pokemonCp >= 1000)
+                return AllEnum.ItemId.ItemWeparBerry;
+            else if (nanabBerryCount > 0 && pokemonCp >= 1000)
+                return AllEnum.ItemId.ItemNanabBerry;
+
+            if (weparBerryCount > 0 && pokemonCp >= 600)
+                return AllEnum.ItemId.ItemWeparBerry;
+            else if (nanabBerryCount > 0 && pokemonCp >= 600)
+                return AllEnum.ItemId.ItemNanabBerry;
+            else if (blukBerryCount > 0 && pokemonCp >= 600)
+                return AllEnum.ItemId.ItemBlukBerry;
+
+            if (blukBerryCount > 0 && pokemonCp >= 350)
+                return AllEnum.ItemId.ItemBlukBerry;
+
+            if (razzBerryCount > 0)
+                return AllEnum.ItemId.ItemRazzBerry;
+            if (blukBerryCount > 0)
+                return AllEnum.ItemId.ItemBlukBerry;
+            if (nanabBerryCount > 0)
+                return AllEnum.ItemId.ItemNanabBerry;
+            if (weparBerryCount > 0)
+                return AllEnum.ItemId.ItemWeparBerry;
+            if (pinapBerryCount > 0)
+                return AllEnum.ItemId.ItemPinapBerry;
+
+            return AllEnum.ItemId.ItemUnknown;
         }
     }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/Client.cs b/PokemonGo.RocketAPI/Client.cs
index b5739fb..1199977 100644
--- a/PokemonGo.RocketAPI/Client.cs
+++ b/PokemonGo.RocketAPI/Client.cs
@@ -1,239 +1,247 @@
-using System;
-using System.Net;
-using System.Net.Http;
-using System.Threading.Tasks;
-using Google.Protobuf;
-using PokemonGo.RocketAPI.Enums;
-using PokemonGo.RocketAPI.GeneratedCode;
-using PokemonGo.RocketAPI.Helpers;
-using PokemonGo.RocketAPI.Extensions;
-using PokemonGo.RocketAPI.Login;
-using static PokemonGo.RocketAPI.GeneratedCode.Response.Types;
-
-namespace PokemonGo.RocketAPI
-{
-    public class Client
-    {
-        private readonly ISettings _settings;
-        private readonly HttpClient _httpClient;
-        private AuthType _authType = AuthType.Google;
-        private string _accessToken;
-        private string _apiUrl;
-        private Request.Types.UnknownAuth _unknownAuth;
-
-        private double _currentLat;
-        private double _currentLng;
-
-        public Client(ISettings settings)
-        {
-            _settings = settings;
-            SetCoordinates(_settings.DefaultLatitude, _settings.DefaultLongitude);
-
-            //Setup HttpClient and create default headers
-            HttpClientHandler handler = new HttpClientHandler()
-            {
-                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
-                AllowAutoRedirect = false
-            };
-            _httpClient = new HttpClient(new RetryHandler(handler));
-            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Niantic App");
-                //"Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G900F Build/LMY48G)");
-            _httpClient.DefaultRequestHeaders.ExpectContinue = false;
-            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Connection", "keep-alive");
-            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "*/*");
-            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type",
-                "application/x-www-form-urlencoded");
-        }
-
-        private void SetCoordinates(double lat, double lng)
-        {
-            _currentLat = lat;
-            _currentLng = lng;
-        }
-
-        public async Task DoGoogleLogin()
-        {
-            _authType = AuthType.Google;
-            if (_settings.GoogleRefreshToken != string.Empty)
-            {
-                var tokenResponse = await GoogleLogin.GetAccessToken(_settings.GoogleRefreshToken);
-                _accessToken = tokenResponse.id_token;
-            }
-
-            if (_accessToken == null)
-            {
-                var tokenResponse = await GoogleLogin.GetAccessToken();
-                _accessToken = tokenResponse.id_token;
-                _settings.GoogleRefreshToken = tokenResponse.access_token;
-            }
-        }
-
-        public async Task DoPtcLogin(string username, string password)
-        {
-            _accessToken = await PtcLogin.GetAccessToken(username, password);
-            _authType = AuthType.Ptc;
-        }
-
-        public async Task<PlayerUpdateResponse> UpdatePlayerLocation(double lat, double lng)
-        {
-            this.SetCoordinates(lat, lng);
-            var customRequest = new Request.Types.PlayerUpdateProto()
-            {
-                Lat = Utils.FloatAsUlong(_currentLat),
-                Lng = Utils.FloatAsUlong(_currentLng)
-            };
-
-            var updateRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 10,
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.PLAYER_UPDATE,
-                    Message = customRequest.ToByteString()
-                });
-            var updateResponse =
-                await
-                    _httpClient.PostProtoPayload<Request, PlayerUpdateResponse>($"https://{_apiUrl}/rpc", updateRequest);
-            return updateResponse;
-        }
-
-        public async Task SetServer()
-        {
-            var serverRequest = RequestBuilder.GetInitialRequest(_accessToken, _authType, _currentLat, _currentLng, 10,
-                RequestType.GET_PLAYER, RequestType.GET_HATCHED_OBJECTS, RequestType.GET_INVENTORY,
-                RequestType.CHECK_AWARDED_BADGES, RequestType.DOWNLOAD_SETTINGS);
-            var serverResponse = await _httpClient.PostProto<Request>(Resources.RpcUrl, serverRequest);
-            _unknownAuth = new Request.Types.UnknownAuth()
-            {
-                Unknown71 = serverResponse.Auth.Unknown71,
-                Timestamp = serverResponse.Auth.Timestamp,
-                Unknown73 = serverResponse.Auth.Unknown73,
-            };
-
-            _apiUrl = serverResponse.ApiUrl;
-        }
-
-        public async Task<GetPlayerResponse> GetProfile()
-        {
-            var profileRequest = RequestBuilder.GetInitialRequest(_accessToken, _authType, _currentLat, _currentLng, 10,
-                new Request.Types.Requests() { Type = (int)RequestType.GET_PLAYER });
-            return await _httpClient.PostProtoPayload<Request, GetPlayerResponse>($"https://{_apiUrl}/rpc", profileRequest);
-        }
-
-        public async Task<DownloadSettingsResponse> GetSettings()
-        {
-            var settingsRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 10,
-                RequestType.DOWNLOAD_SETTINGS);
-            return await _httpClient.PostProtoPayload<Request, DownloadSettingsResponse>($"https://{_apiUrl}/rpc", settingsRequest);
-        }
-
-        public async Task<DownloadItemTemplatesResponse> GetItemTemplates()
-        {
-            var settingsRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 10,
-                RequestType.DOWNLOAD_ITEM_TEMPLATES);
-            return
-                await
-                    _httpClient.PostProtoPayload<Request, DownloadItemTemplatesResponse>($"https://{_apiUrl}/rpc",
-                        settingsRequest);
-        }
-
-
-
-        public async Task<GetMapObjectsResponse> GetMapObjects()
-        {
-            var customRequest = new Request.Types.MapObjectsRequest()
-            {
-                CellIds =
-                    ByteString.CopyFrom(
-                        ProtoHelper.EncodeUlongList(S2Helper.GetNearbyCellIds(_currentLng,
-                            _currentLat))),
-                Latitude = Utils.FloatAsUlong(_currentLat),
-                Longitude = Utils.FloatAsUlong(_currentLng),
-                Unknown14 = ByteString.CopyFromUtf8("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
-            };
-
-            var mapRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 10,
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.GET_MAP_OBJECTS,
-                    Message = customRequest.ToByteString()
-                },
-                new Request.Types.Requests() { Type = (int)RequestType.GET_HATCHED_OBJECTS },
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.GET_INVENTORY,
-                    Message = new Request.Types.Time() { Time_ = DateTime.UtcNow.ToUnixTime() }.ToByteString()
-                },
-                new Request.Types.Requests() { Type = (int)RequestType.CHECK_AWARDED_BADGES },
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.DOWNLOAD_SETTINGS,
-                    Message =
-                        new Request.Types.SettingsGuid()
-                        {
-                            Guid = ByteString.CopyFromUtf8("4a2e9bc330dae60e7b74fc85b98868ab4700802e")
-                        }.ToByteString()
-                });
-
-            return await _httpClient.PostProtoPayload<Request, GetMapObjectsResponse>($"https://{_apiUrl}/rpc", mapRequest);
-        }
-
-        public async Task<FortDetailsResponse> GetFort(string fortId, double fortLat, double fortLng)
-        {
-            var customRequest = new Request.Types.FortDetailsRequest()
-            {
-                Id = ByteString.CopyFromUtf8(fortId),
-                Latitude = Utils.FloatAsUlong(fortLat),
-                Longitude = Utils.FloatAsUlong(fortLng),
-            };
-
-            var fortDetailRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 10,
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.FORT_DETAILS,
-                    Message = customRequest.ToByteString()
-                });
-            return await _httpClient.PostProtoPayload<Request, FortDetailsResponse>($"https://{_apiUrl}/rpc", fortDetailRequest);
-        }
-
-        public async Task<FortSearchResponse> SearchFort(string fortId, double fortLat, double fortLng)
-        {
-            var customRequest = new Request.Types.FortSearchRequest()
-            {
-                Id = ByteString.CopyFromUtf8(fortId),
-                FortLatDegrees = Utils.FloatAsUlong(fortLat),
-                FortLngDegrees = Utils.FloatAsUlong(fortLng),
-                PlayerLatDegrees = Utils.FloatAsUlong(_currentLat),
-                PlayerLngDegrees = Utils.FloatAsUlong(_currentLng)
-            };
-
-            var fortDetailRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.FORT_SEARCH,
-                    Message = customRequest.ToByteString()
-                });
-            return await _httpClient.PostProtoPayload<Request, FortSearchResponse>($"https://{_apiUrl}/rpc", fortDetailRequest);
-        }
-
-        public async Task<EncounterResponse> EncounterPokemon(ulong encounterId, string spawnPointGuid)
-        {
-            var customRequest = new Request.Types.EncounterRequest()
-            {
-                EncounterId = encounterId,
-                SpawnpointId = spawnPointGuid,
-                PlayerLatDegrees = Utils.FloatAsUlong(_currentLat),
-                PlayerLngDegrees = Utils.FloatAsUlong(_currentLng)
-            };
-
-            var encounterResponse = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.ENCOUNTER,
-                    Message = customRequest.ToByteString()
-                });
-            return await _httpClient.PostProtoPayload<Request, EncounterResponse>($"https://{_apiUrl}/rpc", encounterResponse);
+using System;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using PokemonGo.RocketAPI.Enums;
+using PokemonGo.RocketAPI.GeneratedCode;
+using PokemonGo.RocketAPI.Helpers;
+using PokemonGo.RocketAPI.Extensions;
+using PokemonGo.RocketAPI.Login;
+using static PokemonGo.RocketAPI.GeneratedCode.Response.Types;
+using System.Threading;
+using System.Windows.Forms;
+
+namespace PokemonGo.RocketAPI
+{
+    public class Client
+    {
+        private readonly ISettings _settings;
+        private readonly HttpClient _httpClient;
+        private AuthType _authType = AuthType.Google;
+        private string _accessToken;
+        private string _apiUrl;
+        private Request.Types.UnknownAuth _unknownAuth;
+
+        private double _currentLat;
+        private double _currentLng;
+
+        public Client(ISettings settings)
+        {
+            _settings = settings;
+            SetCoordinates(_settings.DefaultLatitude, _settings.DefaultLongitude);
+
+            //Setup HttpClient and create default headers
+            HttpClientHandler handler = new HttpClientHandler()
+            {
+                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
+                AllowAutoRedirect = false
+            };
+            _httpClient = new HttpClient(new RetryHandler(handler));
+            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Niantic App");
+                //"Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G900F Build/LMY48G)");
+            _httpClient.DefaultRequestHeaders.ExpectContinue = false;
+            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Connection", "keep-alive");
+            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "*/*");
+            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type",
+                "application/x-www-form-urlencoded");
+        }
+
+        private void SetCoordinates(double lat, double lng)
+        {
+            _currentLat = lat;
+            _currentLng = lng;
+        }
+
+        public async Task DoGoogleLogin()
+        {
+            _authType = AuthType.Google;
+            if (_settings.GoogleRefreshToken != string.Empty)
+            {
+                var tokenResponse = await GoogleLogin.GetAccessToken(_settings.GoogleRefreshToken);
+                _accessToken = tokenResponse.id_token;
+            }
+
+            if (_accessToken == null)
+            {
+                var tokenResponse = await GoogleLogin.GetAccessToken();
+                _accessToken = tokenResponse.id_token;
+                _settings.GoogleRefreshToken = tokenResponse.access_token;
+                Logger.Normal($"Put RefreshToken in settings for direct login: {tokenResponse.access_token}");
+                Thread thread = new Thread(() => Clipboard.SetText(tokenResponse.access_token));
+                thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
+                thread.Start();
+                thread.Join();
+                Logger.Normal("The RefreshToken is in your Clipboard!");
+            }
+        }
+
+        public async Task DoPtcLogin(string username, string password)
+        {
+            _accessToken = await PtcLogin.GetAccessToken(username, password);
+            _authType = AuthType.Ptc;
         }

-        public async Task<UseItemCaptureRequest> UseCaptureItem(ulong encounterId, AllEnum.ItemId itemId, string spawnPointGuid)
+        public async Task<PlayerUpdateResponse> UpdatePlayerLocation(double lat, double lng)
+        {
+            this.SetCoordinates(lat, lng);
+            var customRequest = new Request.Types.PlayerUpdateProto()
+            {
+                Lat = Utils.FloatAsUlong(_currentLat),
+                Lng = Utils.FloatAsUlong(_currentLng)
+            };
+
+            var updateRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 10,
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.PLAYER_UPDATE,
+                    Message = customRequest.ToByteString()
+                });
+            var updateResponse =
+                await
+                    _httpClient.PostProtoPayload<Request, PlayerUpdateResponse>($"https://{_apiUrl}/rpc", updateRequest);
+            return updateResponse;
+        }
+
+        public async Task SetServer()
+        {
+            var serverRequest = RequestBuilder.GetInitialRequest(_accessToken, _authType, _currentLat, _currentLng, 10,
+                RequestType.GET_PLAYER, RequestType.GET_HATCHED_OBJECTS, RequestType.GET_INVENTORY,
+                RequestType.CHECK_AWARDED_BADGES, RequestType.DOWNLOAD_SETTINGS);
+            var serverResponse = await _httpClient.PostProto<Request>(Resources.RpcUrl, serverRequest);
+            _unknownAuth = new Request.Types.UnknownAuth()
+            {
+                Unknown71 = serverResponse.Auth.Unknown71,
+                Timestamp = serverResponse.Auth.Timestamp,
+                Unknown73 = serverResponse.Auth.Unknown73,
+            };
+
+            _apiUrl = serverResponse.ApiUrl;
+        }
+
+        public async Task<GetPlayerResponse> GetProfile()
+        {
+            var profileRequest = RequestBuilder.GetInitialRequest(_accessToken, _authType, _currentLat, _currentLng, 10,
+                new Request.Types.Requests() { Type = (int)RequestType.GET_PLAYER });
+            return await _httpClient.PostProtoPayload<Request, GetPlayerResponse>($"https://{_apiUrl}/rpc", profileRequest);
+        }
+
+        public async Task<DownloadSettingsResponse> GetSettings()
+        {
+            var settingsRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 10,
+                RequestType.DOWNLOAD_SETTINGS);
+            return await _httpClient.PostProtoPayload<Request, DownloadSettingsResponse>($"https://{_apiUrl}/rpc", settingsRequest);
+        }
+
+        public async Task<DownloadItemTemplatesResponse> GetItemTemplates()
+        {
+            var settingsRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 10,
+                RequestType.DOWNLOAD_ITEM_TEMPLATES);
+            return
+                await
+                    _httpClient.PostProtoPayload<Request, DownloadItemTemplatesResponse>($"https://{_apiUrl}/rpc",
+                        settingsRequest);
+        }
+
+
+
+        public async Task<GetMapObjectsResponse> GetMapObjects()
+        {
+            var customRequest = new Request.Types.MapObjectsRequest()
+            {
+                CellIds =
+                    ByteString.CopyFrom(
+                        ProtoHelper.EncodeUlongList(S2Helper.GetNearbyCellIds(_currentLng,
+                            _currentLat))),
+                Latitude = Utils.FloatAsUlong(_currentLat),
+                Longitude = Utils.FloatAsUlong(_currentLng),
+                Unknown14 = ByteString.CopyFromUtf8("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
+            };
+
+            var mapRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 10,
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.GET_MAP_OBJECTS,
+                    Message = customRequest.ToByteString()
+                },
+                new Request.Types.Requests() { Type = (int)RequestType.GET_HATCHED_OBJECTS },
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.GET_INVENTORY,
+                    Message = new Request.Types.Time() { Time_ = DateTime.UtcNow.ToUnixTime() }.ToByteString()
+                },
+                new Request.Types.Requests() { Type = (int)RequestType.CHECK_AWARDED_BADGES },
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.DOWNLOAD_SETTINGS,
+                    Message =
+                        new Request.Types.SettingsGuid()
+                        {
+                            Guid = ByteString.CopyFromUtf8("4a2e9bc330dae60e7b74fc85b98868ab4700802e")
+                        }.ToByteString()
+                });
+
+            return await _httpClient.PostProtoPayload<Request, GetMapObjectsResponse>($"https://{_apiUrl}/rpc", mapRequest);
+        }
+
+        public async Task<FortDetailsResponse> GetFort(string fortId, double fortLat, double fortLng)
+        {
+            var customRequest = new Request.Types.FortDetailsRequest()
+            {
+                Id = ByteString.CopyFromUtf8(fortId),
+                Latitude = Utils.FloatAsUlong(fortLat),
+                Longitude = Utils.FloatAsUlong(fortLng),
+            };
+
+            var fortDetailRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 10,
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.FORT_DETAILS,
+                    Message = customRequest.ToByteString()
+                });
+            return await _httpClient.PostProtoPayload<Request, FortDetailsResponse>($"https://{_apiUrl}/rpc", fortDetailRequest);
+        }
+
+        public async Task<FortSearchResponse> SearchFort(string fortId, double fortLat, double fortLng)
+        {
+            var customRequest = new Request.Types.FortSearchRequest()
+            {
+                Id = ByteString.CopyFromUtf8(fortId),
+                FortLatDegrees = Utils.FloatAsUlong(fortLat),
+                FortLngDegrees = Utils.FloatAsUlong(fortLng),
+                PlayerLatDegrees = Utils.FloatAsUlong(_currentLat),
+                PlayerLngDegrees = Utils.FloatAsUlong(_currentLng)
+            };
+
+            var fortDetailRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.FORT_SEARCH,
+                    Message = customRequest.ToByteString()
+                });
+            return await _httpClient.PostProtoPayload<Request, FortSearchResponse>($"https://{_apiUrl}/rpc", fortDetailRequest);
+        }
+
+        public async Task<EncounterResponse> EncounterPokemon(ulong encounterId, string spawnPointGuid)
+        {
+            var customRequest = new Request.Types.EncounterRequest()
+            {
+                EncounterId = encounterId,
+                SpawnpointId = spawnPointGuid,
+                PlayerLatDegrees = Utils.FloatAsUlong(_currentLat),
+                PlayerLngDegrees = Utils.FloatAsUlong(_currentLng)
+            };
+
+            var encounterResponse = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.ENCOUNTER,
+                    Message = customRequest.ToByteString()
+                });
+            return await _httpClient.PostProtoPayload<Request, EncounterResponse>($"https://{_apiUrl}/rpc", encounterResponse);
+        }
+
+        public async Task<UseItemCaptureRequest> UseCaptureItem(ulong encounterId, string spawnPointGuid, AllEnum.ItemId itemId)
         {
             var customRequest = new UseItemCaptureRequest
             {
@@ -249,89 +257,89 @@ namespace PokemonGo.RocketAPI
                     Message = customRequest.ToByteString()
                 });
             return await _httpClient.PostProtoPayload<Request, UseItemCaptureRequest>($"https://{_apiUrl}/rpc", useItemRequest);
-        }
-
-        public async Task<CatchPokemonResponse> CatchPokemon(ulong encounterId, string spawnPointGuid, double pokemonLat,
-            double pokemonLng, MiscEnums.Item pokeball)
-        {
-
-            var customRequest = new Request.Types.CatchPokemonRequest()
-            {
-                EncounterId = encounterId,
-                Pokeball = (int)pokeball,
-                SpawnPointGuid = spawnPointGuid,
-                HitPokemon = 1,
-                NormalizedReticleSize = Utils.FloatAsUlong(1.950),
-                SpinModifier = Utils.FloatAsUlong(1),
-                NormalizedHitPosition = Utils.FloatAsUlong(1)
-            };
-
-            var catchPokemonRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.CATCH_POKEMON,
-                    Message = customRequest.ToByteString()
-                });
-            return
-                await
-                    _httpClient.PostProtoPayload<Request, CatchPokemonResponse>($"https://{_apiUrl}/rpc", catchPokemonRequest);
-        }
-
-        public async Task<TransferPokemonOut> TransferPokemon(ulong pokemonId)
-        {
-            var customRequest = new TransferPokemon
-            {
-                PokemonId = pokemonId
-            };
-
-            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.RELEASE_POKEMON,
-                    Message = customRequest.ToByteString()
-                });
-            return await _httpClient.PostProtoPayload<Request, TransferPokemonOut>($"https://{_apiUrl}/rpc", releasePokemonRequest);
-        }
-
-        public async Task<EvolvePokemonOut> EvolvePokemon(ulong pokemonId)
-        {
-            var customRequest = new EvolvePokemon
-            {
-                PokemonId = pokemonId
-            };
-
-            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.EVOLVE_POKEMON,
-                    Message = customRequest.ToByteString()
-                });
-            return
-                await
-                    _httpClient.PostProtoPayload<Request, EvolvePokemonOut>($"https://{_apiUrl}/rpc", releasePokemonRequest);
-        }
-
-        public async Task<GetInventoryResponse> GetInventory()
-        {
-            var inventoryRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30, RequestType.GET_INVENTORY);
-            return await _httpClient.PostProtoPayload<Request, GetInventoryResponse>($"https://{_apiUrl}/rpc", inventoryRequest);
-        }
-
-        public async Task<RecycleInventoryItemResponse> RecycleItem(AllEnum.ItemId itemId, int amount)
-        {
-            var customRequest = new RecycleInventoryItem
-            {
-                ItemId = (AllEnum.ItemId)Enum.Parse(typeof(AllEnum.ItemId), itemId.ToString()),
-                Count = amount
-            };
-
-            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.RECYCLE_INVENTORY_ITEM,
-                    Message = customRequest.ToByteString()
-                });
-            return await _httpClient.PostProtoPayload<Request, RecycleInventoryItemResponse>($"https://{_apiUrl}/rpc", releasePokemonRequest);
-        }
-    }
-}
+        }
+
+        public async Task<CatchPokemonResponse> CatchPokemon(ulong encounterId, string spawnPointGuid, double pokemonLat,
+            double pokemonLng, MiscEnums.Item pokeball)
+        {
+
+            var customRequest = new Request.Types.CatchPokemonRequest()
+            {
+                EncounterId = encounterId,
+                Pokeball = (int)pokeball,
+                SpawnPointGuid = spawnPointGuid,
+                HitPokemon = 1,
+                NormalizedReticleSize = Utils.FloatAsUlong(1.950),
+                SpinModifier = Utils.FloatAsUlong(1),
+                NormalizedHitPosition = Utils.FloatAsUlong(1)
+            };
+
+            var catchPokemonRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.CATCH_POKEMON,
+                    Message = customRequest.ToByteString()
+                });
+            return
+                await
+                    _httpClient.PostProtoPayload<Request, CatchPokemonResponse>($"https://{_apiUrl}/rpc", catchPokemonRequest);
+        }
+
+        public async Task<TransferPokemonOut> TransferPokemon(ulong pokemonId)
+        {
+            var customRequest = new TransferPokemon
+            {
+                PokemonId = pokemonId
+            };
+
+            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.RELEASE_POKEMON,
+                    Message = customRequest.ToByteString()
+                });
+            return await _httpClient.PostProtoPayload<Request, TransferPokemonOut>($"https://{_apiUrl}/rpc", releasePokemonRequest);
+        }
+
+        public async Task<EvolvePokemonOut> EvolvePokemon(ulong pokemonId)
+        {
+            var customRequest = new EvolvePokemon
+            {
+                PokemonId = pokemonId
+            };
+
+            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.EVOLVE_POKEMON,
+                    Message = customRequest.ToByteString()
+                });
+            return
+                await
+                    _httpClient.PostProtoPayload<Request, EvolvePokemonOut>($"https://{_apiUrl}/rpc", releasePokemonRequest);
+        }
+
+        public async Task<GetInventoryResponse> GetInventory()
+        {
+            var inventoryRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30, RequestType.GET_INVENTORY);
+            return await _httpClient.PostProtoPayload<Request, GetInventoryResponse>($"https://{_apiUrl}/rpc", inventoryRequest);
+        }
+
+        public async Task<RecycleInventoryItemResponse> RecycleItem(AllEnum.ItemId itemId, int amount)
+        {
+            var customRequest = new RecycleInventoryItem
+            {
+                ItemId = (AllEnum.ItemId)Enum.Parse(typeof(AllEnum.ItemId), itemId.ToString()),
+                Count = amount
+            };
+
+            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, _currentLat, _currentLng, 30,
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.RECYCLE_INVENTORY_ITEM,
+                    Message = customRequest.ToByteString()
+                });
+            return await _httpClient.PostProtoPayload<Request, RecycleInventoryItemResponse>($"https://{_apiUrl}/rpc", releasePokemonRequest);
+        }
+    }
+}
diff --git a/PokemonGo.RocketAPI/Helpers/RandomHelper.cs b/PokemonGo.RocketAPI/Helpers/RandomHelper.cs
index c338839..6014794 100644
--- a/PokemonGo.RocketAPI/Helpers/RandomHelper.cs
+++ b/PokemonGo.RocketAPI/Helpers/RandomHelper.cs
@@ -1,22 +1,39 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PokemonGo.RocketAPI.Helpers
-{
-    public class RandomHelper
-    {
-        private static Random _random = new Random();
-
-        public static long GetLongRandom(long min, long max)
-        {
-            byte[] buf = new byte[8];
-            _random.NextBytes(buf);
-            var longRand = BitConverter.ToInt64(buf, 0);
-
-            return (Math.Abs(longRand % (max - min)) + min);
-        }
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PokemonGo.RocketAPI.Helpers
+{
+    public static class RandomHelper
+    {
+        private static readonly Random _random = new Random();
+        private static readonly Random _rng = new Random();
+
+        public static long GetLongRandom(long min, long max)
+        {
+            byte[] buf = new byte[8];
+            _random.NextBytes(buf);
+            var longRand = BitConverter.ToInt64(buf, 0);
+
+            return (Math.Abs(longRand % (max - min)) + min);
+        }
+
+        public static async Task RandomDelay(int maxDelay = 5000)
+        {
+            await Task.Delay(_rng.Next((maxDelay > 500) ? 500 : 0, maxDelay));
+        }
+
+        public static async Task RandomDelay(int min, int max)
+        {
+            await Task.Delay(_rng.Next(min, max));
+        }
+
+        public static int RandomNumber(int min, int max)
+        {
+            Random random = new Random();
+            return random.Next(min, max);
+        }
+    }
+}
diff --git a/PokemonGo.RocketAPI/Login/GoogleLogin.cs b/PokemonGo.RocketAPI/Login/GoogleLogin.cs
index 3cd9a95..85925c7 100644
--- a/PokemonGo.RocketAPI/Login/GoogleLogin.cs
+++ b/PokemonGo.RocketAPI/Login/GoogleLogin.cs
@@ -1,101 +1,101 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Newtonsoft.Json.Linq;
-using PokemonGo.RocketAPI.Enums;
-using PokemonGo.RocketAPI.Helpers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Newtonsoft.Json.Linq;
+using PokemonGo.RocketAPI.Enums;
+using PokemonGo.RocketAPI.Helpers;
 using System.Windows.Forms;
 using System.Diagnostics;

-namespace PokemonGo.RocketAPI.Login
-{
-    internal static class GoogleLogin
-    {
-        private const string OauthTokenEndpoint = "https://www.googleapis.com/oauth2/v4/token";
-        private const string OauthEndpoint = "https://accounts.google.com/o/oauth2/device/code";
-        private const string ClientId = "848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com";
-        private const string ClientSecret = "NCjF1TLi2CcY6t5mt0ZveuL7";
-
-        internal static async Task<TokenResponseModel> GetAccessToken()
-        {
-            var deviceCodeResponse = await GetDeviceCode();
+namespace PokemonGo.RocketAPI.Login
+{
+    internal static class GoogleLogin
+    {
+        private const string OauthTokenEndpoint = "https://www.googleapis.com/oauth2/v4/token";
+        private const string OauthEndpoint = "https://accounts.google.com/o/oauth2/device/code";
+        private const string ClientId = "848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com";
+        private const string ClientSecret = "NCjF1TLi2CcY6t5mt0ZveuL7";
+
+        internal static async Task<TokenResponseModel> GetAccessToken()
+        {
+            var deviceCodeResponse = await GetDeviceCode();
             Logger.Normal("Please visit " + deviceCodeResponse.verification_url + " and enter " + deviceCodeResponse.user_code);
             Thread thread = new Thread(() => Clipboard.SetText(deviceCodeResponse.user_code));
             thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
             thread.Start();
             thread.Join();
             Logger.Normal("The Token is in your Clipboard!");
-            Process.Start("https://google.com/device");
-
-            //Poll until user submitted code..
-            TokenResponseModel tokenResponse;
-            do
-            {
-                await Task.Delay(2000);
-                tokenResponse = await PollSubmittedToken(deviceCodeResponse.device_code);
-            } while (tokenResponse.access_token == null || tokenResponse.refresh_token == null);
-
-            return tokenResponse;
-        }
-
-        private static async Task<DeviceCodeModel> GetDeviceCode()
-        {
-            return await HttpClientHelper.PostFormEncodedAsync<DeviceCodeModel>(OauthEndpoint,
-                new KeyValuePair<string, string>("client_id", ClientId),
-                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
-        }
-
-        private static async Task<TokenResponseModel> PollSubmittedToken(string deviceCode)
-        {
-            return await HttpClientHelper.PostFormEncodedAsync<TokenResponseModel>(OauthTokenEndpoint,
-                new KeyValuePair<string, string>("client_id", ClientId),
-                new KeyValuePair<string, string>("client_secret", ClientSecret),
-                new KeyValuePair<string, string>("code", deviceCode),
-                new KeyValuePair<string, string>("grant_type", "http://oauth.net/grant_type/device/1.0"),
-                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
-        }
-
-        public static async Task<TokenResponseModel> GetAccessToken(string refreshToken)
-        {
-            return await HttpClientHelper.PostFormEncodedAsync<TokenResponseModel>(OauthTokenEndpoint,
-                new KeyValuePair<string, string>("access_type", "offline"),
-                new KeyValuePair<string, string>("client_id", ClientId),
-                new KeyValuePair<string, string>("client_secret", ClientSecret),
-                new KeyValuePair<string, string>("refresh_token", refreshToken),
-                new KeyValuePair<string, string>("grant_type", "refresh_token"),
-                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
-        }
-
-
-        internal class ErrorResponseModel
-        {
-            public string error { get; set; }
-            public string error_description { get; set; }
-        }
-
-        internal class TokenResponseModel
-        {
-            public string access_token { get; set; }
-            public string token_type { get; set; }
-            public int expires_in { get; set; }
-            public string refresh_token { get; set; }
-            public string id_token { get; set; }
-        }
-
-
-        public class DeviceCodeModel
-        {
-            public string verification_url { get; set; }
-            public int expires_in { get; set; }
-            public int interval { get; set; }
-            public string device_code { get; set; }
-            public string user_code { get; set; }
-        }
-
-    }
-}
+            Process.Start("https://google.com/device");
+
+            //Poll until user submitted code..
+            TokenResponseModel tokenResponse;
+            do
+            {
+                await Task.Delay(2000);
+                tokenResponse = await PollSubmittedToken(deviceCodeResponse.device_code);
+            } while (tokenResponse.access_token == null || tokenResponse.refresh_token == null);
+
+            return tokenResponse;
+        }
+
+        private static async Task<DeviceCodeModel> GetDeviceCode()
+        {
+            return await HttpClientHelper.PostFormEncodedAsync<DeviceCodeModel>(OauthEndpoint,
+                new KeyValuePair<string, string>("client_id", ClientId),
+                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
+        }
+
+        private static async Task<TokenResponseModel> PollSubmittedToken(string deviceCode)
+        {
+            return await HttpClientHelper.PostFormEncodedAsync<TokenResponseModel>(OauthTokenEndpoint,
+                new KeyValuePair<string, string>("client_id", ClientId),
+                new KeyValuePair<string, string>("client_secret", ClientSecret),
+                new KeyValuePair<string, string>("code", deviceCode),
+                new KeyValuePair<string, string>("grant_type", "http://oauth.net/grant_type/device/1.0"),
+                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
+        }
+
+        public static async Task<TokenResponseModel> GetAccessToken(string refreshToken)
+        {
+            return await HttpClientHelper.PostFormEncodedAsync<TokenResponseModel>(OauthTokenEndpoint,
+                new KeyValuePair<string, string>("access_type", "offline"),
+                new KeyValuePair<string, string>("client_id", ClientId),
+                new KeyValuePair<string, string>("client_secret", ClientSecret),
+                new KeyValuePair<string, string>("refresh_token", refreshToken),
+                new KeyValuePair<string, string>("grant_type", "refresh_token"),
+                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
+        }
+
+
+        internal class ErrorResponseModel
+        {
+            public string error { get; set; }
+            public string error_description { get; set; }
+        }
+
+        internal class TokenResponseModel
+        {
+            public string access_token { get; set; }
+            public string token_type { get; set; }
+            public int expires_in { get; set; }
+            public string refresh_token { get; set; }
+            public string id_token { get; set; }
+        }
+
+
+        public class DeviceCodeModel
+        {
+            public string verification_url { get; set; }
+            public int expires_in { get; set; }
+            public int interval { get; set; }
+            public string device_code { get; set; }
+            public string user_code { get; set; }
+        }
+
+    }
+}
diff --git a/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj b/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
index 693bcbc..f9dde93 100644
--- a/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
+++ b/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
@@ -1,124 +1,126 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{05D2DA44-1B8E-4CF7-94ED-4D52451CD095}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>PokemonGo.RocketAPI</RootNamespace>
-    <AssemblyName>Pokemon Go Rocket API</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="C5, Version=2.2.5073.27396, Culture=neutral, PublicKeyToken=282361b99ded7e8e, processorArchitecture=MSIL">
-      <HintPath>..\packages\C5.2.2.5073.27396\lib\portable-net40+sl50+wp80+win\C5.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\dotnet\Google.Protobuf.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <HintPath>..\packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <HintPath>..\packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="S2Geometry, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\S2Geometry.1.0.1\lib\portable-net45+wp8+win8\S2Geometry.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Configuration" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.VarintBitConverter, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\VarintBitConverter.1.0.0.0\lib\Net40\System.VarintBitConverter.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Web" />
-    <Reference Include="System.Windows.Forms" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Enums\AuthType.cs" />
-    <Compile Include="Enums\MiscEnums.cs" />
-    <Compile Include="Enums\RequestType.cs" />
-    <Compile Include="Exceptions\InvalidResponseException.cs" />
-    <Compile Include="Exceptions\PtcOfflineException.cs" />
-    <Compile Include="Extensions\DateTimeExtensions.cs" />
-    <Compile Include="GeneratedCode\AllEnum.cs" />
-    <Compile Include="GeneratedCode\Payloads.cs" />
-    <Compile Include="GeneratedCode\Request.cs" />
-    <Compile Include="GeneratedCode\Response.cs" />
-    <Compile Include="Helpers\HttpClientHelper.cs" />
-    <Compile Include="Helpers\JsonHelper.cs" />
-    <Compile Include="Helpers\ProtoHelper.cs" />
-    <Compile Include="Helpers\RetryHandler.cs" />
-    <Compile Include="Helpers\S2Helper.cs" />
-    <Compile Include="Helpers\Utils.cs" />
-    <Compile Include="ISettings.cs" />
-    <Compile Include="Logging\ConsoleLogger.cs" />
-    <Compile Include="Logging\ILogger.cs" />
-    <Compile Include="Logger.cs" />
-    <Compile Include="Login\GoogleLogin.cs" />
-    <Compile Include="Login\PtcLogin.cs" />
-    <None Include="app.config" />
-    <Compile Include="Client.cs" />
-    <Compile Include="Extensions\HttpClientExtensions.cs" />
-    <Compile Include="Helpers\RandomHelper.cs" />
-    <Compile Include="Helpers\RequestBuilder.cs" />
-    <Compile Include="Resources.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-    <None Include="Proto\AllEnum.proto" />
-    <None Include="Proto\Payloads.proto" />
-    <None Include="Proto\Response.proto" />
-    <None Include="Proto\Request.proto" />
-  </ItemGroup>
-  <ItemGroup />
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{05D2DA44-1B8E-4CF7-94ED-4D52451CD095}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>PokemonGo.RocketAPI</RootNamespace>
+    <AssemblyName>Pokemon Go Rocket API</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="C5, Version=2.2.5073.27396, Culture=neutral, PublicKeyToken=282361b99ded7e8e, processorArchitecture=MSIL">
+      <HintPath>..\packages\C5.2.2.5073.27396\lib\portable-net40+sl50+wp80+win\C5.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\dotnet\Google.Protobuf.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="S2Geometry, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\S2Geometry.1.0.1\lib\portable-net45+wp8+win8\S2Geometry.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.VarintBitConverter, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\VarintBitConverter.1.0.0.0\lib\Net40\System.VarintBitConverter.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Web" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Enums\AuthType.cs" />
+    <Compile Include="Enums\MiscEnums.cs" />
+    <Compile Include="Enums\RequestType.cs" />
+    <Compile Include="Exceptions\InvalidResponseException.cs" />
+    <Compile Include="Exceptions\PtcOfflineException.cs" />
+    <Compile Include="Extensions\DateTimeExtensions.cs" />
+    <Compile Include="GeneratedCode\AllEnum.cs" />
+    <Compile Include="GeneratedCode\Payloads.cs" />
+    <Compile Include="GeneratedCode\Request.cs" />
+    <Compile Include="GeneratedCode\Response.cs" />
+    <Compile Include="Helpers\HttpClientHelper.cs" />
+    <Compile Include="Helpers\JsonHelper.cs" />
+    <Compile Include="Helpers\ProtoHelper.cs" />
+    <Compile Include="Helpers\RetryHandler.cs" />
+    <Compile Include="Helpers\S2Helper.cs" />
+    <Compile Include="Helpers\Utils.cs" />
+    <Compile Include="ISettings.cs" />
+    <Compile Include="Logging\ConsoleLogger.cs" />
+    <Compile Include="Logging\ILogger.cs" />
+    <Compile Include="Logging\Logger.cs" />
+    <Compile Include="Login\GoogleLogin.cs" />
+    <Compile Include="Login\PtcLogin.cs" />
+    <None Include="app.config">
+      <SubType>Designer</SubType>
+    </None>
+    <Compile Include="Client.cs" />
+    <Compile Include="Extensions\HttpClientExtensions.cs" />
+    <Compile Include="Helpers\RandomHelper.cs" />
+    <Compile Include="Helpers\RequestBuilder.cs" />
+    <Compile Include="Resources.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+    <None Include="Proto\AllEnum.proto" />
+    <None Include="Proto\Payloads.proto" />
+    <None Include="Proto\Response.proto" />
+    <None Include="Proto\Request.proto" />
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
   </Target>
   <Target Name="AfterBuild">
   </Target>
-  -->
+  -->
 </Project>
\ No newline at end of file
You may download the files in Public Git.