Changes, changes, changes ;-)

Spegeli [2016-07-24 06:16:22]
Changes, changes, changes ;-)
Filename
PokemonGo.RocketAPI.Console/Program.cs
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/Git.cs
PokemonGo.RocketAPI/Helpers/RetryHandler.cs
PokemonGo.RocketAPI/Logging/ConsoleLogger.cs
PokemonGo.RocketAPI/Logging/ILogger.cs
PokemonGo.RocketAPI/Logging/Logger.cs
PokemonGo.RocketAPI/Login/GoogleLogin.cs
PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
diff --git a/PokemonGo.RocketAPI.Console/Program.cs b/PokemonGo.RocketAPI.Console/Program.cs
index 31afbbb..117317a 100644
--- a/PokemonGo.RocketAPI.Console/Program.cs
+++ b/PokemonGo.RocketAPI.Console/Program.cs
@@ -4,6 +4,7 @@ using System;
 using System.Threading;
 using System.Threading.Tasks;
 using PokemonGo.RocketAPI.Exceptions;
+using PokemonGo.RocketAPI.Logging;

 #endregion

@@ -23,7 +24,7 @@ namespace PokemonGo.RocketAPI.Console
                     Environment.Exit(1);
                 };

-            Logger.SetLogger(new Logging.ConsoleLogger(LogLevel.Info));
+            Logger.SetLogger();

             Task.Run(() =>
             {
@@ -33,19 +34,19 @@ namespace PokemonGo.RocketAPI.Console
                 }
                 catch (PtcOfflineException)
                 {
-                    Logger.Error("PTC Servers are probably down OR your credentials are wrong. Try google");
-                    Logger.Error("Trying again in 60 seconds...");
+                    Logger.Write("PTC Servers are probably down OR your credentials are wrong. Try google", LogLevel.Error);
+                    Logger.Write("Trying again in 60 seconds...");
                     Thread.Sleep(60000);
                     new Logic.Logic(new Settings()).Execute().Wait();
                 }
                 catch (AccountNotVerifiedException)
                 {
-                    Logger.Error("Account not verified. - Exiting");
+                    Logger.Write("Account not verified. - Exiting");
                     Environment.Exit(0);
                 }
                 catch (Exception ex)
                 {
-                    Logger.Error($"Unhandled exception: {ex}");
+                    Logger.Write($"Unhandled exception: {ex}", LogLevel.Error);
                     new Logic.Logic(new Settings()).Execute().Wait();
                 }
             });
diff --git a/PokemonGo.RocketAPI.Console/Settings.cs b/PokemonGo.RocketAPI.Console/Settings.cs
index 4178417..2286a09 100644
--- a/PokemonGo.RocketAPI.Console/Settings.cs
+++ b/PokemonGo.RocketAPI.Console/Settings.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
 using System.IO;
 using PokemonGo.RocketAPI.Enums;
 using PokemonGo.RocketAPI.GeneratedCode;
+using PokemonGo.RocketAPI.Logging;

 #endregion

