Update to the latest NecronomiconCoding changes ;-)

Spegeli [2016-07-23 11:43:14]
Update to the latest NecronomiconCoding changes ;-)
Filename
PokemonGo.RocketAPI.Console/Settings.cs
PokemonGo.RocketAPI.Logic/Inventory.cs
PokemonGo.RocketAPI.Logic/Logic.cs
PokemonGo.RocketAPI.Logic/Navigation.cs
PokemonGo.RocketAPI.Logic/Utils/Statistics.cs
PokemonGo.RocketAPI/Client.cs
PokemonGo.RocketAPI/Helpers/RetryHandler.cs
PokemonGo.RocketAPI/Helpers/S2Helper.cs
PokemonGo.RocketAPI/ISettings.cs
PokemonGo.RocketAPI/Logging/Logger.cs
PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
diff --git a/PokemonGo.RocketAPI.Console/Settings.cs b/PokemonGo.RocketAPI.Console/Settings.cs
index 32c76a1..09ec3c7 100644
--- a/PokemonGo.RocketAPI.Console/Settings.cs
+++ b/PokemonGo.RocketAPI.Console/Settings.cs
@@ -42,55 +42,74 @@ namespace PokemonGo.RocketAPI.Console
             }
         }

-        ICollection<KeyValuePair<ItemId, int>> ISettings.ItemRecycleFilter
+        public ICollection<KeyValuePair<ItemId, int>> ItemRecycleFilter => new[]
+        {
+            new KeyValuePair<ItemId, int>(ItemId.ItemUnknown, 0),
+            new KeyValuePair<ItemId, int>(ItemId.ItemPokeBall, 20),
+            new KeyValuePair<ItemId, int>(ItemId.ItemGreatBall, 20),
+            new KeyValuePair<ItemId, int>(ItemId.ItemUltraBall, 50),
+            new KeyValuePair<ItemId, int>(ItemId.ItemMasterBall, 100),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemPotion, 0),
+            new KeyValuePair<ItemId, int>(ItemId.ItemSuperPotion, 0),
+            new KeyValuePair<ItemId, int>(ItemId.ItemHyperPotion, 20),
+            new KeyValuePair<ItemId, int>(ItemId.ItemMaxPotion, 50),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemRevive, 10),
+            new KeyValuePair<ItemId, int>(ItemId.ItemMaxRevive, 50),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemLuckyEgg, 200),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseOrdinary, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseSpicy, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseCool, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseFloral, 100),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemTroyDisk, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemXAttack, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemXDefense, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemXMiracle, 100),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemRazzBerry, 20),
+            new KeyValuePair<ItemId, int>(ItemId.ItemBlukBerry, 10),
+            new KeyValuePair<ItemId, int>(ItemId.ItemNanabBerry, 10),
+            new KeyValuePair<ItemId, int>(ItemId.ItemWeparBerry, 30),
+            new KeyValuePair<ItemId, int>(ItemId.ItemPinapBerry, 30),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemSpecialCamera, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncubatorBasicUnlimited, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncubatorBasic, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemPokemonStorageUpgrade, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemItemStorageUpgrade, 100),
+        };
+
+        public ICollection<PokemonId> PokemonsToEvolve
         {
             get
             {
-                //Items to Recylce but keep X amount
-                return new[]
-                {
-                    new KeyValuePair<ItemId, int>(ItemId.ItemUnknown, 0),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemPokeBall, 20),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemGreatBall, 20),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemUltraBall, 50),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemMasterBall, 100),
-
-                    new KeyValuePair<ItemId, int>(ItemId.ItemPotion, 0),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemSuperPotion, 0),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemHyperPotion, 20),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemMaxPotion, 50),
-
-                    new KeyValuePair<ItemId, int>(ItemId.ItemRevive, 10),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemMaxRevive, 50),
-
-                    new KeyValuePair<ItemId, int>(ItemId.ItemLuckyEgg, 200),
-
-                    new KeyValuePair<ItemId, int>(ItemId.ItemIncenseOrdinary, 100),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemIncenseSpicy, 100),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemIncenseCool, 100),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemIncenseFloral, 100),
-
-                    new KeyValuePair<ItemId, int>(ItemId.ItemTroyDisk, 100),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemXAttack, 100),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemXDefense, 100),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemXMiracle, 100),
-
-                    new KeyValuePair<ItemId, int>(ItemId.ItemRazzBerry, 20),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemBlukBerry, 10),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemNanabBerry, 10),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemWeparBerry, 30),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemPinapBerry, 30),
-
-                    new KeyValuePair<ItemId, int>(ItemId.ItemSpecialCamera, 100),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemIncubatorBasicUnlimited, 100),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemIncubatorBasic, 100),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemPokemonStorageUpgrade, 100),
-                    new KeyValuePair<ItemId, int>(ItemId.ItemItemStorageUpgrade, 100),
-                };
+                //Type of pokemons to evolve
+                _pokemonsToEvolve = _pokemonsToEvolve ?? LoadPokemonList("PokemonsToEvolve");
+                return _pokemonsToEvolve;
             }
