public static async Task Execute()
        {
            var currentAmountOfLuckyEggs = await Inventory.GetItemAmountByType(ItemId.ItemLuckyEgg);

            if (currentAmountOfLuckyEggs <= 0 || _lastLuckyEggTime.AddMinutes(30).Ticks > DateTime.Now.Ticks)
            {
                return;
            }

            var UseEgg = await Logic._client.Inventory.UseItemXpBoost();

            if (UseEgg.Result == UseItemXpBoostResponse.Types.Result.ErrorXpBoostAlreadyActive)
            {
                return;
            }

            if (UseEgg.Result == UseItemXpBoostResponse.Types.Result.Success)
            {
                _lastLuckyEggTime = DateTime.Now;
                Logger.Write($"Used Lucky Egg [Remaining: {currentAmountOfLuckyEggs - 1}]", LogLevel.Egg);
            }
            else if (UseEgg.Result == UseItemXpBoostResponse.Types.Result.ErrorNoItemsRemaining)
            {
                Logger.Write($"No Eggs Available", LogLevel.Debug);
            }
            else if (UseEgg.Result == UseItemXpBoostResponse.Types.Result.ErrorXpBoostAlreadyActive || (UseEgg.AppliedItems == null))
            {
                Logger.Write($"Lucky Egg Already Active", LogLevel.Debug);
            }
        }
        public static async Task Execute()
        {
            await Inventory.GetCachedInventory(true);

            var pokemonToEvolve = await Inventory.GetPokemonToEvolve(Logic._client.Settings.PrioritizeIVOverCP, Logic._client.Settings.PokemonToEvolve);

            if (pokemonToEvolve == null || !pokemonToEvolve.Any())
            {
                return;
            }

            Logger.Write($"Found {pokemonToEvolve.Count()} Pokemon for Evolve:", LogLevel.Debug);
            foreach (var pokemon in pokemonToEvolve)
            {
                var evolvePokemonOutProto = await Logic._client.Inventory.EvolvePokemon(pokemon.Id);

                await Inventory.GetCachedInventory(true);

                Logger.Write(evolvePokemonOutProto.Result == EvolvePokemonResponse.Types.Result.Success
                        ? $"{pokemon.PokemonId} [CP: {pokemon.Cp}/{PokemonInfo.CalculateMaxCp(pokemon)} | IV: { PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00")}% perfect] | received XP {evolvePokemonOutProto.ExperienceAwarded}"
                        : $"Failed: {pokemon.PokemonId}. EvolvePokemonOutProto.Result was {evolvePokemonOutProto.Result}, stopping evolving {pokemon.PokemonId}"
                             , LogLevel.Evolve);

                if (evolvePokemonOutProto.Result == EvolvePokemonResponse.Types.Result.Success)
                {
                    BotStats.ExperienceThisSession += evolvePokemonOutProto.ExperienceAwarded;
                }
            }
            await BotStats.GetPokeDexCount();

            BotStats.UpdateConsoleTitle();
        }
        public static async Task Execute()
        {
            var currentAmountOfIncense = await Inventory.GetItemAmountByType(ItemId.ItemIncenseOrdinary);

            if (currentAmountOfIncense <= 0 || _lastIncenseTime.AddMinutes(30).Ticks > DateTime.Now.Ticks)
            {
                return;
            }

            var UseIncense = await Logic._client.Inventory.UseIncense(ItemId.ItemIncenseOrdinary);

            if (UseIncense.Result == UseIncenseResponse.Types.Result.IncenseAlreadyActive)
            {
                return;
            }

            if (UseIncense.Result == UseIncenseResponse.Types.Result.Success)
            {
                _lastIncenseTime = DateTime.Now;
                Logger.Write($"Used Incense [Remaining: {currentAmountOfIncense - 1}]", LogLevel.Incense);
            }
            else if (UseIncense.Result == UseIncenseResponse.Types.Result.NoneInInventory)
            {
                Logger.Write($"No Incense Available", LogLevel.Debug);
            }
            else if (UseIncense.Result == UseIncenseResponse.Types.Result.IncenseAlreadyActive || (UseIncense.AppliedIncense == null))
            {
                Logger.Write($"Incense Already Active", LogLevel.Debug);
            }
        }
        public static async Task Execute()
        {
            var tracks = GetGpxTracks();

            for (var curTrk = 0; curTrk < tracks.Count; curTrk++)
            {
                var track         = tracks.ElementAt(curTrk);
                var trackSegments = track.Segments;
                for (var curTrkSeg = 0; curTrkSeg < trackSegments.Count; curTrkSeg++)
                {
                    var trackPoints = track.Segments.ElementAt(curTrkSeg).TrackPoints;
                    for (var curTrkPt = 0; curTrkPt < trackPoints.Count; curTrkPt++)
                    {
                        var nextPoint     = trackPoints.ElementAt(curTrkPt);
                        var distanceCheck = LocationUtils.CalculateDistanceInMeters(Logic._client.CurrentLatitude,
                                                                                    Logic._client.CurrentLongitude, Convert.ToDouble(nextPoint.Lat),
                                                                                    Convert.ToDouble(nextPoint.Lon));

                        if (distanceCheck > 5000)
                        {
                            Logger.Write(
                                $"Your Target destination of {nextPoint.Lat}, {nextPoint.Lon} is too far from your current position of {Logic._client.CurrentLatitude}, {Logic._client.CurrentLongitude} - Distance: {distanceCheck:0.##}",
                                LogLevel.Error);
                            break;
                        }

                        Logger.Write($"Your Target destination is {nextPoint.Lat}, {nextPoint.Lon} your location is {Logic._client.CurrentLatitude}, {Logic._client.CurrentLongitude} - Distance: {distanceCheck:0.##}", LogLevel.Debug);

                        if (Logic._client.Settings.UseCSVExport && ExportPokemonToCsv._lastExportTime.AddMinutes(Logic._client.Settings.CSVExportInMinutes).Ticks < DateTime.Now.Ticks)
                        {
                            var _playerProfile = await Logic._client.Player.GetPlayer();

                            await ExportPokemonToCsv.Execute(_playerProfile.PlayerData);
                        }
                        if (Logic._client.Settings.UseLuckyEggs)
                        {
                            await UseLuckyEggTask.Execute();
                        }
                        if (Logic._client.Settings.CatchIncensePokemon)
                        {
                            await UseIncenseTask.Execute();
                        }

                        await
                        Navigation.HumanPathWalking(trackPoints.ElementAt(curTrkPt),
                                                    async() =>
                        {
                            //await CatchNearbyPokemonsTask.Execute(session, cancellationToken);
                            // Catch normal map Pokemon
                            await CatchMapPokemonsTask.Execute();
                            //Catch Pokestops on the Way
                            await UseNearbyPokestopsTask.Execute();
                            //Catch Incense Pokemon
                            await CatchIncensePokemonsTask.Execute();
                            return(true);
                        });
                    } //end trkpts
                }     //end trksegs
            }         //end tracks
        }