@@ -124,11 +125,12 @@ namespace PokemonGo.RocketAPI.Console
             if (!File.Exists(path + filename + ".txt"))
             {
                 string pokemonName = Properties.Resources.ResourceManager.GetString(filename);
-                Logger.Normal($"File: {filename} not found, creating new...");
+                Logger.Write($"File: {filename} not found, creating new...", LogLevel.Warning);
                 File.WriteAllText(path + filename + ".txt", pokemonName);
             }
             if (File.Exists(path + filename + ".txt"))
             {
+                Logger.Write($"Loading File: Configs\\{filename}", LogLevel.Info);
                 string[] _locallist = File.ReadAllLines(path + filename + ".txt");
                 foreach (string pokemonName in _locallist)
                 {
diff --git a/PokemonGo.RocketAPI.Logic/Inventory.cs b/PokemonGo.RocketAPI.Logic/Inventory.cs
index caa4f91..c4a53ef 100644
--- a/PokemonGo.RocketAPI.Logic/Inventory.cs
+++ b/PokemonGo.RocketAPI.Logic/Inventory.cs
@@ -29,7 +29,7 @@ namespace PokemonGo.RocketAPI.Logic
         {
             var myPokemon = await GetPokemons();

-            var pokemonList = myPokemon.Where(p => p.DeployedFortId == 0 && p.Favorite == 0).ToList(); //Don't evolve pokemon in gyms
+            var pokemonList = myPokemon.Where(p => p.DeployedFortId == 0 && p.Favorite == 0 && p.Cp < _client.Settings.KeepMinCP).ToList(); //Don't evolve pokemon in gyms
             if (filter != null)
             {
                 pokemonList = pokemonList.Where(p => !filter.Contains(p.PokemonId)).ToList();
diff --git a/PokemonGo.RocketAPI.Logic/Logic.cs b/PokemonGo.RocketAPI.Logic/Logic.cs
index 5ad692e..0de5aaa 100644
--- a/PokemonGo.RocketAPI.Logic/Logic.cs
+++ b/PokemonGo.RocketAPI.Logic/Logic.cs
@@ -13,6 +13,7 @@ using PokemonGo.RocketAPI.Logic.Utils;
 using PokemonGo.RocketAPI.Helpers;
 using System.IO;
 using System.Text;
+using PokemonGo.RocketAPI.Logging;

 #endregion

@@ -27,6 +28,7 @@ namespace PokemonGo.RocketAPI.Logic
         private readonly Statistics _stats;
         private readonly Navigation _navigation;
         private GetPlayerResponse _playerProfile;
+        private int recycleCounter = 0;

         public Logic(ISettings clientSettings)
         {
@@ -43,21 +45,21 @@ namespace PokemonGo.RocketAPI.Logic

             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!");
+                Logger.Write($"Please change first Latitude and/or Longitude because currently your using default values!", LogLevel.Error);
+                Logger.Write($"Window will be auto closed in 15 seconds!", LogLevel.Error);
                 await Task.Delay(15000);
                 System.Environment.Exit(1);
             } else
             {
-                Logger.Error($"Make sure Lat & Lng is right. Exit Program if not! Lat: {_client.CurrentLat} Lng: {_client.CurrentLng}");
+                Logger.Write($"Make sure Lat & Lng is right. Exit Program if not! Lat: {_client.CurrentLat} Lng: {_client.CurrentLng}", LogLevel.Warning);
                 for (int i = 3; i > 0; i--)
                 {
-                    Logger.Error($"Script will continue in {i * 5} seconds!");
+                    Logger.Write($"Script will continue in {i * 5} seconds!", LogLevel.Warning);
                     await Task.Delay(5000);
                 }
             }

-            Logger.Normal(ConsoleColor.DarkGreen, $"Logging in via: {_clientSettings.AuthType}");
+            Logger.Write($"Logging in via: {_clientSettings.AuthType}", LogLevel.Info);
             while (true)
             {
                 try
@@ -73,48 +75,48 @@ namespace PokemonGo.RocketAPI.Logic
                 }
                 catch (AccessTokenExpiredException ex)
                 {
-                    Logger.Error($"Access token expired");
-                    Logger.Error($"{ex}");
+                    Logger.Write($"Access token expired", LogLevel.Error);
+                    Logger.Write($"{ex}", LogLevel.Error);
                 }
                 catch (TaskCanceledException ex)
                 {
-                    Logger.Error("Task Canceled Exception - Restarting");
-                    Logger.Error($"{ex}");
+                    Logger.Write("Task Canceled Exception - Restarting", LogLevel.Error);
+                    Logger.Write($"{ex}", LogLevel.Error);
                     await Execute();
                 }
                 catch (UriFormatException ex)
                 {
-                    Logger.Error("UriFormatException - Restarting");
-                    Logger.Error($"{ex}");
+                    Logger.Write("UriFormatException - Restarting", LogLevel.Error);
+                    Logger.Write($"{ex}", LogLevel.Error);
                     await Execute();
                 }
                 catch (ArgumentOutOfRangeException ex)
                 {
-                    Logger.Error("ArgumentOutOfRangeException - Restarting");
-                    Logger.Error($"{ex}");
+                    Logger.Write("ArgumentOutOfRangeException - Restarting", LogLevel.Error);
+                    Logger.Write($"{ex}", LogLevel.Error);
                     await Execute();
                 }
                 catch (ArgumentNullException ex)
                 {
-                    Logger.Error("ArgumentNullException - Restarting");
-                    Logger.Error($"{ex}");
+                    Logger.Write("ArgumentNullException - Restarting", LogLevel.Error);
+                    Logger.Write($"{ex}");
                     await Execute();
                 }
                 catch (NullReferenceException ex)
                 {
-                    Logger.Error("NullReferenceException - Restarting");
-                    Logger.Error($"{ex}");
+                    Logger.Write("NullReferenceException - Restarting", LogLevel.Error);
+                    Logger.Write($"{ex}");
                     await Execute();
                 }
                 catch (InvalidResponseException)
                 {
-                    Logger.Error("InvalidResponseException - Restarting");
+                    Logger.Write("InvalidResponseException - Restarting", LogLevel.Error);
                     await Execute();
                 }
                 catch (AggregateException ex)
                 {
-                    Logger.Error("AggregateException - Restarting");
-                    Logger.Error($"{ex}");
+                    Logger.Write("AggregateException - Restarting", LogLevel.Error);
+                    Logger.Write($"{ex}");
                     await Execute();
                 }
                 await Task.Delay(10000);
@@ -123,7 +125,7 @@ namespace PokemonGo.RocketAPI.Logic

         public async Task PostLoginExecute()
         {
-            Logger.Normal(ConsoleColor.DarkGreen, $"Client logged in");
+            Logger.Write($"Client logged in", LogLevel.Info);

             while (true)
             {
@@ -134,21 +136,21 @@ namespace PokemonGo.RocketAPI.Logic

                 var _currentLevelInfos = await Statistics._getcurrentLevelInfos(_inventory);

-                Logger.Normal(ConsoleColor.Yellow, "----------------------------");
+                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);
                 if (_clientSettings.AuthType == AuthType.Ptc)
-                    Logger.Normal(ConsoleColor.Cyan, $"PTC Account: {_clientSettings.PtcUsername}\n");
+                    Logger.Write($"PTC Account: {_clientSettings.PtcUsername}\n", LogLevel.None, ConsoleColor.Cyan);
                 //Logger.Normal(ConsoleColor.Cyan, "Password: " + _clientSettings.PtcPassword + "\n");
-                Logger.Normal(ConsoleColor.DarkGray, $"Latitude: {_clientSettings.DefaultLatitude}");
-                Logger.Normal(ConsoleColor.DarkGray, $"Longitude: {_clientSettings.DefaultLongitude}");
-                Logger.Normal(ConsoleColor.Yellow, "----------------------------");
-                Logger.Normal(ConsoleColor.DarkGray, "Your Account:\n");
-                Logger.Normal(ConsoleColor.DarkGray, $"Name: {_playerProfile.Profile.Username}");
-                Logger.Normal(ConsoleColor.DarkGray, $"Team: {_playerProfile.Profile.Team}");
-                Logger.Normal(ConsoleColor.DarkGray, $"Level: {_currentLevelInfos}");
-                Logger.Normal(ConsoleColor.DarkGray, $"Stardust: {_playerProfile.Profile.Currency.ToArray()[1].Amount}");
-                Logger.Normal(ConsoleColor.Yellow, "----------------------------");
+                Logger.Write($"Latitude: {_clientSettings.DefaultLatitude}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write($"Longitude: {_clientSettings.DefaultLongitude}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);
+                Logger.Write("Your Account:\n");
+                Logger.Write($"Name: {_playerProfile.Profile.Username}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write($"Team: {_playerProfile.Profile.Team}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write($"Level: {_currentLevelInfos}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write($"Stardust: {_playerProfile.Profile.Currency.ToArray()[1].Amount}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);
                 await DisplayHighests();
-                Logger.Normal(ConsoleColor.Yellow, "----------------------------");
+                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);

                 var PokemonsNotToTransfer = _clientSettings.PokemonsNotToTransfer;
                 var PokemonsNotToCatch = _clientSettings.PokemonsNotToCatch;
@@ -195,7 +197,7 @@ namespace PokemonGo.RocketAPI.Logic
                     i =>
                     LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude)).ToArray());

-            Logger.Normal(ConsoleColor.Green, $"Found {pokeStops.Count()} pokestops");
+            Logger.Write($"Found {pokeStops.Count()} pokestops", LogLevel.None, ConsoleColor.Green);

             foreach (var pokeStop in pokeStops)
             {
@@ -203,62 +205,32 @@ namespace PokemonGo.RocketAPI.Logic
                 if (_clientSettings.EvolveAllPokemonWithEnoughCandy) await EvolveAllPokemonWithEnoughCandy(_clientSettings.PokemonsToEvolve);
                 if (_clientSettings.TransferDuplicatePokemon) await TransferDuplicatePokemon();

-                var update = await _navigation.HumanLikeWalking(new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);
                 var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokeStop.Latitude, pokeStop.Longitude);
                 var fortInfo = await _client.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
-                var fortSearch = await _client.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);

-                Logger.Normal(ConsoleColor.Cyan, $"(POKESTOP) Name: {fortInfo.Name} in {distance:0.##} m distance");
+                Logger.Write($"Name: {fortInfo.Name} in {distance:0.##} m distance", LogLevel.Pokestop);
+                var update = await _navigation.HumanLikeWalking(new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);
+
+                var fortSearch = await _client.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
                 if (fortSearch.ExperienceAwarded > 0)
                 {
                     _stats.AddExperience(fortSearch.ExperienceAwarded);
                     _stats.UpdateConsoleTitle(_inventory);
+
+                    Logger.Write($"XP: {fortSearch.ExperienceAwarded}, Gems: {fortSearch.GemsAwarded}, Eggs: {fortSearch.PokemonDataEgg} Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}", LogLevel.Pokestop);

-                    Logger.Normal(ConsoleColor.Cyan, $"(POKESTOP) XP: {fortSearch.ExperienceAwarded}, Gems: {fortSearch.GemsAwarded}, Eggs: {fortSearch.PokemonDataEgg} Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}");
+                    recycleCounter++;
                 }
                 await RandomHelper.RandomDelay(50, 200);
-                await RecycleItems();
-            }
-        }
-
-        private async Task ExecuteCatchAllNearbyPokemons()
-        {
-            var mapObjects = await _client.GetMapObjects();
-
-            var pokemons =
-                mapObjects.MapCells.SelectMany(i => i.CatchablePokemons)
-                .OrderBy(
-                    i =>
-                    LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude));
-
-            if (_clientSettings.UsePokemonToNotCatchFilter)
-            {
-                ICollection<PokemonId> filter = _clientSettings.PokemonsNotToCatch;
-                pokemons = mapObjects.MapCells.SelectMany(i => i.CatchablePokemons).Where(p => !filter.Contains(p.PokemonId)).OrderBy(i => LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude));
-            }
-
-            if (pokemons != null && pokemons.Any())
-                Logger.Normal(ConsoleColor.Green, $"Found {pokemons.Count()} catchable Pokemon");
-
-            foreach (var pokemon in pokemons)
-            {
-                var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokemon.Latitude, pokemon.Longitude);
-                await Task.Delay(distance > 100 ? 1000 : 100);
-
-                var encounter = await _client.EncounterPokemon(pokemon.EncounterId, pokemon.SpawnpointId);
-
-                if (encounter.Status == EncounterResponse.Types.Status.EncounterSuccess)
-                    await CatchEncounter(encounter, pokemon);
-                else
-                    Logger.Normal($"Encounter problem: {encounter.Status}");
-                if (pokemons.ElementAtOrDefault(pokemons.Count() - 1) != pokemon)
-                    await RandomHelper.RandomDelay(50, 200);
+                if (recycleCounter >= 5)
+                    await RecycleItems();
             }
         }

         private async Task CatchEncounter(EncounterResponse encounter, MapPokemon pokemon)
         {
             CatchPokemonResponse caughtPokemonResponse;
+            int attemptCounter = 1;
             do
             {
                 var bestBerry = await GetBestBerry(encounter?.WildPokemon);
@@ -268,14 +240,14 @@ namespace PokemonGo.RocketAPI.Logic
                 var bestPokeball = await GetBestBall(encounter?.WildPokemon);
                 if (bestPokeball == MiscEnums.Item.ITEM_UNKNOWN)
                 {
-                    Logger.Normal($"(POKEBATTLE) You don't own any Pokeballs :( - We missed a {pokemon.PokemonId} with CP {encounter?.WildPokemon?.PokemonData?.Cp}");
+                    Logger.Write($"You don't own any Pokeballs :( - We missed a {pokemon.PokemonId} with CP {encounter?.WildPokemon?.PokemonData?.Cp}", LogLevel.Warning);
                     return;
                 }
                 var berries = inventoryBerries.Where(p => (ItemId)p.Item_ == bestBerry).FirstOrDefault();
                 if (bestBerry != ItemId.ItemUnknown && probability.HasValue && probability.Value < 0.35 && PokemonInfo.CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData) >= _clientSettings.KeepMinIVPercentage)
                 {
                     var useRaspberry = await _client.UseCaptureItem(pokemon.EncounterId, bestBerry, pokemon.SpawnpointId);
-                    Logger.Normal($"(BERRY) {bestBerry} used, remaining: {berries.Count}");
+                    Logger.Write($"{bestBerry} used, remaining: {berries.Count}", LogLevel.Berry);
                     await RandomHelper.RandomDelay(50, 200);
                 }

@@ -291,31 +263,74 @@ namespace PokemonGo.RocketAPI.Logic
                     _stats.GetStardust(profile.Profile.Currency.ToArray()[1].Amount);
                 }
                 _stats.UpdateConsoleTitle(_inventory);