-            set
+        }
+
+        public ICollection<PokemonId> PokemonsNotToTransfer
+        {
+            get
+            {
+                //Type of pokemons not to transfer
+                _pokemonsNotToTransfer = _pokemonsNotToTransfer ?? LoadPokemonList("PokemonsNotToTransfer");
+                return _pokemonsNotToTransfer;
+            }
+        }
+
+        public ICollection<PokemonId> PokemonsNotToCatch
+        {
+            get
             {
-                throw new NotImplementedException();
+                //Type of pokemons not to catch
+                _pokemonsNotToCatch = _pokemonsNotToCatch ?? LoadPokemonList("PokemonsNotToCatch");
+                return _pokemonsNotToCatch;
             }
         }

@@ -119,36 +138,5 @@ namespace PokemonGo.RocketAPI.Console
             }
             return result;
         }
-
-        public ICollection<PokemonId> PokemonsToEvolve
-        {
-            get
-            {
-                //Type of pokemons to evolve
-                _pokemonsToEvolve = _pokemonsToEvolve != null ? _pokemonsToEvolve : LoadPokemonList("PokemonsToEvolve");
-                return _pokemonsToEvolve;
-            }
-        }
-
-        public ICollection<PokemonId> PokemonsNotToTransfer
-        {
-            get
-            {
-                //Type of pokemons not to transfer
-                _pokemonsNotToTransfer = _pokemonsNotToTransfer != null ? _pokemonsNotToTransfer : LoadPokemonList("PokemonsNotToTransfer");
-                return _pokemonsNotToTransfer;
-            }
-        }
-
-        public ICollection<PokemonId> PokemonsNotToCatch
-        {
-            get
-            {
-                //Type of pokemons not to catch
-                _pokemonsNotToCatch = _pokemonsNotToCatch != null ? _pokemonsNotToCatch : LoadPokemonList("PokemonsNotToCatch");
-                return _pokemonsNotToCatch;
-            }
-        }
-
     }
 }
diff --git a/PokemonGo.RocketAPI.Logic/Inventory.cs b/PokemonGo.RocketAPI.Logic/Inventory.cs
index f954abb..785d165 100644
--- a/PokemonGo.RocketAPI.Logic/Inventory.cs
+++ b/PokemonGo.RocketAPI.Logic/Inventory.cs
@@ -25,7 +25,7 @@ namespace PokemonGo.RocketAPI.Logic
             var inventory = await _client.GetInventory();
             return
                 inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.Pokemon)
-                    .Where(p => p != null && p?.PokemonId > 0);
+                    .Where(p => p != null && p.PokemonId > 0);
         }

         public async Task<IEnumerable<PokemonFamily>> GetPokemonFamilies()
@@ -33,7 +33,7 @@ namespace PokemonGo.RocketAPI.Logic
             var inventory = await _client.GetInventory();
             return
                 inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.PokemonFamily)
-                    .Where(p => p != null && p?.FamilyId != PokemonFamilyId.FamilyUnset);
+                    .Where(p => p != null && p.FamilyId != PokemonFamilyId.FamilyUnset);
         }

         public async Task<IEnumerable<PokemonSettings>> GetPokemonSettings()
@@ -41,7 +41,7 @@ namespace PokemonGo.RocketAPI.Logic
             var templates = await _client.GetItemTemplates();
             return
                 templates.ItemTemplates.Select(i => i.PokemonSettings)