Example #5
0
        public static void CheckVersion()
        {
            try
            {
                var match =
                    new Regex(
                        @"\[assembly\: AssemblyVersion\(""(\d{1,})\.(\d{1,})\.(\d{1,})\.(\d{1,})""\)\]")
                    .Match(DownloadServerVersion());

                if (!match.Success)
                {
                    return;
                }
                var gitVersion =
                    new Version(
                        $"{match.Groups[1]}.{match.Groups[2]}.{match.Groups[3]}.{match.Groups[4]}");

                if (gitVersion <= Assembly.GetExecutingAssembly().GetName().Version)
                {
                    Logger.Write(
                        "Awesome! You have already got the newest version! " +
                        Assembly.GetExecutingAssembly().GetName().Version, LogLevel.Info);
                    return;
                }

                Logger.Write("There is a new Version available: https://github.com/Spegeli/PokemoGoBot-GottaCatchEmAll", LogLevel.Info);
                Logger.Write($"GitHub Version: {gitVersion} | Local Version: {CurrentVersion}", LogLevel.Info);
                Thread.Sleep(1000);
            }
            catch (Exception)
            {
                // ignored
            }
        }
Example #6
0
        public static async Task Execute()
        {
            await Inventory.GetCachedInventory(true);

            var pokemonToTransfer = await Inventory.GetPokemonToTransfer(Logic._clientSettings.NotTransferPokemonsThatCanEvolve, Logic._clientSettings.PrioritizeIVOverCP, Logic._clientSettings.PokemonToNotTransfer);

            if (pokemonToTransfer == null || !pokemonToTransfer.Any())
            {
                return;
            }

            Logger.Write($"Found {pokemonToTransfer.Count()} Pokemon for Transfer:", LogLevel.Debug);
            foreach (var pokemon in pokemonToTransfer)
            {
                await Logic._client.Inventory.TransferPokemon(pokemon.Id);

                await Inventory.GetCachedInventory(true);

                var myPokemonSettings = await Inventory.GetPokemonSettings();

                var pokemonSettings   = myPokemonSettings.ToList();
                var myPokemonFamilies = await Inventory.GetPokemonFamilies();

                var pokemonFamilies = myPokemonFamilies.ToArray();
                var settings        = pokemonSettings.Single(x => x.PokemonId == pokemon.PokemonId);
                var familyCandy     = pokemonFamilies.Single(x => settings.FamilyId == x.FamilyId);
                var familyCandies   = $"{familyCandy.Candy_}";

                BotStats.PokemonTransferedThisSession += 1;

                var bestPokemonOfType = Logic._client.Settings.PrioritizeIVOverCP
                    ? await Inventory.GetHighestPokemonOfTypeByIv(pokemon)
                    : await Inventory.GetHighestPokemonOfTypeByCp(pokemon);

                var bestPokemonInfo = "NONE";
                if (bestPokemonOfType != null)
                {
                    bestPokemonInfo = $"CP: {bestPokemonOfType.Cp}/{PokemonInfo.CalculateMaxCp(bestPokemonOfType)} | IV: {PokemonInfo.CalculatePokemonPerfection(bestPokemonOfType).ToString("0.00")}% perfect";
                }

                Logger.Write($"{pokemon.PokemonId} [CP: {pokemon.Cp}/{PokemonInfo.CalculateMaxCp(pokemon)} | IV: { PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00")}% perfect] | Best: [{bestPokemonInfo}] | Family Candies: {familyCandies}", LogLevel.Transfer);
            }

            await BotStats.GetPokemonCount();

            BotStats.UpdateConsoleTitle();
        }
        private static async Task UseBerry(ulong encounterId, string spawnPointId)
        {
            await Inventory.GetCachedInventory(true);

            var inventoryitems = await Inventory.GetItems();

            var berry = inventoryitems.FirstOrDefault(p => p.ItemId == ItemId.ItemRazzBerry);

            if (berry == null || berry.Count <= 0)
            {
                return;
            }

            await Logic._client.Encounter.UseCaptureItem(encounterId, ItemId.ItemRazzBerry, spawnPointId);

            berry.Count -= 1;
            Logger.Write($"Used Razz Berry [Remaining: {berry.Count}]", LogLevel.Berry);
        }
        public static async Task Execute(FortData currentFortData)
        {
            Logger.Write("Looking for lured Pokemon...", LogLevel.Debug);

            var fortId    = currentFortData.Id;
            var pokemonId = currentFortData.LureInfo.ActivePokemonId;

            if (Logic._client.Settings.UsePokemonToNotCatchList &&
                Logic._client.Settings.PokemonToNotCatch.Contains(pokemonId))
            {
                Logger.Write($"Ignore Pokemon - {pokemonId} - is on ToNotCatch List", LogLevel.Debug);
                return;
            }

            var encounterId = currentFortData.LureInfo.EncounterId;

            var encounter = await Logic._client.Encounter.EncounterLurePokemon(encounterId, fortId);

            Logger.Write($"fortId: {fortId}", LogLevel.Debug);
            Logger.Write($"pokemonId: {pokemonId}", LogLevel.Debug);
            Logger.Write($"encounterId: {encounterId}", LogLevel.Debug);
            Logger.Write($"encounter: {encounter}", LogLevel.Debug);

            if (encounter.Result == DiskEncounterResponse.Types.Result.Success)
            {
                await CatchPokemonTask.Execute(encounter, null, currentFortData, encounterId);
            }
            else
            {
                if (encounter.Result.ToString().Contains("NotAvailable"))
                {
                    return;
                }
                Logger.Write($"Encounter problem: Lure Pokemon {encounter.Result}", LogLevel.Warning);
            }
        }
        public static async Task Execute()
        {
            await Inventory.GetCachedInventory(true);

            var items = await Inventory.GetItemsToRecycle(Logic._clientSettings);

            if (items == null || !items.Any())
            {
                return;
            }

            Logger.Write($"Found {items.Count()} Recyclable {(items.Count() == 1 ? "Item" : "Items")}:", LogLevel.Debug);
            foreach (var item in items)
            {
                await Logic._client.Inventory.RecycleItem(item.ItemId, item.Count);

                Logger.Write($"{item.Count}x {item.ItemId}", LogLevel.Recycling);

                BotStats.ItemsRemovedThisSession += item.Count;
            }

            BotStats.UpdateConsoleTitle();
            _recycleCounter = 0;
        }
        public GpxReader(string xml)
        {
            if (xml.Equals(""))
            {
                return;
            }
            _gpx.LoadXml(xml);
            if (_gpx.DocumentElement == null || !_gpx.DocumentElement.Name.Equals("gpx"))
            {
                return;
            }
            var gpxNodes = _gpx.GetElementsByTagName("gpx")[0].ChildNodes;

            foreach (XmlNode node in gpxNodes)
            {
                switch (node.Name)
                {
                case "name":
                    Name = node.InnerText;
                    break;

                case "desc":
                    Description = node.InnerText;
                    break;

                case "author":
                    Author = node.InnerText;
                    break;

                case "email":
                    EMail = node.InnerText;
                    break;

                case "time":
                    Time = node.InnerText;
                    break;

                case "keywords":
                    KeyWords = node.InnerText;
                    break;

                case "bounds":
                    Bounds = new GpsBoundary();
                    if (node.Attributes != null)
                    {
                        foreach (XmlAttribute att in node.Attributes)
                        {
                            switch (att.Name)
                            {
                            case "minlat":
                                Bounds.Min.Lat = att.Value;
                                break;

                            case "minlon":
                                Bounds.Min.Lon = att.Value;
                                break;

                            case "maxlat":
                                Bounds.Max.Lat = att.Value;
                                break;

                            case "maxlon":
                                Bounds.Max.Lon = att.Value;
                                break;
                            }
                        }
                    }
                    break;

                case "wpt":
                    var newWayPoint = new Wpt(node);
                    WayPoints.Add(newWayPoint);
                    break;

                case "rte":
                    var newRoute = new Rte(node);
                    Routes.Add(newRoute);
                    break;

                case "trk":
                    var track = new Trk(node);
                    Tracks.Add(track);
                    break;

                case "url":
                    Url = node.InnerText;
                    break;

                case "urlname":
                    UrlName = node.InnerText;
                    break;

                case "topografix:active_point":
                case "topografix:map":
                    break;

                default:
                    Logger.Write("Unhandled data in GPX file, attempting to skip.", LogLevel.Info);
                    break;
                }
            }
        }
        public static async Task Execute(PlayerData player, string filename = "PokeList.csv")
        {
            if (player == null)
            {
                return;
            }
            var stats = await Inventory.GetPlayerStats();

            var stat = stats.FirstOrDefault();

            if (stat == null)
            {
                return;
            }

            if (!Directory.Exists(_exportPath))
            {
                Directory.CreateDirectory(_exportPath);
            }
            if (Directory.Exists(_exportPath))
            {
                try
                {
                    var pokelistFile = Path.Combine(_exportPath, $"Profile_{player.Username}_{filename}");
                    if (File.Exists(pokelistFile))
                    {
                        File.Delete(pokelistFile);
                    }

                    CsvExport myExport   = new CsvExport();
                    var       allPokemon = await Inventory.GetHighestsIv();

                    var myPokemonSettings = await Inventory.GetPokemonSettings();

                    var pokemonSettings   = myPokemonSettings.ToList();
                    var myPokemonFamilies = await Inventory.GetPokemonFamilies();

                    var pokemonFamilies = myPokemonFamilies.ToArray();
                    var trainerLevel    = stat.Level;
                    foreach (var pokemon in allPokemon)
                    {
                        var toEncode = $"{(int)pokemon.PokemonId}" + "," + trainerLevel + "," + PokemonInfo.GetLevel(pokemon) + "," + pokemon.Cp + "," + pokemon.Stamina;
                        //Generate base64 code to make it viewable here http://poke.isitin.org/#MTUwLDIzLDE3LDE5MDIsMTE4
                        var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(toEncode));

                        var settings       = pokemonSettings.Single(x => x.PokemonId == pokemon.PokemonId);
                        var familiecandies = pokemonFamilies.Single(x => settings.FamilyId == x.FamilyId).Candy_;

                        myExport.AddRow();
                        myExport["PokemonID"]          = (int)pokemon.PokemonId;
                        myExport["Name"]               = pokemon.PokemonId;
                        myExport["NickName"]           = pokemon.Nickname;
                        myExport["Level"]              = PokemonInfo.GetLevel(pokemon).ToString("0.0");
                        myExport["CP"]                 = pokemon.Cp;
                        myExport["MaxCP"]              = PokemonInfo.CalculateMaxCp(pokemon);
                        myExport["IV Perfection in %"] = PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00");
                        myExport["Attack 1"]           = pokemon.Move1;
                        myExport["Attack 2"]           = pokemon.Move2;
                        myExport["HP"]                 = pokemon.Stamina;
                        myExport["Attk"]               = pokemon.IndividualAttack;
                        myExport["Def"]                = pokemon.IndividualDefense;
                        myExport["Stamina"]            = pokemon.IndividualStamina;
                        myExport["Familie Candies"]    = familiecandies;
                        myExport["IsInGym"]            = pokemon.DeployedFortId != string.Empty ? "Yes" : "No";
                        myExport["IsFavorite"]         = pokemon.Favorite != 0 ? "Yes" : "No";
                        myExport["previewLink"]        = $"http://poke.isitin.org/#{encoded}";
                    }
                    myExport.ExportToFile(pokelistFile);
                    Logger.Write($"Export Player Infos and all Pokemon to \"\\Export\\Profile_{player.Username}_{filename}\"", LogLevel.Info);
                }
                catch
                {
                    Logger.Write("Export Player Infos and all Pokemons to CSV not possible. File seems be in use!", LogLevel.Warning);
                }
                _lastExportTime = DateTime.Now;
                Logger.Write($"Next Export in {Logic._client.Settings.CSVExportInMinutes} Minutes", LogLevel.Info);
            }
        }
        public static async Task Execute(dynamic encounter, MapPokemon pokemon, FortData currentFortData = null, ulong encounterId = 0)
        {
            // If the encounter is null nothing will work below, so exit now
            if (encounter == null)
            {
                return;
            }
            float probability = encounter.CaptureProbability?.CaptureProbability_[0];

            var catchType   = encounter is EncounterResponse ? "Normal" : encounter is DiskEncounterResponse ? "Lure" : "Incense";
            var Id          = encounter is EncounterResponse ? pokemon.PokemonId : encounter?.PokemonData.PokemonId;
            var Level       = PokemonInfo.GetLevel(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData);
            var Cp          = encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData?.Cp : encounter?.PokemonData?.Cp ?? 0;
            var MaxCp       = PokemonInfo.CalculateMaxCp(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData);
            var Iv          = PokemonInfo.CalculatePokemonPerfection(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData);
            var Probability = Math.Round(probability * 100, 2);
            var distance    = LocationUtils.CalculateDistanceInMeters(Logic._client.CurrentLatitude,
                                                                      Logic._client.CurrentLongitude,
                                                                      encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Latitude : currentFortData.Latitude,
                                                                      encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Longitude : currentFortData.Longitude);

            if (!float.IsNaN(probability) && probability < 0.35)
            {
                await
                UseBerry(encounter is EncounterResponse || encounter is IncenseEncounterResponse?pokemon.EncounterId : encounterId,
                         encounter is EncounterResponse || encounter is IncenseEncounterResponse?pokemon.SpawnPointId : currentFortData?.Id);
            }

            CatchPokemonResponse caughtPokemonResponse;
            var attemptCounter = 1;

            do
            {
                var pokeball = await GetBestBall(encounter, probability);

                if (pokeball == ItemId.ItemUnknown)
                {
                    Logger.Write($"You don't own any Pokeballs :( - We missed a {Id} with CP {Cp}", LogLevel.Warning);
                    return;
                }

                caughtPokemonResponse =
                    await Logic._client.Encounter.CatchPokemon(
                        encounter is EncounterResponse || encounter is IncenseEncounterResponse?pokemon.EncounterId : encounterId,
                        encounter is EncounterResponse || encounter is IncenseEncounterResponse?pokemon.SpawnPointId : currentFortData.Id, pokeball);

                if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
                {
                    BotStats.ExperienceThisSession    += caughtPokemonResponse.CaptureAward.Xp.Sum();
                    BotStats.PokemonCaughtThisSession += 1;
                    await BotStats.GetPokeDexCount();

                    await BotStats.GetPokemonCount();

                    var profile = await Logic._client.Player.GetPlayer();

                    BotStats.TotalStardust = profile.PlayerData.Currencies.ToArray()[1].Amount;
                    BotStats.UpdateConsoleTitle();
                }

                if (encounter?.CaptureProbability?.CaptureProbability_ != null)
                {
                    Func <ItemId, string> returnRealBallName = a =>
                    {
                        switch (a)
                        {
                        case ItemId.ItemPokeBall:
                            return("Poke");

                        case ItemId.ItemGreatBall:
                            return("Great");

                        case ItemId.ItemUltraBall:
                            return("Ultra");

                        case ItemId.ItemMasterBall:
                            return("Master");

                        default:
                            return("Unknown");
                        }
                    };

                    var catchStatus = attemptCounter > 1
                        ? $"{caughtPokemonResponse.Status} Attempt #{attemptCounter}"
                        : $"{caughtPokemonResponse.Status}";

                    var receivedXp = caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess
                        ? $"and received XP {caughtPokemonResponse.CaptureAward.Xp.Sum()}"
                        : $"";

                    await Inventory.GetCachedInventory(true);

                    var BallAmount = await Inventory.GetItemAmountByType(pokeball);

                    Logger.Write($"({catchStatus} / {catchType}) | {Id} - Lvl {Level} [CP {Cp}/{MaxCp} | IV: {Iv.ToString("0.00")}% perfect] | Chance: {Probability} | {distance:0.##}m dist | with a {returnRealBallName(pokeball)}Ball [Remaining: {BallAmount}] {receivedXp}", LogLevel.Pokemon);
                }

                attemptCounter++;
            }while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed || caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape);
        }
        public static async Task Execute()
        {
            var distanceFromStart = LocationUtils.CalculateDistanceInMeters(
                Logic._client.Settings.DefaultLatitude, Logic._client.Settings.DefaultLongitude,
                Logic._client.CurrentLatitude, Logic._client.CurrentLongitude);

            // Edge case for when the client somehow ends up outside the defined radius
            if (Logic._client.Settings.MaxTravelDistanceInMeters != 0 &&
                distanceFromStart > Logic._client.Settings.MaxTravelDistanceInMeters)
            {
                Logger.Write(
                    $"You're outside of your defined radius! Walking to Default Coords ({distanceFromStart:0.##}m away). Is your LastCoords.ini file correct?",
                    LogLevel.Warning);
                await Navigation.HumanLikeWalking(
                    new GeoUtils(Logic._client.Settings.DefaultLatitude, Logic._client.Settings.DefaultLongitude),
                    async() =>
                {
                    // Catch normal map Pokemon
                    await CatchMapPokemonsTask.Execute();
                    //Catch Incense Pokemon
                    await CatchIncensePokemonsTask.Execute();
                    return(true);
                });
            }

            var pokestops = await Inventory.GetPokestops();

            if (pokestops == null || !pokestops.Any())
            {
                Logger.Write(
                    "No usable PokeStops found in your area. Reasons: Softbanned - Server Issues - MaxTravelDistanceInMeters too small",
                    LogLevel.Warning);
                return;
            }

            Logger.Write($"Found {pokestops.Count()} {(pokestops.Count() == 1 ? "Pokestop" : "Pokestops")}", LogLevel.Info);
            Gui.SetPokestopMarker(pokestops);

            while (pokestops.Any())
            {
                if (Logic._client.Settings.UseCSVExport && ExportPokemonToCsv._lastExportTime.AddMinutes(Logic._client.Settings.CSVExportInMinutes).Ticks < DateTime.Now.Ticks)
                {
                    var _playerProfile = await Logic._client.Player.GetPlayer();

                    await ExportPokemonToCsv.Execute(_playerProfile.PlayerData);
                }
                if (Logic._client.Settings.UseLuckyEggs)
                {
                    await UseLuckyEggTask.Execute();
                }
                if (Logic._client.Settings.CatchIncensePokemon)
                {
                    await UseIncenseTask.Execute();
                }

                var pokestopwithcooldown = pokestops.Where(p => p.CooldownCompleteTimestampMs > DateTime.UtcNow.ToUnixTime()).FirstOrDefault();
                if (pokestopwithcooldown != null)
                {
                    pokestops.Remove(pokestopwithcooldown);
                }

                var pokestop =
                    pokestops.Where(p => p.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime())
                    .OrderBy(
                        i =>
                        LocationUtils.CalculateDistanceInMeters(Logic._client.CurrentLatitude,
                                                                Logic._client.CurrentLongitude, i.Latitude, i.Longitude)).First();

                var lured    = string.Empty;
                var distance = LocationUtils.CalculateDistanceInMeters(Logic._client.CurrentLatitude, Logic._client.CurrentLongitude, pokestop.Latitude, pokestop.Longitude);
                if (distance > 100)
                {
                    var lurePokestop = pokestops.FirstOrDefault(x => x.LureInfo != null);
                    if (lurePokestop != null)
                    {
                        distance = LocationUtils.CalculateDistanceInMeters(Logic._client.CurrentLatitude, Logic._client.CurrentLongitude, pokestop.Latitude, pokestop.Longitude);
                        if (distance < 200)
                        {
                            lured    = " is Lured";
                            pokestop = lurePokestop;
                        }
                        else
                        {
                            pokestops.Remove(pokestop);
                        }
                    }
                }
                else
                {
                    pokestops.Remove(pokestop);
                }

                var fortInfo = await Logic._client.Fort.GetFort(pokestop.Id, pokestop.Latitude, pokestop.Longitude);

                var latlngDebug = string.Empty;
                if (Logic._client.Settings.DebugMode)
                {
                    latlngDebug = $" | Latitude: {pokestop.Latitude} - Longitude: {pokestop.Longitude}";
                }
                Logger.Write($"Name: {fortInfo.Name} in {distance:0.##} m distance{lured}{latlngDebug}", LogLevel.Pokestop);

                if (Logic._client.Settings.MovementBy == "UseTeleportInsteadOfWalking")
                {
                    await
                    Logic._client.Player.UpdatePlayerLocation(pokestop.Latitude, pokestop.Longitude,
                                                              Logic._client.Settings.DefaultAltitude);

                    await RandomHelper.RandomDelay(500);

                    Logger.Write($"Using Teleport instead of Walking!", LogLevel.Navigation);
                }
                else
                {
                    await
                    Navigation.HumanLikeWalking(new GeoUtils(pokestop.Latitude, pokestop.Longitude),
                                                async() =>
                    {
                        // Catch normal map Pokemon
                        await CatchMapPokemonsTask.Execute();
                        //Catch Incense Pokemon
                        await CatchIncensePokemonsTask.Execute();
                        return(true);
                    });
                }

                //Catch Lure Pokemon
                if (pokestop.LureInfo != null && Logic._client.Settings.CatchLuredPokemon)
                {
                    await CatchLurePokemonsTask.Execute(pokestop);
                }

                var       timesZeroXPawarded = 0;
                var       fortTry            = 0;  //Current check
                const int retryNumber        = 45; //How many times it needs to check to clear softban
                const int zeroCheck          = 5;  //How many times it checks fort before it thinks it's softban
                do
                {
                    var fortSearch = await Logic._client.Fort.SearchFort(pokestop.Id, pokestop.Latitude, pokestop.Longitude);

                    if (fortSearch.ExperienceAwarded > 0 && timesZeroXPawarded > 0)
                    {
                        timesZeroXPawarded = 0;
                    }
                    if (fortSearch.ExperienceAwarded == 0)
                    {
                        if (fortSearch.Result == FortSearchResponse.Types.Result.InCooldownPeriod)
                        {
                            Logger.Write("Pokestop is on Cooldown", LogLevel.Debug);
                            break;
                        }

                        timesZeroXPawarded++;
                        if (timesZeroXPawarded > zeroCheck)
                        {
                            fortTry += 1;

                            if (Logic._client.Settings.DebugMode)
                            {
                                Logger.Write(
                                    $"Seems your Soft-Banned. Trying to Unban via Pokestop Spins. Retry {fortTry} of {retryNumber - zeroCheck}",
                                    LogLevel.Warning);
                            }

                            await RandomHelper.RandomDelay(450);
                        }
                    }
                    else if (fortSearch.ExperienceAwarded != 0)
                    {
                        BotStats.ExperienceThisSession += fortSearch.ExperienceAwarded;
                        BotStats.UpdateConsoleTitle();
                        Logger.Write($"XP: {fortSearch.ExperienceAwarded}, Gems: {fortSearch.GemsAwarded}, Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}", LogLevel.Pokestop);
                        RecycleItemsTask._recycleCounter++;
                        HatchEggsTask._hatchUpdateDelay++;
                        break;                               //Continue with program as loot was succesfull.
                    }
                } while (fortTry < retryNumber - zeroCheck); //Stop trying if softban is cleaned earlier or if 40 times fort looting failed.

                if (RecycleItemsTask._recycleCounter >= 5)
                {
                    await RecycleItemsTask.Execute();
                }
                if (HatchEggsTask._hatchUpdateDelay >= 15)
                {
                    await HatchEggsTask.Execute();
                }
            }
        }
        //Please do not change GetPokeStops() in this file, it's specifically set
        //to only find stops within 40 meters
        //this is for gpx pathing, we are not going to the pokestops,
        //so do not make it more than 40 because it will never get close to those stops.
        public static async Task Execute()
        {
            if (Logic._client.Settings.GPXIgnorePokestops)
            {
                return;
            }

            var pokestops = await Inventory.GetPokestops(true);

            while (pokestops.Any())
            {
                var pokestop =
                    pokestops.OrderBy(
                        i =>
                        LocationUtils.CalculateDistanceInMeters(Logic._client.CurrentLatitude,
                                                                Logic._client.CurrentLongitude, i.Latitude, i.Longitude)).First();
                pokestops.Remove(pokestop);

                var distance = LocationUtils.CalculateDistanceInMeters(Logic._client.CurrentLatitude, Logic._client.CurrentLongitude, pokestop.Latitude, pokestop.Longitude);

                var fortInfo = await Logic._client.Fort.GetFort(pokestop.Id, pokestop.Latitude, pokestop.Longitude);

                var latlngDebug = string.Empty;
                if (Logic._client.Settings.DebugMode)
                {
                    latlngDebug = $"| Latitude: {pokestop.Latitude} - Longitude: {pokestop.Longitude}";
                }
                Logger.Write($"Name: {fortInfo.Name} in {distance:0.##} m distance {latlngDebug}", LogLevel.Pokestop);

                //Catch Lure Pokemon
                if (pokestop.LureInfo != null && Logic._client.Settings.CatchLuredPokemon)
                {
                    await CatchLurePokemonsTask.Execute(pokestop);
                }

                var       timesZeroXPawarded = 0;
                var       fortTry            = 0;  //Current check
                const int retryNumber        = 50; //How many times it needs to check to clear softban
                const int zeroCheck          = 5;  //How many times it checks fort before it thinks it's softban
                do
                {
                    var fortSearch = await Logic._client.Fort.SearchFort(pokestop.Id, pokestop.Latitude, pokestop.Longitude);

                    if (fortSearch.ExperienceAwarded > 0 && timesZeroXPawarded > 0)
                    {
                        timesZeroXPawarded = 0;
                    }
                    if (fortSearch.ExperienceAwarded == 0)
                    {
                        timesZeroXPawarded++;

                        if (timesZeroXPawarded <= zeroCheck)
                        {
                            continue;
                        }
                        if ((int)fortSearch.CooldownCompleteTimestampMs != 0)
                        {
                            break; // Check if successfully looted, if so program can continue as this was "false alarm".
                        }
                        fortTry += 1;

                        if (Logic._client.Settings.DebugMode)
                        {
                            Logger.Write($"Seems your Soft-Banned. Trying to Unban via Pokestop Spins. Retry {fortTry} of {retryNumber - zeroCheck}", LogLevel.Warning);
                        }

                        await RandomHelper.RandomDelay(75, 100);
                    }
                    else
                    {
                        BotStats.ExperienceThisSession += fortSearch.ExperienceAwarded;
                        BotStats.UpdateConsoleTitle();
                        Logger.Write($"XP: {fortSearch.ExperienceAwarded}, Gems: {fortSearch.GemsAwarded}, Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}", LogLevel.Pokestop);
                        RecycleItemsTask._recycleCounter++;
                        HatchEggsTask._hatchUpdateDelayGPX++;
                        break; //Continue with program as loot was succesfull.
                    }
                } while (fortTry < retryNumber - zeroCheck);
                //Stop trying if softban is cleaned earlier or if 40 times fort looting failed.

                if (RecycleItemsTask._recycleCounter >= 5)
                {
                    await RecycleItemsTask.Execute();
                }
                if (HatchEggsTask._hatchUpdateDelayGPX >= 5)
                {
                    await HatchEggsTask.Execute();
                }
            }
        }