-                Logger.Normal(ConsoleColor.Yellow,
-                    caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess
-                    ? $"(POKEBATTLE) Caught {pokemon.PokemonId} Lvl {PokemonInfo.GetLevel(encounter?.WildPokemon?.PokemonData)} (CP {encounter?.WildPokemon?.PokemonData?.Cp}/{PokemonInfo.CalculateMaxCP(encounter?.WildPokemon?.PokemonData)} | {Math.Round(PokemonInfo.CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData)).ToString("0.00")} % perfect) | Chance: {(float)((int)(encounter?.CaptureProbability?.CaptureProbability_.First() * 100)) / 100} | {Math.Round(distance)}m dist | with {bestPokeball} and received XP {caughtPokemonResponse.Scores.Xp.Sum()}"
-                    : $"(POKEBATTLE) Missed/Escaped {pokemon.PokemonId} Lvl {PokemonInfo.GetLevel(encounter?.WildPokemon?.PokemonData)} (CP {encounter?.WildPokemon?.PokemonData?.Cp} | {Math.Round(PokemonInfo.CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData)).ToString("0.00")} % perfect) | Chance: {(float)((int)(encounter?.CaptureProbability?.CaptureProbability_.First() * 100)) / 100} {caughtPokemonResponse.Status} | {Math.Round(distance)}m dist | using a {bestPokeball}.."
-                    );
+                if (encounter?.CaptureProbability?.CaptureProbability_ != null)
+                {
+                    string catchStatus = attemptCounter > 1 ? $"{caughtPokemonResponse.Status} Attempt #{attemptCounter}" : $"{caughtPokemonResponse.Status}";
+                    Logger.Write(
+                        $"({catchStatus}) | {pokemon.PokemonId} Lvl {PokemonInfo.GetLevel(encounter?.WildPokemon?.PokemonData)} (CP {encounter?.WildPokemon?.PokemonData?.Cp}/{PokemonInfo.CalculateMaxCP(encounter?.WildPokemon?.PokemonData)} | {Math.Round(PokemonInfo.CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData)).ToString("0.00")} % perfect) | Chance: {(float)((int)(encounter?.CaptureProbability?.CaptureProbability_.First() * 100)) / 100} | {Math.Round(distance)}m dist | with {bestPokeball} and received XP {caughtPokemonResponse.Scores.Xp.Sum()}"
+                        , LogLevel.Pokemon);
+                    //Logger.Normal(ConsoleColor.Yellow,
+                    //caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess
+                    //? $"(POKEBATTLE) ({catchStatus}) | {pokemon.PokemonId} Lvl {PokemonInfo.GetLevel(encounter?.WildPokemon?.PokemonData)} (CP {encounter?.WildPokemon?.PokemonData?.Cp}/{PokemonInfo.CalculateMaxCP(encounter?.WildPokemon?.PokemonData)} | {Math.Round(PokemonInfo.CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData)).ToString("0.00")} % perfect) | Chance: {(float)((int)(encounter?.CaptureProbability?.CaptureProbability_.First() * 100)) / 100} | {Math.Round(distance)}m dist | with {bestPokeball} and received XP {caughtPokemonResponse.Scores.Xp.Sum()}"
+                    //: $"(POKEBATTLE) ({catchStatus}) | {pokemon.PokemonId} Lvl {PokemonInfo.GetLevel(encounter?.WildPokemon?.PokemonData)} (CP {encounter?.WildPokemon?.PokemonData?.Cp} | {Math.Round(PokemonInfo.CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData)).ToString("0.00")} % perfect) | Chance: {(float)((int)(encounter?.CaptureProbability?.CaptureProbability_.First() * 100)) / 100} {caughtPokemonResponse.Status} | {Math.Round(distance)}m dist | using a {bestPokeball}.."
+                    //);
+                }
+                attemptCounter++;
                 await RandomHelper.RandomDelay(750, 1250);
             }
             while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed || caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape);
         }