-                    .Where(p => p != null && p?.FamilyId != PokemonFamilyId.FamilyUnset);
+                    .Where(p => p != null && p.FamilyId != PokemonFamilyId.FamilyUnset);
         }

         public async Task<IEnumerable<PokemonData>> GetHighestsCP(int limit)
@@ -64,7 +64,7 @@ namespace PokemonGo.RocketAPI.Logic
         {
             var myPokemon = await GetPokemons();
             var pokemons = myPokemon.ToList();
-            return pokemons.OrderByDescending(x => Logic.CalculatePokemonPerfection(x)).Take(limit);
+            return pokemons.OrderByDescending(Logic.CalculatePokemonPerfection).Take(limit);
         }

         public async Task<IEnumerable<PokemonData>> GetDuplicatePokemonToTransfer(bool keepPokemonsThatCanEvolve = false, int KeepMinDuplicatePokemon = 1, IEnumerable<PokemonId> filter = null)
diff --git a/PokemonGo.RocketAPI.Logic/Logic.cs b/PokemonGo.RocketAPI.Logic/Logic.cs
index 05e14dc..9006344 100644
--- a/PokemonGo.RocketAPI.Logic/Logic.cs
+++ b/PokemonGo.RocketAPI.Logic/Logic.cs
@@ -239,7 +239,7 @@ namespace PokemonGo.RocketAPI.Logic
                 if (encounter.Status == EncounterResponse.Types.Status.EncounterSuccess)
                     await CatchEncounter(encounter, pokemon);
                 else
-                    Logger.Normal($"Encounter problem: {encounter?.Status}");
+                    Logger.Normal($"Encounter problem: {encounter.Status}");
             }
             await RandomHelper.RandomDelay(500, 1000);
         }
@@ -253,7 +253,7 @@ namespace PokemonGo.RocketAPI.Logic
                 var inventoryBerries = await _inventory.GetItems();
                 var berries = inventoryBerries.Where(p => (ItemId)p.Item_ == bestBerry).FirstOrDefault(); ;
                 var probability = encounter?.CaptureProbability?.CaptureProbability_?.FirstOrDefault();
-                if (bestBerry != AllEnum.ItemId.ItemUnknown && probability.HasValue && probability.Value < 0.35)
+                if (bestBerry != AllEnum.ItemId.ItemUnknown && probability.HasValue && probability.Value < 0.35 && CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData) >= _clientSettings.KeepMinIVPercentage)
                 {
                     var useRaspberry = await _client.UseCaptureItem(pokemon.EncounterId, bestBerry, pokemon.SpawnpointId);
                     Logger.Normal($"(BERRY) {bestBerry} used, remaining: {berries.Count}");
@@ -281,8 +281,8 @@ namespace PokemonGo.RocketAPI.Logic
                 _stats.updateConsoleTitle(_inventory);
                 Logger.Normal(ConsoleColor.Yellow,
                     caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess
-                    ? $"(POKEBATTLE) {pokemon.PokemonId} (CP {encounter?.WildPokemon?.PokemonData?.Cp}) ({Math.Round(CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData)).ToString("0.00")}% perfection) | Chance: {Math.Round(Convert.ToDouble(encounter?.CaptureProbability.CaptureProbability_.First()))} | {Math.Round(distance)}m distance | with {bestPokeball} and received XP {caughtPokemonResponse.Scores.Xp.Sum()}"
-                    : $"(POKEBATTLE) {pokemon.PokemonId} (CP {encounter?.WildPokemon?.PokemonData?.Cp}) | Chance: {Math.Round(Convert.ToDouble(encounter?.CaptureProbability?.CaptureProbability_.First()))} {caughtPokemonResponse.Status} | {Math.Round(distance)}m distance | using a {bestPokeball}.."
+                    ? $"(POKEBATTLE) Caught {pokemon.PokemonId} (CP {encounter?.WildPokemon?.PokemonData?.Cp} | {Math.Round(CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData)).ToString("0.00")} % perfect) | Chance: {(float)((int)(encounter?.CaptureProbability?.CaptureProbability_.First() * 100)) / 100} | {Math.Round(distance)}m distance | with {bestPokeball} and received XP {caughtPokemonResponse.Scores.Xp.Sum()}"
+                    : $"(POKEBATTLE) Missed/Escaped {pokemon.PokemonId} (CP {encounter?.WildPokemon?.PokemonData?.Cp} | {Math.Round(CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData)).ToString("0.00")} % perfect) | Chance: {(float)((int)(encounter?.CaptureProbability?.CaptureProbability_.First() * 100)) / 100} {caughtPokemonResponse.Status} | {Math.Round(distance)}m distance | using a {bestPokeball}.."
                     );
                 await RandomHelper.RandomDelay(1750, 2250);
             }