+        private async Task ExecuteCatchAllNearbyPokemons()
+        {
+            var mapObjects = await _client.GetMapObjects();
+
+            var pokemons =
+                mapObjects.MapCells.SelectMany(i => i.CatchablePokemons)
+                .OrderBy(
+                    i =>
+                    LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude));
+
+            if (_clientSettings.UsePokemonToNotCatchFilter)
+            {
+                ICollection<PokemonId> filter = _clientSettings.PokemonsNotToCatch;
+                pokemons = mapObjects.MapCells.SelectMany(i => i.CatchablePokemons).Where(p => !filter.Contains(p.PokemonId)).OrderBy(i => LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude));
+            }
+
+            if (pokemons != null && pokemons.Any())
+                Logger.Write($"Found {pokemons.Count()} catchable Pokemon", LogLevel.None, ConsoleColor.Green);
+
+            foreach (var pokemon in pokemons)
+            {
+                var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokemon.Latitude, pokemon.Longitude);
+                await Task.Delay(distance > 100 ? 1000 : 100);
+
+                var encounter = await _client.EncounterPokemon(pokemon.EncounterId, pokemon.SpawnpointId);
+
+                if (encounter.Status == EncounterResponse.Types.Status.EncounterSuccess)
+                    await CatchEncounter(encounter, pokemon);
+                else
+                    Logger.Write($"Encounter problem: {encounter.Status}", LogLevel.Warning);
+                if (pokemons.ElementAtOrDefault(pokemons.Count() - 1) != pokemon)
+                    await RandomHelper.RandomDelay(50, 200);
+            }
+        }
+
         private async Task EvolveAllPokemonWithEnoughCandy(IEnumerable<PokemonId> filter = null)
         {
             var pokemonToEvolve = await _inventory.GetPokemonToEvolve(filter);
             if (pokemonToEvolve != null && pokemonToEvolve.Any())
-                Logger.Normal($"(EVOLVE) {pokemonToEvolve.Count()} Pokemon:");
+                Logger.Write($"{pokemonToEvolve.Count()} Pokemon:", LogLevel.Evolve);

             foreach (var pokemon in pokemonToEvolve)
             {
                 var evolvePokemonOutProto = await _client.EvolvePokemon((ulong)pokemon.Id);

-                Logger.Normal(
+                Logger.Write(
                     evolvePokemonOutProto.Result == EvolvePokemonOut.Types.EvolvePokemonStatus.PokemonEvolvedSuccess
-                        ? $"(EVOLVE) {pokemon.PokemonId} successfully for {evolvePokemonOutProto.ExpAwarded} xp"
-                        : $"(EVOLVE) Failed: {pokemon.PokemonId}. EvolvePokemonOutProto.Result was {evolvePokemonOutProto.Result}, stopping evolving {pokemon.PokemonId}"
-                    );
+                        ? $"{pokemon.PokemonId} successfully for {evolvePokemonOutProto.ExpAwarded} xp"
+                        : $"Failed: {pokemon.PokemonId}. EvolvePokemonOutProto.Result was {evolvePokemonOutProto.Result}, stopping evolving {pokemon.PokemonId}"
+                    , LogLevel.Evolve);

                 await Task.Delay(1000);
             }
@@ -330,17 +345,13 @@ namespace PokemonGo.RocketAPI.Logic

             foreach (var duplicatePokemon in duplicatePokemons)
             {
-                //if (PokemonInfo.CalculatePokemonPerfection(duplicatePokemon) >= _clientSettings.KeepMinIVPercentage || duplicatePokemon.Cp > _clientSettings.KeepMinCP)
-                if (duplicatePokemon.Cp >= _clientSettings.KeepMinCP)
-                    continue;
-
                 var transfer = await _client.TransferPokemon(duplicatePokemon.Id);

                 _stats.IncreasePokemonsTransfered();
                 _stats.UpdateConsoleTitle(_inventory);

                 var bestPokemonOfType = await _inventory.GetHighestPokemonOfTypeByCP(duplicatePokemon);
-                Logger.Normal(ConsoleColor.DarkYellow, $"(TRANSFER) {duplicatePokemon.PokemonId} (CP {duplicatePokemon.Cp} | {PokemonInfo.CalculatePokemonPerfection(duplicatePokemon).ToString("0.00")} % perfect) | (Best: {bestPokemonOfType.Cp} CP | {PokemonInfo.CalculatePokemonPerfection(bestPokemonOfType).ToString("0.00")} % perfect)");
+                Logger.Write($"{duplicatePokemon.PokemonId} (CP {duplicatePokemon.Cp} | {PokemonInfo.CalculatePokemonPerfection(duplicatePokemon).ToString("0.00")} % perfect) | (Best: {bestPokemonOfType.Cp} CP | {PokemonInfo.CalculatePokemonPerfection(bestPokemonOfType).ToString("0.00")} % perfect)", LogLevel.Transfer);
                 await Task.Delay(100);
             }
         }
@@ -349,18 +360,19 @@ namespace PokemonGo.RocketAPI.Logic
         {
             var items = await _inventory.GetItemsToRecycle(_clientSettings);
             if (items != null && items.Any())
-                Logger.Normal(ConsoleColor.DarkMagenta, $"(RECYCLE) {items.Count()} Items:");
+                Logger.Write($"{items.Count()} {(items.Count() == 1 ? "Item" : "Items")}:", LogLevel.Recycling);

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

                 _stats.AddItemsRemoved(item.Count);
                 _stats.UpdateConsoleTitle(_inventory);

                 await Task.Delay(100);
             }
+            recycleCounter = 0;
         }

         private async Task<MiscEnums.Item> GetBestBall(WildPokemon pokemon)
@@ -454,7 +466,7 @@ namespace PokemonGo.RocketAPI.Logic
                     $" {playerName} | Level {playerStat.Level:0} - ({playerStat.Experience - playerStat.PrevLevelXp:0} / {playerStat.NextLevelXp - playerStat.PrevLevelXp:0} XP)";
                 Console.Title = message;
                 if (updateOnly == false)
-                    Logger.Normal(message);
+                    Logger.Write(message);
             }
             if (updateOnly == false)
                 await Task.Delay(5000);
@@ -462,15 +474,15 @@ namespace PokemonGo.RocketAPI.Logic

         private async Task DisplayHighests()
         {
-            Logger.Normal($"====== DisplayHighestsCP ======");
+            Logger.Write($"====== DisplayHighestsCP ======");
             var highestsPokemonCP = await _inventory.GetHighestsCP(5);
             foreach (var pokemon in highestsPokemonCP)
-                Logger.Normal($"# CP {pokemon.Cp.ToString().PadLeft(4, ' ')}/{PokemonInfo.CalculateMaxCP(pokemon).ToString().PadLeft(4, ' ')} | ({PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00")}% perfect)\t| Lvl {PokemonInfo.GetLevel(pokemon)}\t NAME: '{pokemon.PokemonId}'");
-            Logger.Normal($"====== DisplayHighestsPerfect ======");
+                Logger.Write($"# CP {pokemon.Cp.ToString().PadLeft(4, ' ')}/{PokemonInfo.CalculateMaxCP(pokemon).ToString().PadLeft(4, ' ')} | ({PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00")}% perfect)\t| Lvl {PokemonInfo.GetLevel(pokemon)}\t NAME: '{pokemon.PokemonId}'");
+            Logger.Write($"====== DisplayHighestsPerfect ======");
             var highestsPokemonPerfect = await _inventory.GetHighestsPerfect(5);
             foreach (var pokemon in highestsPokemonPerfect)
             {
-                Logger.Normal($"# CP {pokemon.Cp.ToString().PadLeft(4, ' ')}/{PokemonInfo.CalculateMaxCP(pokemon).ToString().PadLeft(4, ' ')} | ({PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00")}% perfect)\t| Lvl {PokemonInfo.GetLevel(pokemon)}\t NAME: '{pokemon.PokemonId}'");
+                Logger.Write($"# CP {pokemon.Cp.ToString().PadLeft(4, ' ')}/{PokemonInfo.CalculateMaxCP(pokemon).ToString().PadLeft(4, ' ')} | ({PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00")}% perfect)\t| Lvl {PokemonInfo.GetLevel(pokemon)}\t NAME: '{pokemon.PokemonId}'");
             }
         }

@@ -501,13 +513,13 @@ namespace PokemonGo.RocketAPI.Logic
                             var pokedata = string.Format("{0};{1};{2};{3}", POKENUMBER, NAME, CP, PERFECTION);
                             csvExportPokemonAll.AppendLine(pokedata);
                         }
-                        Logger.Normal($"Export all Pokemon to {path + filename}");
+                        Logger.Write($"Export all Pokemon to \\Export\\{filename}", LogLevel.Info);
                         File.WriteAllText(path + filename, csvExportPokemonAll.ToString());
                     }
                 }
                 catch
                 {
-                    Logger.Error("Export all Pokemons to CSV not possible. File seems be in use!");
+                    Logger.Write("Export all Pokemons to CSV not possible. File seems be in use!", LogLevel.Warning);
                 }
             }
         }
diff --git a/PokemonGo.RocketAPI.Logic/Navigation.cs b/PokemonGo.RocketAPI.Logic/Navigation.cs
index f2e217a..d7a97ee 100644
--- a/PokemonGo.RocketAPI.Logic/Navigation.cs
+++ b/PokemonGo.RocketAPI.Logic/Navigation.cs
@@ -5,6 +5,7 @@ using System.Device.Location;
 using System.Threading.Tasks;
 using PokemonGo.RocketAPI.GeneratedCode;
 using PokemonGo.RocketAPI.Logic.Utils;
+using PokemonGo.RocketAPI.Logging;

 #endregion

@@ -29,7 +30,7 @@ namespace PokemonGo.RocketAPI.Logic

             var sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
             var distanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
-            Logger.Normal(ConsoleColor.DarkCyan, $"(NAVIGATION) Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget / speedInMetersPerSecond:0.##} seconds!");
+            Logger.Write($"Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget / speedInMetersPerSecond:0.##} seconds!", LogLevel.Navigation);

             var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
             var nextWaypointDistance = speedInMetersPerSecond;
@@ -52,7 +53,7 @@ namespace PokemonGo.RocketAPI.Logic
                 {
                     if (speedInMetersPerSecond > SpeedDownTo)
                     {
-                        Logger.Normal(ConsoleColor.DarkCyan, $"(NAVIGATION) We are within 40 meters of the target. Speeding down to 10 km/h to not pass the target.");
+                        Logger.Write($"We are within 40 meters of the target. Speeding down to 10 km/h to not pass the target.", LogLevel.Navigation);
                         speedInMetersPerSecond = SpeedDownTo;
                     }
                 }