@@ -326,7 +326,7 @@ namespace PokemonGo.RocketAPI.Logic
                 _stats.increasePokemonsTransfered();
                 _stats.updateConsoleTitle(_inventory);

-                PokemonData bestPokemonOfType = await _inventory.GetHighestPokemonOfTypeByCP(duplicatePokemon);
+                var bestPokemonOfType = await _inventory.GetHighestPokemonOfTypeByCP(duplicatePokemon);
                 Logger.Normal(ConsoleColor.DarkYellow, $"(TRANSFER) {duplicatePokemon.PokemonId} (CP {duplicatePokemon.Cp} | {CalculatePokemonPerfection(duplicatePokemon).ToString("0.00")} % perfect) | (Best: {bestPokemonOfType.Cp} CP | {CalculatePokemonPerfection(bestPokemonOfType).ToString("0.00")} % perfect)");
                 await Task.Delay(500);
             }
@@ -340,8 +340,8 @@ namespace PokemonGo.RocketAPI.Logic

             foreach (var item in items)
             {
-                var transfer = await _client.RecycleItem((AllEnum.ItemId)item.Item_, item.Count);
-                Logger.Normal(ConsoleColor.DarkCyan, $"(RECYCLED) {item.Count}x {(AllEnum.ItemId)item.Item_}");
+                var transfer = await _client.RecycleItem((ItemId)item.Item_, item.Count);
+                Logger.Normal(ConsoleColor.DarkCyan, $"(RECYCLED) {item.Count}x {item.Item_}");

                 _stats.addItemsRemoved(item.Count);
                 _stats.updateConsoleTitle(_inventory);
@@ -429,7 +429,7 @@ namespace PokemonGo.RocketAPI.Logic
             return berries.OrderBy(g => g.Key).First().Key;
         }

-        private async Task DisplayPlayerLevelInTitle()
+        private async Task DisplayPlayerLevelInTitle(bool updateOnly = false)
         {
             _playerProfile = _playerProfile.Profile != null ? _playerProfile : await _client.GetProfile();
             var playerName = _playerProfile.Profile.Username ?? "";
@@ -438,11 +438,13 @@ namespace PokemonGo.RocketAPI.Logic
             if (playerStat != null)
             {
                 var message =
-                    $"Character Level {playerName} {playerStat.Level:0} - ({playerStat.Experience - playerStat.PrevLevelXp:0} / {playerStat.NextLevelXp - playerStat.PrevLevelXp:0} XP)";
+                    $" {playerName} | Level {playerStat.Level:0} - ({playerStat.Experience - playerStat.PrevLevelXp:0} / {playerStat.NextLevelXp - playerStat.PrevLevelXp:0} XP)";
                 Console.Title = message;
-                Logger.Normal(message);
+                if (updateOnly == false)
+                    Logger.Normal(message);
             }
-            await Task.Delay(5000);
+            if (updateOnly == false)
+                await Task.Delay(5000);
         }

         private async Task DisplayHighests()
diff --git a/PokemonGo.RocketAPI.Logic/Navigation.cs b/PokemonGo.RocketAPI.Logic/Navigation.cs
index 23eef21..0d4217e 100644
--- a/PokemonGo.RocketAPI.Logic/Navigation.cs
+++ b/PokemonGo.RocketAPI.Logic/Navigation.cs
@@ -1,7 +1,6 @@
 #region

 using System;
-using System.Runtime.InteropServices;
 using System.Threading.Tasks;
 using PokemonGo.RocketAPI.GeneratedCode;
 using PokemonGo.RocketAPI.Logic.Utils;