diff --git a/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs b/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs
index d682a60..b7f8638 100644
--- a/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs
+++ b/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs
@@ -19,6 +19,7 @@ namespace PokemonGo.RocketAPI.Logic.Utils
         public static int TotalStardust;
         public static string CurrentLevelInfos;
         public static int Currentlevel = -1;
+        public static string PlayerName;

         public static DateTime InitSessionDateTime = DateTime.Now;
         public static TimeSpan Duration = DateTime.Now - InitSessionDateTime;
@@ -39,6 +40,11 @@ namespace PokemonGo.RocketAPI.Logic.Utils
             return output;
         }

+        public void SetUsername(GetPlayerResponse profile)
+        {
+            PlayerName = profile.Profile.Username ?? "";
+        }
+
         public static double _getSessionRuntime()
         {
             return (DateTime.Now - InitSessionDateTime).TotalSeconds/3600;
@@ -84,8 +90,8 @@ namespace PokemonGo.RocketAPI.Logic.Utils
         {
             return
                 string.Format(
-                    "Runtime {0} - Lvl: {1:0} | EXP/H: {2:0} | P/H: {3:0} | Stardust: {4:0} | Transfered: {5:0} | Items Recycled: {6:0}",
-                    _getSessionRuntimeInTimeFormat(), CurrentLevelInfos, TotalExperience / _getSessionRuntime(),
+                    "{0} - Runtime {1} - Lvl: {2:0} | EXP/H: {3:0} | P/H: {4:0} | Stardust: {5:0} | Transfered: {6:0} | Items Recycled: {7:0}",
+                    PlayerName, _getSessionRuntimeInTimeFormat(), CurrentLevelInfos, TotalExperience / _getSessionRuntime(),
                     TotalPokemons / _getSessionRuntime(), TotalStardust, TotalPokemonsTransfered, TotalItemsRemoved);
         }

diff --git a/PokemonGo.RocketAPI/Client.cs b/PokemonGo.RocketAPI/Client.cs
index 501edfc..91488e9 100644
--- a/PokemonGo.RocketAPI/Client.cs
+++ b/PokemonGo.RocketAPI/Client.cs
@@ -13,6 +13,7 @@ using PokemonGo.RocketAPI.GeneratedCode;
 using PokemonGo.RocketAPI.Helpers;
 using PokemonGo.RocketAPI.Login;
 using static PokemonGo.RocketAPI.GeneratedCode.Response.Types;
+using PokemonGo.RocketAPI.Logging;

 #endregion

@@ -40,7 +41,6 @@ namespace PokemonGo.RocketAPI
             {
                 var latlngFromFile = File.ReadAllText(path + filename);
                 var latlng = latlngFromFile.Split(':');
-                double latitude, longitude;
                 if (latlng[0].Length != 0 && latlng[1].Length != 0)
                 {
                     try
@@ -55,13 +55,13 @@ namespace PokemonGo.RocketAPI
                         }
                         else
                         {
-                            Logger.Error("Coordinates in \"Configs\\Coords.txt\" file is invalid, using the default coordinates");
+                            Logger.Write("Coordinates in \"Configs\\Coords.txt\" file is invalid, using the default coordinates", LogLevel.Error);
                             SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
                         }
                     }
                     catch (FormatException)
                     {
-                        Logger.Error("Coordinates in \"Configs\\Coords.txt\" file is invalid, using the default coordinates");
+                        Logger.Write("Coordinates in \"Configs\\Coords.txt\" file is invalid, using the default coordinates", LogLevel.Error);
                         SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
                     }
                 }
@@ -72,7 +72,7 @@ namespace PokemonGo.RocketAPI
             }
             else
             {
-                Logger.Normal("Missing \"Configs\\Coords.txt\", using default settings for coordinates.");
+                Logger.Write("Missing \"Configs\\Coords.txt\", using default settings for coordinates.");
                 SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
             }

@@ -141,7 +141,7 @@ namespace PokemonGo.RocketAPI
                 var deviceCode = await GoogleLogin.GetDeviceCode();
                 tokenResponse = await GoogleLogin.GetAccessToken(deviceCode);
                 Settings.GoogleRefreshToken = tokenResponse?.refresh_token;
-                Logger.Normal("Refreshtoken " + tokenResponse?.refresh_token + " saved");
+                Logger.Write("Refreshtoken " + tokenResponse?.refresh_token + " saved", LogLevel.Info);
                 AccessToken = tokenResponse?.id_token;
             }

diff --git a/PokemonGo.RocketAPI/Helpers/Git.cs b/PokemonGo.RocketAPI/Helpers/Git.cs
index c2340e0..e42b1ab 100644
--- a/PokemonGo.RocketAPI/Helpers/Git.cs
+++ b/PokemonGo.RocketAPI/Helpers/Git.cs
@@ -1,5 +1,6 @@
 #region

+using PokemonGo.RocketAPI.Logging;
 using System;
 using System.Net;
 using System.Reflection;
@@ -28,13 +29,13 @@ namespace PokemonGo.RocketAPI.Helpers
                         $"{match.Groups[1]}.{match.Groups[2]}.{match.Groups[3]}.{match.Groups[4]}");
                 if (gitVersion <= Assembly.GetExecutingAssembly().GetName().Version)
                 {
-                    Logger.Normal(
+                    Logger.Write(
                         "Awesome! You have already got the newest version! " +
-                        Assembly.GetExecutingAssembly().GetName().Version);
+                        Assembly.GetExecutingAssembly().GetName().Version, LogLevel.Info);
                     return;
                 }

-                Logger.Normal(ConsoleColor.DarkGreen, "TThere is a new Version available: https://github.com/Spegeli/Pokemon-Go-Rocket-API");
+                Logger.Write("There is a new Version available: https://github.com/Spegeli/Pokemon-Go-Rocket-API", LogLevel.Info);
                 Thread.Sleep(1000);
             }
             catch (Exception)
diff --git a/PokemonGo.RocketAPI/Helpers/RetryHandler.cs b/PokemonGo.RocketAPI/Helpers/RetryHandler.cs
index b514eb7..ee1d61f 100644
--- a/PokemonGo.RocketAPI/Helpers/RetryHandler.cs
+++ b/PokemonGo.RocketAPI/Helpers/RetryHandler.cs
@@ -1,5 +1,6 @@
 #region

+using PokemonGo.RocketAPI.Logging;
 using System;
 using System.Net;
 using System.Net.Http;
@@ -35,7 +36,7 @@ namespace PokemonGo.RocketAPI.Helpers
                 }
                 catch (Exception ex)
                 {
-                    Logger.Error($"[#{i} of {MaxRetries}] retry request {request.RequestUri} - Error: {ex}");
+                    Logger.Write($"[#{i} of {MaxRetries}] retry request {request.RequestUri} - Error: {ex}", LogLevel.Error);
                     if (i >= MaxRetries) throw;
                     await Task.Delay(1000, cancellationToken);
                 }
diff --git a/PokemonGo.RocketAPI/Logging/ConsoleLogger.cs b/PokemonGo.RocketAPI/Logging/ConsoleLogger.cs
deleted file mode 100644
index 9118371..0000000
--- a/PokemonGo.RocketAPI/Logging/ConsoleLogger.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-#region
-
-using System;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Logging
-{
-	/// <summary>
-	/// The ConsoleLogger is a simple logger which writes all logs to the Console.
-	/// </summary>
-	public class ConsoleLogger : ILogger
-	{
-		private LogLevel maxLogLevel;
-
-		/// <summary>
-		/// To create a ConsoleLogger, we must define a maximum log level.
-		/// All levels above won't be logged.
-		/// </summary>
-		/// <param name="maxLogLevel"></param>
-		public ConsoleLogger(LogLevel maxLogLevel)
-		{
-			this.maxLogLevel = maxLogLevel;
-		}
-
-		/// <summary>
-		/// Log a specific message by LogLevel. Won't log if the LogLevel is greater than the maxLogLevel set.
-		/// </summary>
-		/// <param name="message">The message to log. The current time will be prepended.</param>
-		/// <param name="level">Optional. Default <see cref="LogLevel.Info"/>.</param>
-		public void Write(string message, LogLevel level = LogLevel.Info)
-		{
-			if (level > maxLogLevel)
-				return;
-
-			Console.WriteLine($"[{ DateTime.Now.ToString("HH:mm:ss")}] { message}");
-		}
-	}
-}
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/Logging/ILogger.cs b/PokemonGo.RocketAPI/Logging/ILogger.cs
deleted file mode 100644
index e040fdd..0000000
--- a/PokemonGo.RocketAPI/Logging/ILogger.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-#region
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Logging
-{
-	/// <summary>
-	/// All loggers must implement this interface.
-	/// </summary>
-	public interface ILogger
-	{
-		/// <summary>
-		/// Log a specific message by LogLevel.
-		/// </summary>
-		/// <param name="message">The message to log.</param>
-		/// <param name="level">Optional. Default <see cref="LogLevel.Info"/>.</param>
-		void Write(string message, LogLevel level = LogLevel.Info);
-	}
-}
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/Logging/Logger.cs b/PokemonGo.RocketAPI/Logging/Logger.cs
index e3a86b3..67dd8dc 100644
--- a/PokemonGo.RocketAPI/Logging/Logger.cs
+++ b/PokemonGo.RocketAPI/Logging/Logger.cs
@@ -2,52 +2,29 @@

 using System;
 using System.IO;
-using PokemonGo.RocketAPI.Logging;

 #endregion


-namespace PokemonGo.RocketAPI
+namespace PokemonGo.RocketAPI.Logging
 {
-    public static class LogColor
-    {
-        public static ConsoleColor Black = ConsoleColor.Black;
-        public static ConsoleColor Blue = ConsoleColor.Blue;
-        public static ConsoleColor Cyan = ConsoleColor.Cyan;
-        public static ConsoleColor DarkBlue = ConsoleColor.DarkBlue;
-        public static ConsoleColor DarkCyan = ConsoleColor.DarkCyan;
-        public static ConsoleColor DarkGray = ConsoleColor.DarkGray;
-        public static ConsoleColor DarkGreen = ConsoleColor.DarkGreen;
-        public static ConsoleColor DarkMagenta = ConsoleColor.DarkMagenta;
-        public static ConsoleColor DarkRed = ConsoleColor.DarkRed;
-        public static ConsoleColor DarkYellow = ConsoleColor.DarkYellow;
-
-        public static ConsoleColor Gray = ConsoleColor.Gray;
-        public static ConsoleColor Green = ConsoleColor.Green;
-        public static ConsoleColor Magenta = ConsoleColor.Magenta;
-        public static ConsoleColor Error = ConsoleColor.Red;
-        public static ConsoleColor White = ConsoleColor.White;
-        public static ConsoleColor Yellow = ConsoleColor.Yellow;
-    }
-
     /// <summary>
     /// Generic logger which can be used across the projects.
     /// Logger should be set to properly log.
     /// </summary>
-    public static class Logger
-	{
+    public class Logger
+    {
         static string _currentFile = string.Empty;
         static string path = Directory.GetCurrentDirectory() + "\\Logs\\";

-        private static ILogger logger;
+        private static Logger _logger;

         /// <summary>
         /// Set the logger. All future requests to <see cref="Write(string, LogLevel)"/> will use that logger, any old will be unset.
         /// </summary>
         /// <param name="logger"></param>
-        public static void SetLogger(ILogger logger)
+        public static void SetLogger()
 		{
-			Logger.logger = logger;
             if (!Directory.Exists(path))
             {
                 DirectoryInfo di = Directory.CreateDirectory(path);
@@ -57,47 +34,69 @@ namespace PokemonGo.RocketAPI
         }

         /// <summary>
-        /// write message to log window and file
-        /// </summary>
-        /// <param name="message">message text</param>
-        public static void Normal(string message)
-        {
-            if (logger == null)
-                return;
-            logger.Write(message);
-            Log(String.Concat($"[{DateTime.Now.ToString("HH:mm:ss")}] ", message));
-        }
-
-        /// <summary>
-        /// Log a specific message to the logger setup by <see cref="SetLogger(ILogger)"/> .
+        ///     Log a specific message to the logger setup by <see cref="SetLogger(ILogger)" /> .
         /// </summary>
         /// <param name="message">The message to log.</param>
-        /// <param name="level">Optional level to log. Default <see cref="LogLevel.Info"/>.</param>
-        public static void Normal(ConsoleColor color, string message)
-		{
-			if (logger == null)
-				return;
-            ConsoleColor originalColor = System.Console.ForegroundColor;
-            System.Console.ForegroundColor = color;
-            logger.Write(message);
-            System.Console.ForegroundColor = originalColor;
-            Log(String.Concat($"[{DateTime.Now.ToString("HH:mm:ss")}] ", message));
-        }
-
-        /// <summary>
-        /// Log a specific message to the logger setup by <see cref="SetLogger(ILogger)"/> .
-        /// </summary>
-        /// <param name="message">The message to log.</param>
-        /// <param name="level">Optional level to log. Default <see cref="LogLevel.Info"/>.</param>
-        public static void Error(string message)
+        /// <param name="level">Optional level to log. Default <see cref="LogLevel.Info" />.</param>
+        /// <param name="color">Optional. Default is automatic color.</param>
+        public static void Write(string message, LogLevel level = LogLevel.None, ConsoleColor color = ConsoleColor.White)
         {
-            if (logger == null)
-                return;
-            ConsoleColor originalColor = System.Console.ForegroundColor;
-            System.Console.ForegroundColor = ConsoleColor.Red;
-            logger.Write(message);
-            System.Console.ForegroundColor = originalColor;
-            Log(String.Concat($"[{DateTime.Now.ToString("HH:mm:ss")}] ", message));
+            switch (level)
+            {
+                case LogLevel.Info:
+                    System.Console.ForegroundColor = ConsoleColor.DarkGreen;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (INFO) {message}");
+                    break;
+                case LogLevel.Warning:
+                    System.Console.ForegroundColor = ConsoleColor.DarkYellow;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (ATTENTION) {message}");
+                    break;
+                case LogLevel.Error:
+                    System.Console.ForegroundColor = ConsoleColor.Red;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (ERROR) {message}");
+                    break;
+                case LogLevel.Debug:
+                    System.Console.ForegroundColor = ConsoleColor.Gray;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (DEBUG) {message}");
+                    break;
+                case LogLevel.Navigation:
+                    System.Console.ForegroundColor = ConsoleColor.DarkCyan;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (NAVIGATION) {message}");
+                    break;
+                case LogLevel.Pokestop:
+                    System.Console.ForegroundColor = ConsoleColor.Cyan;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (POKESTOP) {message}");
+                    break;
+                case LogLevel.Pokemon:
+                    System.Console.ForegroundColor = ConsoleColor.Yellow;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (PKMN) {message}");
+                    break;
+                case LogLevel.Transfer:
+                    System.Console.ForegroundColor = ConsoleColor.White;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (TRANSFER) {message}");
+                    break;
+                case LogLevel.Evolve:
+                    System.Console.ForegroundColor = ConsoleColor.White;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (EVOLVE) {message}");
+                    break;
+                case LogLevel.Berry:
+                    System.Console.ForegroundColor = ConsoleColor.White;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (BERRY) {message}");
+                    break;
+                case LogLevel.Recycling:
+                    System.Console.ForegroundColor = ConsoleColor.DarkMagenta;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (RECYCLING) {message}");
+                    break;
+                case LogLevel.None:
+                    System.Console.ForegroundColor = color;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] {message}");
+                    break;
+                default:
+                    System.Console.ForegroundColor = ConsoleColor.White;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] {message}");
+                    break;
+            }
+            Log(string.Concat($"[{DateTime.Now.ToString("HH:mm:ss")}] ", message));
         }

         private static void Log(string message)
@@ -111,12 +110,19 @@ namespace PokemonGo.RocketAPI
         }
     }