@@ -14,7 +13,7 @@ namespace PokemonGo.RocketAPI.Logic
     public class Navigation
     {

-        private static readonly double speedDownTo = 10 / 3.6;
+        private const double SpeedDownTo = 10 / 3.6;
         private readonly Client _client;

         public Navigation(Client client)
@@ -22,58 +21,66 @@ namespace PokemonGo.RocketAPI.Logic
             _client = client;
         }

-        public async Task<PlayerUpdateResponse> HumanLikeWalking(Location targetLocation, double walkingSpeedInKilometersPerHour, Func<Task> functionExecutedWhileWalking)
+        public static double DistanceBetween2Coordinates(double lat1, double lng1, double lat2, double lng2)
         {
-            double speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6;
+            const double rEarth = 6378137;
+            var dLat = (lat2 - lat1) * Math.PI / 180;
+            var dLon = (lng2 - lng1) * Math.PI / 180;
+            var alpha = Math.Sin(dLat / 2) * Math.Sin(dLat / 2)
+                        + Math.Cos(lat1 * Math.PI / 180) * Math.Cos(lat2 * Math.PI / 180)
+                        * Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
+            var d = 2 * rEarth * Math.Atan2(Math.Sqrt(alpha), Math.Sqrt(1 - alpha));
+            return d;
+        }

-            Location sourceLocation = new Location(_client.CurrentLat, _client.CurrentLng);
+        public async Task<PlayerUpdateResponse> HumanLikeWalking(Location targetLocation,
+            double walkingSpeedInKilometersPerHour, Func<Task> functionExecutedWhileWalking)
+        {
+            var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6;
+
+            var sourceLocation = new Location(_client.CurrentLat, _client.CurrentLng);
             var distanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
             Logger.Normal($"(NAVIGATION) Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget / speedInMetersPerSecond:0.##} seconds!");

-            double nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
-            double nextWaypointDistance = speedInMetersPerSecond;
-            Location waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
+            var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
+            var nextWaypointDistance = speedInMetersPerSecond;
+            var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);

             //Initial walking
-            DateTime requestSendDateTime = DateTime.Now;
-            var result = await _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, _client.Settings.DefaultAltitude);
+            var requestSendDateTime = DateTime.Now;
+            var result =
+                await
+                    _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, _client.Settings.DefaultAltitude);

+            if (functionExecutedWhileWalking != null)
+                await functionExecutedWhileWalking();
             do
             {
-                double millisecondsUntilGetUpdatePlayerLocationResponse = (DateTime.Now - requestSendDateTime).TotalMilliseconds;
+                var millisecondsUntilGetUpdatePlayerLocationResponse =
+                    (DateTime.Now - requestSendDateTime).TotalMilliseconds;

                 sourceLocation = new Location(_client.CurrentLat, _client.CurrentLng);
                 var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);

                 if (currentDistanceToTarget < 40)
                 {
-                    if (speedInMetersPerSecond > speedDownTo)
-                    {
-                        Logger.Normal("(NAVIGATION) We are within 40 meters of the target. Speeding down to 10 km/h to not pass the target.");
-                        speedInMetersPerSecond = speedDownTo;
-                    }
-                    else
+                    if (speedInMetersPerSecond > SpeedDownTo)
                     {
-                        Logger.Normal("(NAVIGATION) We are within 40 meters of the target, attempting to interact.");
+                        Logger.Normal($"(NAVIGATION) We are within 40 meters of the target. Speeding down to 10 km/h to not pass the target.");
+                        speedInMetersPerSecond = SpeedDownTo;
                     }
                 }
-                else
-                {
-                    Logger.Normal($"(NAVIGATION) Distance to target location: {LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation):0.##} meters.");
-                }

-                nextWaypointDistance = Math.Min(currentDistanceToTarget, millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
+                nextWaypointDistance = Math.Min(currentDistanceToTarget,
+                    millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
                 nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
                 waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);

                 requestSendDateTime = DateTime.Now;
-                result = await _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, _client.Settings.DefaultAltitude);
-
-                if (functionExecutedWhileWalking != null)
-                {
-                    await functionExecutedWhileWalking();
-                }
-
+                result =
+                    await
+                        _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude,
+                            _client.Settings.DefaultAltitude);
                 await Task.Delay(Math.Min((int)(distanceToTarget / speedInMetersPerSecond * 1000), 3000));
             } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30);

@@ -82,26 +89,14 @@ namespace PokemonGo.RocketAPI.Logic

         public class Location
         {
-            public double Latitude { get; set; }
-            public double Longitude { get; set; }
-
             public Location(double latitude, double longitude)
             {
                 Latitude = latitude;
                 Longitude = longitude;
             }
-        }

-        public static double DistanceBetween2Coordinates(double Lat1, double Lng1, double Lat2, double Lng2)
-        {
-            double r_earth = 6378137;
-            double d_lat = (Lat2 - Lat1) * Math.PI / 180;
-            double d_lon = (Lng2 - Lng1) * Math.PI / 180;
-            double alpha = Math.Sin(d_lat / 2) * Math.Sin(d_lat / 2)
-                + Math.Cos(Lat1 * Math.PI / 180) * Math.Cos(Lat2 * Math.PI / 180)
-                * Math.Sin(d_lon / 2) * Math.Sin(d_lon / 2);
-            double d = 2 * r_earth * Math.Atan2(Math.Sqrt(alpha), Math.Sqrt(1 - alpha));
-            return d;
+            public double Latitude { get; set; }
+            public double Longitude { get; set; }
         }
     }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs b/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs
index 00e6bdf..aeea988 100644
--- a/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs
+++ b/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs
@@ -79,9 +79,9 @@ namespace PokemonGo.RocketAPI.Logic.Utils
             return string.Format("{0} - LvL: {1:0}    EXP/H: {2:0.0} EXP   P/H: {3:0.0} Pokemon(s)   Stardust: {4:0}   Pokemon Transfered: {5:0}   Items Removed: {6:0}", "Statistics", _currentLevelInfos, _totalExperience / _getSessionRuntime(), _totalPokemons / _getSessionRuntime(), _totalStardust, _totalPokemonsTransfered, _totalItemsRemoved);
         }