-	public enum LogLevel
-	{
-		None = 0,
-		Error = 1,
-		Warning = 2,
-		Info = 3,
-		Debug = 4
-	}
+    public enum LogLevel
+    {
+        None = 0,
+        Info = 1,
+        Warning = 2,
+        Error = 3,
+        Debug = 4,
+        Navigation = 5,
+        Pokestop = 6,
+        Pokemon = 7,
+        Transfer = 8,
+        Evolve = 9,
+        Berry = 10,
+        Recycling = 11
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/Login/GoogleLogin.cs b/PokemonGo.RocketAPI/Login/GoogleLogin.cs
index cc40102..2b881c1 100644
--- a/PokemonGo.RocketAPI/Login/GoogleLogin.cs
+++ b/PokemonGo.RocketAPI/Login/GoogleLogin.cs
@@ -7,6 +7,7 @@ using PokemonGo.RocketAPI.Helpers;
 using System.Windows.Forms;
 using System.Diagnostics;
 using System;
+using PokemonGo.RocketAPI.Logging;

 #endregion

@@ -29,13 +30,13 @@ namespace PokemonGo.RocketAPI.Login
                 tokenResponse = await PollSubmittedToken(deviceCode.device_code);
             } while (tokenResponse.access_token == null || tokenResponse.refresh_token == null);

-            Logger.Normal($"Save the refresh token in your settings: {tokenResponse.refresh_token}");
+            Logger.Write($"Save the refresh token in your settings: {tokenResponse.refresh_token}");
             await Task.Delay(2000);
             Thread thread = new Thread(() => Clipboard.SetText(tokenResponse.refresh_token));
             thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
             thread.Start();
             thread.Join();
-            Logger.Normal("The Token is in your Clipboard!");
+            Logger.Write("The Token is in your Clipboard!");

             return tokenResponse;
         }
@@ -46,7 +47,7 @@ namespace PokemonGo.RocketAPI.Login
                 new KeyValuePair<string, string>("client_id", ClientId),
                 new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));

-            Logger.Normal($"Please visit {deviceCode.verification_url} and enter {deviceCode.user_code}");
+            Logger.Write($"Please visit {deviceCode.verification_url} and enter {deviceCode.user_code}");
             await Task.Delay(2000);
             Process.Start(@"http://www.google.com/device");
             try
@@ -56,11 +57,11 @@ namespace PokemonGo.RocketAPI.Login
                 thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
                 thread.Start();
                 thread.Join();
-                Logger.Normal("The Token is in your Clipboard!");
+                Logger.Write("The Token is in your Clipboard!");
             }
             catch (Exception)
             {
-                Logger.Error("Couldnt copy to clipboard, do it manually");
+                Logger.Write("Couldnt copy to clipboard, do it manually", LogLevel.Warning);
             }

             return deviceCode;
diff --git a/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj b/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
index dc246d9..4de48ff 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.163</AssemblyVersion>
+    <AssemblyVersion>2016.7.23.183</AssemblyVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -102,8 +102,6 @@
     <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" />
diff --git a/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs b/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
index 483916f..aa83ddd 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.163")]
+[assembly: AssemblyVersion("2016.7.23.184")]
 [assembly: AssemblyFileVersion("1.0.0.0")]
You may download the files in Public Git.