-        public static int GetXpDiff(int Level)
+        public static int GetXpDiff(int level)
         {
-            switch (Level)
+            switch (level)
             {
                 case 1:
                     return 0;
diff --git a/PokemonGo.RocketAPI/Client.cs b/PokemonGo.RocketAPI/Client.cs
index c90fcc7..83d1b2c 100644
--- a/PokemonGo.RocketAPI/Client.cs
+++ b/PokemonGo.RocketAPI/Client.cs
@@ -35,19 +35,27 @@ namespace PokemonGo.RocketAPI
         public Client(ISettings settings)
         {
             Settings = settings;
-            if (File.Exists(Directory.GetCurrentDirectory() + "\\Coords.txt") && File.ReadAllText(Directory.GetCurrentDirectory() + "\\Coords.txt").Contains(":"))
+
+            string path = Directory.GetCurrentDirectory() + "\\Configs\\";
+            if (!Directory.Exists(path))
+            {
+                DirectoryInfo di = Directory.CreateDirectory(path);
+            }
+            string filename = "LastCoords.txt";
+            if (File.Exists(path + filename) && File.ReadAllText(path + filename).Contains(":"))
             {
-                var latlngFromFile = File.ReadAllText(Directory.GetCurrentDirectory() + "\\Coords.txt");
+                var latlngFromFile = File.ReadAllText(path + filename);
                 var latlng = latlngFromFile.Split(':');
-                if (latlng[0].Length != 0 && latlng[1].Length != 0)
+                if (latlng[0].Length != 0 && latlng[1].Length != 0 && latlng[0] != "NaN" && latlng[1] != "NaN")
                 {
                     try
                     {
-                        SetCoordinates(Convert.ToDouble(latlng[0]), Convert.ToDouble(latlng[1]), Settings.DefaultAltitude);
+                        SetCoordinates(Convert.ToDouble(latlng[0]), Convert.ToDouble(latlng[1]),
+                            Settings.DefaultAltitude);
                     }
                     catch (FormatException)
                     {
-                        Logger.Error($"Coordinates in \"Coords.txt\" file is invalid, using the default coordinates ");
+                        Logger.Error("Coordinates in \"Configs\\Coords.txt\" file is invalid, using the default coordinates");
                         SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
                     }
                 }
@@ -80,7 +88,7 @@ namespace PokemonGo.RocketAPI
         public void SaveLatLng(double lat, double lng)
         {
             string latlng = lat.ToString() + ":" + lng.ToString();
-            File.WriteAllText(Directory.GetCurrentDirectory() + "\\Coords.txt", latlng);
+            File.WriteAllText(Directory.GetCurrentDirectory() + "\\Configs\\LastCoords.txt", latlng);
         }

         private void SetCoordinates(double lat, double lng, double altitude)
@@ -95,7 +103,7 @@ namespace PokemonGo.RocketAPI
         {
             _authType = AuthType.Google;

-            GoogleLogin.TokenResponseModel tokenResponse = null;
+            GoogleLogin.TokenResponseModel tokenResponse;
             if (Settings.GoogleRefreshToken != string.Empty)
             {
                 tokenResponse = await GoogleLogin.GetAccessToken(Settings.GoogleRefreshToken);
diff --git a/PokemonGo.RocketAPI/Helpers/RetryHandler.cs b/PokemonGo.RocketAPI/Helpers/RetryHandler.cs
index b65a51d..b514eb7 100644
--- a/PokemonGo.RocketAPI/Helpers/RetryHandler.cs
+++ b/PokemonGo.RocketAPI/Helpers/RetryHandler.cs
@@ -36,12 +36,8 @@ namespace PokemonGo.RocketAPI.Helpers
                 catch (Exception ex)
                 {
                     Logger.Error($"[#{i} of {MaxRetries}] retry request {request.RequestUri} - Error: {ex}");
-                    if (i < MaxRetries)
-                    {
-                        await Task.Delay(1000);
-                        continue;
-                    }
-                    throw;
+                    if (i >= MaxRetries) throw;
+                    await Task.Delay(1000, cancellationToken);
                 }
             }
             return null;
diff --git a/PokemonGo.RocketAPI/Helpers/S2Helper.cs b/PokemonGo.RocketAPI/Helpers/S2Helper.cs
index 65cd325..e05f00f 100644
--- a/PokemonGo.RocketAPI/Helpers/S2Helper.cs
+++ b/PokemonGo.RocketAPI/Helpers/S2Helper.cs
@@ -1,51 +1,56 @@
-#region
-
-using System.Collections.Generic;
-using System.Linq;
-using Google.Common.Geometry;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Helpers
-{
-    public class S2Helper
-    {
-        public static List<ulong> GetNearbyCellIds(double longitude, double latitude)
-        {
-            var nearbyCellIds = new List<S2CellId>();
-
-            var cellId = S2CellId.FromLatLng(S2LatLng.FromDegrees(latitude, longitude)).ParentForLevel(15);//.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent;
-
-            nearbyCellIds.Add(cellId);
-            for (int i = 0; i < 10; i++)
-            {
-                nearbyCellIds.Add(GetPrevious(cellId, i));
-                nearbyCellIds.Add(GetNext(cellId, i));
-            }
-
-            return nearbyCellIds.Select(c => c.Id).OrderBy(c => c).ToList();
-        }
-
-        private static S2CellId GetPrevious(S2CellId cellId, int depth)
-        {
-            if (depth < 0)
-                return cellId;
-
-            depth--;
-
-            return GetPrevious(cellId.Previous, depth);
-        }
-
-        private static S2CellId GetNext(S2CellId cellId, int depth)
-        {
-            if (depth < 0)
-                return cellId;
-
-            depth--;
-
-            return GetNext(cellId.Next, depth);
-        }
-
-    }
+#region
+
+using System.Collections.Generic;
+using System.Linq;
+using Google.Common.Geometry;
+
+#endregion
+
+namespace PokemonGo.RocketAPI.Helpers
+{
+    public class S2Helper
+    {
+        public static List<ulong> GetNearbyCellIds(double longitude, double latitude)
+        {
+            var nearbyCellIds = new List<S2CellId>();
+
+            var cellId = S2CellId.FromLatLng(S2LatLng.FromDegrees(latitude, longitude)).ParentForLevel(15);
+            //.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent;
+
+            nearbyCellIds.Add(cellId);
+            for (var i = 0; i < 10; i++)
+            {
+                nearbyCellIds.Add(GetPrevious(cellId, i));
+                nearbyCellIds.Add(GetNext(cellId, i));
+            }
+
+            return nearbyCellIds.Select(c => c.Id).OrderBy(c => c).ToList();
+        }
+
+        private static S2CellId GetNext(S2CellId cellId, int depth)
+        {
+            while (true)
+            {
+                if (depth < 0)
+                    return cellId;
+
+                depth--;
+
+                cellId = cellId.Next;
+            }
+        }
+
+        private static S2CellId GetPrevious(S2CellId cellId, int depth)
+        {
+            while (true)
+            {
+                if (depth < 0)
+                    return cellId;
+
+                depth--;
+
+                cellId = cellId.Previous;
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/ISettings.cs b/PokemonGo.RocketAPI/ISettings.cs
index 4771114..76deca6 100644
--- a/PokemonGo.RocketAPI/ISettings.cs
+++ b/PokemonGo.RocketAPI/ISettings.cs
@@ -2,6 +2,8 @@

 using PokemonGo.RocketAPI.Enums;
 using System.Collections.Generic;
+using PokemonGo.RocketAPI.GeneratedCode;
+using AllEnum;

 #endregion

@@ -25,12 +27,12 @@ namespace PokemonGo.RocketAPI
         bool UsePokemonToNotCatchFilter { get; }
         int KeepMinDuplicatePokemon { get; }

-        ICollection<KeyValuePair<AllEnum.ItemId, int>> ItemRecycleFilter { get; set; }
+        ICollection<KeyValuePair<ItemId, int>> ItemRecycleFilter { get; }

-        ICollection<AllEnum.PokemonId> PokemonsToEvolve { get; }
+        ICollection<PokemonId> PokemonsToEvolve { get; }

-        ICollection<AllEnum.PokemonId> PokemonsNotToTransfer { get; }
+        ICollection<PokemonId> PokemonsNotToTransfer { get; }

-        ICollection<AllEnum.PokemonId> PokemonsNotToCatch { get; }
+        ICollection<PokemonId> PokemonsNotToCatch { get; }
     }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/Logging/Logger.cs b/PokemonGo.RocketAPI/Logging/Logger.cs
index 4611856..e3a86b3 100644
--- a/PokemonGo.RocketAPI/Logging/Logger.cs
+++ b/PokemonGo.RocketAPI/Logging/Logger.cs
@@ -103,7 +103,7 @@ namespace PokemonGo.RocketAPI
         private static void Log(string message)
         {
             // maybe do a new log rather than appending?
-            using (StreamWriter log = File.AppendText(path + _currentFile + ".txt"))
+            using (var log = File.AppendText(path + _currentFile + ".txt"))
             {
                 log.WriteLine(message);
                 log.Flush();
diff --git a/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj b/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
index 67d2913..3c71722 100644
--- a/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
+++ b/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
@@ -17,7 +17,7 @@
     <UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
     <AssemblyVersionSettings>YearStamp.MonthStamp.DayStamp.Increment</AssemblyVersionSettings>
     <PrimaryVersionType>AssemblyVersionAttribute</PrimaryVersionType>
-    <AssemblyVersion>2016.7.23.88</AssemblyVersion>
+    <AssemblyVersion>2016.7.23.103</AssemblyVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -93,6 +93,7 @@
     <Compile Include="GeneratedCode\Payloads.cs" />
     <Compile Include="GeneratedCode\Request.cs" />
     <Compile Include="GeneratedCode\Response.cs" />
+    <Compile Include="Helpers\Git.cs" />
     <Compile Include="Helpers\HttpClientHelper.cs" />
     <Compile Include="Helpers\JsonHelper.cs" />
     <Compile Include="Helpers\ProtoHelper.cs" />
diff --git a/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs b/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
index 521dbcc..05643d3 100644
--- a/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
+++ b/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2016.7.23.88")]
+[assembly: AssemblyVersion("2016.7.23.103")]
 [assembly: AssemblyFileVersion("1.0.0.0")]
You may download the files in Public Git.