diff --git a/PoGo.NecroBot.Logic/Navigation.cs b/PoGo.NecroBot.Logic/Navigation.cs index c4fde7dd5..acd842eda 100644 --- a/PoGo.NecroBot.Logic/Navigation.cs +++ b/PoGo.NecroBot.Logic/Navigation.cs @@ -4,6 +4,7 @@ using System; using System.Globalization; +using System.Threading; using System.Threading.Tasks; using GeoCoordinatePortable; using PoGo.NecroBot.Logic.Utils; @@ -30,9 +31,10 @@ public Navigation(Client client) _client = client; } - public async Task HumanLikeWalking(GeoCoordinate targetLocation, - double walkingSpeedInKilometersPerHour, Func> functionExecutedWhileWalking) + public async Task HumanLikeWalking(GeoCoordinate targetLocation, double walkingSpeedInKilometersPerHour, Func> functionExecutedWhileWalking, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + var speedInMetersPerSecond = walkingSpeedInKilometersPerHour/3.6; var sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude); @@ -54,6 +56,8 @@ public async Task HumanLikeWalking(GeoCoordinate targetLoc do { + cancellationToken.ThrowIfCancellationRequested(); + var millisecondsUntilGetUpdatePlayerLocationResponse = (DateTime.Now - requestSendDateTime).TotalMilliseconds; @@ -85,15 +89,17 @@ public async Task HumanLikeWalking(GeoCoordinate targetLoc if (functionExecutedWhileWalking != null) await functionExecutedWhileWalking(); // look for pokemon - await Task.Delay(500); + await Task.Delay(500, cancellationToken); } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30); return result; } public async Task HumanPathWalking(GpxReader.Trkpt trk, - double walkingSpeedInKilometersPerHour, Func> functionExecutedWhileWalking) + double walkingSpeedInKilometersPerHour, Func> functionExecutedWhileWalking, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + //PlayerUpdateResponse result = null; var targetLocation = new GeoCoordinate(Convert.ToDouble(trk.Lat, CultureInfo.InvariantCulture), @@ -121,6 +127,8 @@ public async Task HumanPathWalking(GpxReader.Trkpt trk, do { + cancellationToken.ThrowIfCancellationRequested(); + var millisecondsUntilGetUpdatePlayerLocationResponse = (DateTime.Now - requestSendDateTime).TotalMilliseconds; @@ -152,7 +160,7 @@ public async Task HumanPathWalking(GpxReader.Trkpt trk, if (functionExecutedWhileWalking != null) await functionExecutedWhileWalking(); // look for pokemon & hit stops - await Task.Delay(500); + await Task.Delay(500, cancellationToken); } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30); return result; diff --git a/PoGo.NecroBot.Logic/State/FarmState.cs b/PoGo.NecroBot.Logic/State/FarmState.cs index bb7276f91..46c0a18f9 100644 --- a/PoGo.NecroBot.Logic/State/FarmState.cs +++ b/PoGo.NecroBot.Logic/State/FarmState.cs @@ -1,5 +1,6 @@ #region using directives +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Tasks; @@ -9,37 +10,37 @@ namespace PoGo.NecroBot.Logic.State { public class FarmState : IState { - public async Task Execute(ISession session) + public async Task Execute(ISession session, CancellationToken cancellationToken) { if (session.LogicSettings.EvolveAllPokemonAboveIv || session.LogicSettings.EvolveAllPokemonWithEnoughCandy) { - await EvolvePokemonTask.Execute(session); + await EvolvePokemonTask.Execute(session, cancellationToken); } if (session.LogicSettings.TransferDuplicatePokemon) { - await TransferDuplicatePokemonTask.Execute(session); + await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } if (session.LogicSettings.RenameAboveIv) { - await RenamePokemonTask.Execute(session); + await RenamePokemonTask.Execute(session, cancellationToken); } - await RecycleItemsTask.Execute(session); + await RecycleItemsTask.Execute(session, cancellationToken); if (session.LogicSettings.UseEggIncubators) { - await UseIncubatorsTask.Execute(session); + await UseIncubatorsTask.Execute(session, cancellationToken); } if (session.LogicSettings.UseGpxPathing) { - await FarmPokestopsGpxTask.Execute(session); + await FarmPokestopsGpxTask.Execute(session, cancellationToken); } else { - await FarmPokestopsTask.Execute(session); + await FarmPokestopsTask.Execute(session, cancellationToken); } return this; diff --git a/PoGo.NecroBot.Logic/State/IState.cs b/PoGo.NecroBot.Logic/State/IState.cs index 11e789b3b..8bf0d267c 100644 --- a/PoGo.NecroBot.Logic/State/IState.cs +++ b/PoGo.NecroBot.Logic/State/IState.cs @@ -1,5 +1,6 @@ #region using directives +using System.Threading; using System.Threading.Tasks; #endregion @@ -8,6 +9,6 @@ namespace PoGo.NecroBot.Logic.State { public interface IState { - Task Execute(ISession session); + Task Execute(ISession session, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/PoGo.NecroBot.Logic/State/InfoState.cs b/PoGo.NecroBot.Logic/State/InfoState.cs index d23b70228..839b0bcc2 100644 --- a/PoGo.NecroBot.Logic/State/InfoState.cs +++ b/PoGo.NecroBot.Logic/State/InfoState.cs @@ -1,5 +1,6 @@ #region using directives +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Tasks; @@ -9,8 +10,10 @@ namespace PoGo.NecroBot.Logic.State { public class InfoState : IState { - public async Task Execute(ISession session) + public async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + if (session.LogicSettings.AmountOfPokemonToDisplayOnStart > 0) await DisplayPokemonStatsTask.Execute(session); diff --git a/PoGo.NecroBot.Logic/State/LoginState.cs b/PoGo.NecroBot.Logic/State/LoginState.cs index 1fe03c2cc..8814deb35 100644 --- a/PoGo.NecroBot.Logic/State/LoginState.cs +++ b/PoGo.NecroBot.Logic/State/LoginState.cs @@ -1,6 +1,7 @@ #region using directives using System; +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Common; using PoGo.NecroBot.Logic.Event; @@ -13,13 +14,17 @@ namespace PoGo.NecroBot.Logic.State { public class LoginState : IState { - public async Task Execute(ISession session) + public async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + session.EventDispatcher.Send(new NoticeEvent { Message = session.Translation.GetTranslation(TranslationString.LoggingIn, session.Settings.AuthType) }); - await CheckLogin(session); + + await CheckLogin(session, cancellationToken); + try { switch (session.Settings.AuthType) @@ -64,7 +69,7 @@ public async Task Execute(ISession session) { session.EventDispatcher.Send(new ErrorEvent { Message = session.Translation.GetTranslation(TranslationString.GoogleTwoFactorAuth) }); session.EventDispatcher.Send(new ErrorEvent { Message = session.Translation.GetTranslation(TranslationString.GoogleTwoFactorAuthExplanation) }); - await Task.Delay(7000); + await Task.Delay(7000, cancellationToken); try { System.Diagnostics.Process.Start("https://security.google.com/settings/security/apppasswords"); @@ -76,7 +81,7 @@ public async Task Execute(ISession session) } } session.EventDispatcher.Send(new ErrorEvent { Message = session.Translation.GetTranslation(TranslationString.GoogleError) }); - await Task.Delay(2000); + await Task.Delay(2000, cancellationToken); Environment.Exit(0); } @@ -85,8 +90,10 @@ public async Task Execute(ISession session) return new PositionCheckState(); } - private static async Task CheckLogin(ISession session) + private static async Task CheckLogin(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + if (session.Settings.AuthType == AuthType.Google && (session.Settings.GoogleUsername == null || session.Settings.GooglePassword == null)) { @@ -94,7 +101,7 @@ private static async Task CheckLogin(ISession session) { Message = session.Translation.GetTranslation(TranslationString.MissingCredentialsGoogle) }); - await Task.Delay(2000); + await Task.Delay(2000, cancellationToken); Environment.Exit(0); } else if (session.Settings.AuthType == AuthType.Ptc && @@ -104,7 +111,7 @@ private static async Task CheckLogin(ISession session) { Message = session.Translation.GetTranslation(TranslationString.MissingCredentialsPtc) }); - await Task.Delay(2000); + await Task.Delay(2000, cancellationToken); Environment.Exit(0); } } @@ -112,7 +119,7 @@ private static async Task CheckLogin(ISession session) public async Task DownloadProfile(ISession session) { session.Profile = await session.Client.Player.GetPlayer(); - session.EventDispatcher.Send(new ProfileEvent {Profile = session.Profile}); + session.EventDispatcher.Send(new ProfileEvent { Profile = session.Profile }); } } } \ No newline at end of file diff --git a/PoGo.NecroBot.Logic/State/PositionCheckState.cs b/PoGo.NecroBot.Logic/State/PositionCheckState.cs index 2c260a0a6..c38b3a2c1 100644 --- a/PoGo.NecroBot.Logic/State/PositionCheckState.cs +++ b/PoGo.NecroBot.Logic/State/PositionCheckState.cs @@ -2,6 +2,7 @@ using System; using System.IO; +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Common; using PoGo.NecroBot.Logic.Event; @@ -13,8 +14,10 @@ namespace PoGo.NecroBot.Logic.State { public class PositionCheckState : IState { - public async Task Execute(ISession session) + public async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + var coordsPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "Configs" + Path.DirectorySeparatorChar + "Coords.ini"; if (File.Exists(coordsPath)) @@ -49,7 +52,7 @@ public async Task Execute(ISession session) }); } } - await Task.Delay(200); + await Task.Delay(200, cancellationToken); } } } diff --git a/PoGo.NecroBot.Logic/State/StateMachine.cs b/PoGo.NecroBot.Logic/State/StateMachine.cs index 13005f0a9..a97ee3119 100644 --- a/PoGo.NecroBot.Logic/State/StateMachine.cs +++ b/PoGo.NecroBot.Logic/State/StateMachine.cs @@ -1,6 +1,7 @@ #region using directives using System; +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Event; using PokemonGo.RocketAPI.Exceptions; @@ -14,9 +15,9 @@ public class StateMachine private ISession _ctx; private IState _initialState; - public Task AsyncStart(IState initialState, Session session) + public Task AsyncStart(IState initialState, Session session, CancellationToken cancellationToken = default(CancellationToken)) { - return Task.Run(() => Start(initialState, session)); + return Task.Run(() => Start(initialState, session, cancellationToken), cancellationToken); } public void SetFailureState(IState state) @@ -24,7 +25,7 @@ public void SetFailureState(IState state) _initialState = state; } - public async Task Start(IState initialState, Session session) + public async Task Start(IState initialState, Session session, CancellationToken cancellationToken = default(CancellationToken)) { _ctx = session; var state = initialState; @@ -32,15 +33,20 @@ public async Task Start(IState initialState, Session session) { try { - state = await state.Execute(session); + state = await state.Execute(session, cancellationToken); } - catch(InvalidResponseException) + catch (InvalidResponseException) { session.EventDispatcher.Send(new ErrorEvent { Message = "The PokemonGo servers are having a bad time, chill." }); } + catch (OperationCanceledException) + { + session.EventDispatcher.Send(new ErrorEvent { Message = "The bot was stopped." }); + return; + } catch (Exception ex) { - session.EventDispatcher.Send(new ErrorEvent {Message = ex.ToString()}); + session.EventDispatcher.Send(new ErrorEvent { Message = ex.ToString() }); state = _initialState; } } while (state != null); diff --git a/PoGo.NecroBot.Logic/State/VersionCheckState.cs b/PoGo.NecroBot.Logic/State/VersionCheckState.cs index 60c3ef58c..fc966c2ec 100644 --- a/PoGo.NecroBot.Logic/State/VersionCheckState.cs +++ b/PoGo.NecroBot.Logic/State/VersionCheckState.cs @@ -7,6 +7,7 @@ using System.Net; using System.Reflection; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Event; using PoGo.NecroBot.Logic.Logging; @@ -28,8 +29,10 @@ public class VersionCheckState : IState public static Version RemoteVersion; - public async Task Execute(ISession session) + public async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + await CleanupOldFiles(); var autoUpdate = session.LogicSettings.AutoUpdate; var needupdate = IsLatest(); diff --git a/PoGo.NecroBot.Logic/Tasks/CatchIncensePokemonsTask.cs b/PoGo.NecroBot.Logic/Tasks/CatchIncensePokemonsTask.cs index 343b59e7a..47f1f5631 100644 --- a/PoGo.NecroBot.Logic/Tasks/CatchIncensePokemonsTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/CatchIncensePokemonsTask.cs @@ -1,5 +1,6 @@ #region using directives +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Event; using PoGo.NecroBot.Logic.Logging; @@ -15,10 +16,11 @@ namespace PoGo.NecroBot.Logic.Tasks { public static class CatchIncensePokemonsTask { - public static async Task Execute(ISession session) + public static async Task Execute(ISession session, CancellationToken cancellationToken) { - Logger.Write(session.Translation.GetTranslation(Common.TranslationString.LookingForIncensePokemon), LogLevel.Debug); + cancellationToken.ThrowIfCancellationRequested(); + Logger.Write(session.Translation.GetTranslation(Common.TranslationString.LookingForIncensePokemon), LogLevel.Debug); var incensePokemon = await session.Client.Map.GetIncensePokemons(); if (incensePokemon.Result == GetIncensePokemonResponse.Types.Result.IncenseEncounterAvailable) @@ -29,7 +31,7 @@ public static async Task Execute(ISession session) ExpirationTimestampMs = incensePokemon.DisappearTimestampMs, Latitude = incensePokemon.Latitude, Longitude = incensePokemon.Longitude, - PokemonId = (PokemonId) incensePokemon.PokemonId, + PokemonId = (PokemonId)incensePokemon.PokemonId, SpawnPointId = incensePokemon.EncounterLocation }; @@ -46,7 +48,7 @@ public static async Task Execute(ISession session) var encounter = await - session.Client.Encounter.EncounterIncensePokemon((long) pokemon.EncounterId, + session.Client.Encounter.EncounterIncensePokemon((long)pokemon.EncounterId, pokemon.SpawnPointId); if (encounter.Result == IncenseEncounterResponse.Types.Result.IncenseEncounterSuccess) @@ -57,8 +59,8 @@ public static async Task Execute(ISession session) { if (session.LogicSettings.TransferDuplicatePokemon) { - session.EventDispatcher.Send(new WarnEvent {Message = session.Translation.GetTranslation(Common.TranslationString.InvFullTransferring)}); - await TransferDuplicatePokemonTask.Execute(session); + session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(Common.TranslationString.InvFullTransferring) }); + await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } else session.EventDispatcher.Send(new WarnEvent @@ -68,7 +70,7 @@ public static async Task Execute(ISession session) } else { - session.EventDispatcher.Send(new WarnEvent {Message = session.Translation.GetTranslation(Common.TranslationString.EncounterProblem, encounter.Result)}); + session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(Common.TranslationString.EncounterProblem, encounter.Result) }); } } } diff --git a/PoGo.NecroBot.Logic/Tasks/CatchLurePokemonsTask.cs b/PoGo.NecroBot.Logic/Tasks/CatchLurePokemonsTask.cs index 9f7403398..103df3076 100644 --- a/PoGo.NecroBot.Logic/Tasks/CatchLurePokemonsTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/CatchLurePokemonsTask.cs @@ -1,5 +1,6 @@ #region using directives +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Event; using PoGo.NecroBot.Logic.Logging; @@ -13,8 +14,10 @@ namespace PoGo.NecroBot.Logic.Tasks { public static class CatchLurePokemonsTask { - public static async Task Execute(ISession session, FortData currentFortData) + public static async Task Execute(ISession session, FortData currentFortData, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + Logger.Write(session.Translation.GetTranslation(Common.TranslationString.LookingForLurePokemon), LogLevel.Debug); var fortId = currentFortData.Id; @@ -24,7 +27,7 @@ public static async Task Execute(ISession session, FortData currentFortData) if (session.LogicSettings.UsePokemonToNotCatchFilter && session.LogicSettings.PokemonsNotToCatch.Contains(pokemonId)) { - session.EventDispatcher.Send(new NoticeEvent {Message = session.Translation.GetTranslation(Common.TranslationString.PokemonSkipped, pokemonId)}); + session.EventDispatcher.Send(new NoticeEvent { Message = session.Translation.GetTranslation(Common.TranslationString.PokemonSkipped, pokemonId) }); } else { @@ -39,8 +42,8 @@ public static async Task Execute(ISession session, FortData currentFortData) { if (session.LogicSettings.TransferDuplicatePokemon) { - session.EventDispatcher.Send(new WarnEvent {Message = session.Translation.GetTranslation(Common.TranslationString.InvFullTransferring) }); - await TransferDuplicatePokemonTask.Execute(session); + session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(Common.TranslationString.InvFullTransferring) }); + await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } else session.EventDispatcher.Send(new WarnEvent @@ -51,7 +54,7 @@ public static async Task Execute(ISession session, FortData currentFortData) else { if (encounter.Result.ToString().Contains("NotAvailable")) return; - session.EventDispatcher.Send(new WarnEvent {Message = session.Translation.GetTranslation(Common.TranslationString.EncounterProblemLurePokemon, encounter.Result)}); + session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(Common.TranslationString.EncounterProblemLurePokemon, encounter.Result) }); } } } diff --git a/PoGo.NecroBot.Logic/Tasks/CatchNearbyPokemonsTask.cs b/PoGo.NecroBot.Logic/Tasks/CatchNearbyPokemonsTask.cs index a4ded13cd..8bff27eb1 100644 --- a/PoGo.NecroBot.Logic/Tasks/CatchNearbyPokemonsTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/CatchNearbyPokemonsTask.cs @@ -1,6 +1,7 @@ #region using directives using System.Linq; +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Event; using PoGo.NecroBot.Logic.Logging; @@ -15,13 +16,17 @@ namespace PoGo.NecroBot.Logic.Tasks { public static class CatchNearbyPokemonsTask { - public static async Task Execute(ISession session) + public static async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + Logger.Write(session.Translation.GetTranslation(Common.TranslationString.LookingForPokemon), LogLevel.Debug); var pokemons = await GetNearbyPokemons(session); foreach (var pokemon in pokemons) { + cancellationToken.ThrowIfCancellationRequested(); + var pokeBallsCount = await session.Inventory.GetItemAmountByType(POGOProtos.Inventory.Item.ItemId.ItemPokeBall); var greatBallsCount = await session.Inventory.GetItemAmountByType(POGOProtos.Inventory.Item.ItemId.ItemGreatBall); var ultraBallsCount = await session.Inventory.GetItemAmountByType(POGOProtos.Inventory.Item.ItemId.ItemUltraBall); @@ -29,7 +34,7 @@ public static async Task Execute(ISession session) if (pokeBallsCount + greatBallsCount + ultraBallsCount + masterBallsCount == 0) return; - + if (session.LogicSettings.UsePokemonToNotCatchFilter && session.LogicSettings.PokemonsNotToCatch.Contains(pokemon.PokemonId)) { @@ -39,7 +44,7 @@ public static async Task Execute(ISession session) var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, pokemon.Latitude, pokemon.Longitude); - await Task.Delay(distance > 100 ? 3000 : 500); + await Task.Delay(distance > 100 ? 3000 : 500, cancellationToken); var encounter = await session.Client.Encounter.EncounterPokemon(pokemon.EncounterId, pokemon.SpawnPointId); @@ -51,8 +56,8 @@ public static async Task Execute(ISession session) { if (session.LogicSettings.TransferDuplicatePokemon) { - session.EventDispatcher.Send(new WarnEvent {Message = session.Translation.GetTranslation(Common.TranslationString.InvFullTransferring)}); - await TransferDuplicatePokemonTask.Execute(session); + session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(Common.TranslationString.InvFullTransferring) }); + await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } else session.EventDispatcher.Send(new WarnEvent @@ -62,13 +67,13 @@ public static async Task Execute(ISession session) } else { - session.EventDispatcher.Send(new WarnEvent {Message = session.Translation.GetTranslation(Common.TranslationString.EncounterProblem, encounter.Status)}); + session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(Common.TranslationString.EncounterProblem, encounter.Status) }); } // If pokemon is not last pokemon in list, create delay between catches, else keep moving. if (!Equals(pokemons.ElementAtOrDefault(pokemons.Count() - 1), pokemon)) { - await Task.Delay(session.LogicSettings.DelayBetweenPokemonCatch); + await Task.Delay(session.LogicSettings.DelayBetweenPokemonCatch, cancellationToken); } } } diff --git a/PoGo.NecroBot.Logic/Tasks/EvolvePokemonTask.cs b/PoGo.NecroBot.Logic/Tasks/EvolvePokemonTask.cs index 9b7cb0cf0..aaa28c58c 100644 --- a/PoGo.NecroBot.Logic/Tasks/EvolvePokemonTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/EvolvePokemonTask.cs @@ -2,6 +2,7 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Event; using PoGo.NecroBot.Logic.State; @@ -17,8 +18,10 @@ public class EvolvePokemonTask { private static DateTime _lastLuckyEggTime; - public static async Task Execute(ISession session) + public static async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + var pokemonToEvolveTask = await session.Inventory.GetPokemonToEvolve(session.LogicSettings.PokemonsToEvolve); var pokemonToEvolve = pokemonToEvolveTask.ToList(); @@ -46,6 +49,7 @@ public static async Task Execute(ISession session) foreach (var pokemon in pokemonToEvolve) { + // no cancellationToken.ThrowIfCancellationRequested here, otherwise the lucky egg would be wasted. var evolveResponse = await session.Client.Inventory.EvolvePokemon(pokemon.Id); session.EventDispatcher.Send(new PokemonEvolveEvent diff --git a/PoGo.NecroBot.Logic/Tasks/Farm.cs b/PoGo.NecroBot.Logic/Tasks/Farm.cs index ae51f99a2..fc0eb0f7a 100644 --- a/PoGo.NecroBot.Logic/Tasks/Farm.cs +++ b/PoGo.NecroBot.Logic/Tasks/Farm.cs @@ -1,16 +1,12 @@ using PoGo.NecroBot.Logic.State; using PoGo.NecroBot.Logic.Tasks; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Threading; namespace PoGo.NecroBot.Logic.Service { public interface IFarm { - void Run(); + void Run(CancellationToken cancellationToken); } public class Farm : IFarm @@ -22,37 +18,37 @@ public Farm(ISession session) _session = session; } - public void Run() + public void Run(CancellationToken cancellationToken) { if (_session.LogicSettings.EvolveAllPokemonAboveIv || _session.LogicSettings.EvolveAllPokemonWithEnoughCandy) { - EvolvePokemonTask.Execute(_session).Wait(); + EvolvePokemonTask.Execute(_session, cancellationToken).Wait(); } if (_session.LogicSettings.TransferDuplicatePokemon) { - TransferDuplicatePokemonTask.Execute(_session).Wait(); + TransferDuplicatePokemonTask.Execute(_session, cancellationToken).Wait(); } if (_session.LogicSettings.RenameAboveIv) { - RenamePokemonTask.Execute(_session).Wait(); + RenamePokemonTask.Execute(_session, cancellationToken).Wait(); } - RecycleItemsTask.Execute(_session).Wait(); + RecycleItemsTask.Execute(_session, cancellationToken).Wait(); if (_session.LogicSettings.UseEggIncubators) { - UseIncubatorsTask.Execute(_session).Wait(); + UseIncubatorsTask.Execute(_session, cancellationToken).Wait(); } if (_session.LogicSettings.UseGpxPathing) { - FarmPokestopsGpxTask.Execute(_session).Wait(); + FarmPokestopsGpxTask.Execute(_session, cancellationToken).Wait(); } else { - FarmPokestopsTask.Execute(_session).Wait(); + FarmPokestopsTask.Execute(_session, cancellationToken).Wait(); } } } diff --git a/PoGo.NecroBot.Logic/Tasks/FarmPokestopsGPXTask.cs b/PoGo.NecroBot.Logic/Tasks/FarmPokestopsGPXTask.cs index 0a7c072aa..7fc4500c7 100644 --- a/PoGo.NecroBot.Logic/Tasks/FarmPokestopsGPXTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/FarmPokestopsGPXTask.cs @@ -5,6 +5,7 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Event; using PoGo.NecroBot.Logic.State; @@ -18,7 +19,7 @@ namespace PoGo.NecroBot.Logic.Tasks { public static class FarmPokestopsGpxTask { - public static async Task Execute(ISession session) + public static async Task Execute(ISession session, CancellationToken cancellationToken) { var tracks = GetGpxTracks(session); var curTrkPt = 0; @@ -28,21 +29,26 @@ public static async Task Execute(ISession session) var eggWalker = new EggWalker(1000, session); while (curTrk <= maxTrk) { + cancellationToken.ThrowIfCancellationRequested(); + var track = tracks.ElementAt(curTrk); var trackSegments = track.Segments; var maxTrkSeg = trackSegments.Count - 1; while (curTrkSeg <= maxTrkSeg) { + cancellationToken.ThrowIfCancellationRequested(); + var trackPoints = track.Segments.ElementAt(0).TrackPoints; var maxTrkPt = trackPoints.Count - 1; - while (curTrkPt <= maxTrkPt) { + cancellationToken.ThrowIfCancellationRequested(); + var nextPoint = trackPoints.ElementAt(curTrkPt); var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, Convert.ToDouble(nextPoint.Lat, CultureInfo.InvariantCulture), Convert.ToDouble(nextPoint.Lon, CultureInfo.InvariantCulture)); - + if (distance > 5000) { session.EventDispatcher.Send(new ErrorEvent @@ -53,10 +59,12 @@ public static async Task Execute(ISession session) } var pokestopList = await GetPokeStops(session); - session.EventDispatcher.Send(new PokeStopListEvent {Forts = pokestopList}); + session.EventDispatcher.Send(new PokeStopListEvent { Forts = pokestopList }); while (pokestopList.Any()) { + cancellationToken.ThrowIfCancellationRequested(); + pokestopList = pokestopList.OrderBy( i => @@ -69,7 +77,7 @@ public static async Task Execute(ISession session) if (pokeStop.LureInfo != null) { - await CatchLurePokemonsTask.Execute(session, pokeStop); + await CatchLurePokemonsTask.Execute(session, pokeStop, cancellationToken); } var fortSearch = @@ -93,42 +101,45 @@ public static async Task Execute(ISession session) await session.Inventory.RefreshCachedInventory(); } - await RecycleItemsTask.Execute(session); + await RecycleItemsTask.Execute(session, cancellationToken); + + if (session.LogicSettings.SnipeAtPokestops) + { + await SnipePokemonTask.Execute(session, cancellationToken); + } if (session.LogicSettings.EvolveAllPokemonWithEnoughCandy || session.LogicSettings.EvolveAllPokemonAboveIv) { - await EvolvePokemonTask.Execute(session); + await EvolvePokemonTask.Execute(session, cancellationToken); } if (session.LogicSettings.TransferDuplicatePokemon) { - await TransferDuplicatePokemonTask.Execute(session); + await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } if (session.LogicSettings.RenameAboveIv) { - await RenamePokemonTask.Execute(session); + await RenamePokemonTask.Execute(session, cancellationToken); } } - if (session.LogicSettings.SnipeAtPokestops) - { - await SnipePokemonTask.Execute(session); - } - - await session.Navigation.HumanPathWalking(trackPoints.ElementAt(curTrkPt), - session.LogicSettings.WalkingSpeedInKilometerPerHour, async () => - { - await CatchNearbyPokemonsTask.Execute(session); - //Catch Incense Pokemon - await CatchIncensePokemonsTask.Execute(session); - await UseNearbyPokestopsTask.Execute(session); - return true; - } + await session.Navigation.HumanPathWalking( + trackPoints.ElementAt(curTrkPt), + session.LogicSettings.WalkingSpeedInKilometerPerHour, + async () => + { + await CatchNearbyPokemonsTask.Execute(session, cancellationToken); + //Catch Incense Pokemon + await CatchIncensePokemonsTask.Execute(session, cancellationToken); + await UseNearbyPokestopsTask.Execute(session, cancellationToken); + return true; + }, + cancellationToken ); - await eggWalker.ApplyDistance(distance); + await eggWalker.ApplyDistance(distance, cancellationToken); if (curTrkPt >= maxTrkPt) curTrkPt = 0; diff --git a/PoGo.NecroBot.Logic/Tasks/FarmPokestopsTask.cs b/PoGo.NecroBot.Logic/Tasks/FarmPokestopsTask.cs index c7fd9c08e..071d9e1c8 100644 --- a/PoGo.NecroBot.Logic/Tasks/FarmPokestopsTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/FarmPokestopsTask.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using GeoCoordinatePortable; using PoGo.NecroBot.Logic.Common; @@ -22,8 +23,10 @@ public static class FarmPokestopsTask { public static int TimesZeroXPawarded; - public static async Task Execute(ISession session) + public static async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + var distanceFromStart = LocationUtils.CalculateDistanceInMeters( session.Settings.DefaultLatitude, session.Settings.DefaultLongitude, session.Client.CurrentLatitude, session.Client.CurrentLongitude); @@ -36,11 +39,11 @@ public static async Task Execute(ISession session) session.Translation.GetTranslation(TranslationString.FarmPokestopsOutsideRadius, distanceFromStart), LogLevel.Warning); - await Task.Delay(1000); + await Task.Delay(1000, cancellationToken); await session.Navigation.HumanLikeWalking( new GeoCoordinate(session.Settings.DefaultLatitude, session.Settings.DefaultLongitude), - session.LogicSettings.WalkingSpeedInKilometerPerHour, null); + session.LogicSettings.WalkingSpeedInKilometerPerHour, null, cancellationToken); } var pokestopList = await GetPokeStops(session); @@ -55,10 +58,12 @@ await session.Navigation.HumanLikeWalking( }); } - session.EventDispatcher.Send(new PokeStopListEvent {Forts = pokestopList}); + session.EventDispatcher.Send(new PokeStopListEvent { Forts = pokestopList }); while (pokestopList.Any()) { + cancellationToken.ThrowIfCancellationRequested(); + //resort pokestopList = pokestopList.OrderBy( @@ -72,23 +77,23 @@ await session.Navigation.HumanLikeWalking( session.Client.CurrentLongitude, pokeStop.Latitude, pokeStop.Longitude); var fortInfo = await session.Client.Fort.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude); - session.EventDispatcher.Send(new FortTargetEvent {Name = fortInfo.Name, Distance = distance}); + session.EventDispatcher.Send(new FortTargetEvent { Name = fortInfo.Name, Distance = distance }); await session.Navigation.HumanLikeWalking(new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude), session.LogicSettings.WalkingSpeedInKilometerPerHour, async () => { // Catch normal map Pokemon - await CatchNearbyPokemonsTask.Execute(session); + await CatchNearbyPokemonsTask.Execute(session, cancellationToken); //Catch Incense Pokemon - await CatchIncensePokemonsTask.Execute(session); + await CatchIncensePokemonsTask.Execute(session, cancellationToken); return true; - }); + }, cancellationToken); //Catch Lure Pokemon if (pokeStop.LureInfo != null) { - await CatchLurePokemonsTask.Execute(session, pokeStop); + await CatchLurePokemonsTask.Execute(session, pokeStop, cancellationToken); } FortSearchResponse fortSearch; @@ -96,7 +101,10 @@ await session.Navigation.HumanLikeWalking(new GeoCoordinate(pokeStop.Latitude, p 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 { + do + { + cancellationToken.ThrowIfCancellationRequested(); + fortSearch = await session.Client.Fort.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude); if (fortSearch.ExperienceAwarded > 0 && TimesZeroXPawarded > 0) TimesZeroXPawarded = 0; if (fortSearch.ExperienceAwarded == 0) @@ -121,7 +129,9 @@ await session.Navigation.HumanLikeWalking(new GeoCoordinate(pokeStop.Latitude, p DelayingUtils.Delay(session.LogicSettings.DelayBetweenPlayerActions, 400); } - } else { + } + else + { session.EventDispatcher.Send(new FortUsedEvent { Id = pokeStop.Id, @@ -136,37 +146,37 @@ await session.Navigation.HumanLikeWalking(new GeoCoordinate(pokeStop.Latitude, p 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. + } while (fortTry < retryNumber - zeroCheck); //Stop trying if softban is cleaned earlier or if 40 times fort looting failed. - await Task.Delay(1000); + await Task.Delay(1000, cancellationToken); - await eggWalker.ApplyDistance(distance); + await eggWalker.ApplyDistance(distance, cancellationToken); - if (++stopsHit%5 == 0) //TODO: OR item/pokemon bag is full + if (++stopsHit % 5 == 0) //TODO: OR item/pokemon bag is full { stopsHit = 0; if (fortSearch.ItemsAwarded.Count > 0) { await session.Inventory.RefreshCachedInventory(); } - await RecycleItemsTask.Execute(session); + await RecycleItemsTask.Execute(session, cancellationToken); if (session.LogicSettings.EvolveAllPokemonWithEnoughCandy || session.LogicSettings.EvolveAllPokemonAboveIv) { - await EvolvePokemonTask.Execute(session); + await EvolvePokemonTask.Execute(session, cancellationToken); } if (session.LogicSettings.TransferDuplicatePokemon) { - await TransferDuplicatePokemonTask.Execute(session); + await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } if (session.LogicSettings.RenameAboveIv) { - await RenamePokemonTask.Execute(session); + await RenamePokemonTask.Execute(session, cancellationToken); } } if (session.LogicSettings.SnipeAtPokestops) { - await SnipePokemonTask.Execute(session); + await SnipePokemonTask.Execute(session, cancellationToken); } } } diff --git a/PoGo.NecroBot.Logic/Tasks/RecycleItemsTask.cs b/PoGo.NecroBot.Logic/Tasks/RecycleItemsTask.cs index da4cdac73..6622998aa 100644 --- a/PoGo.NecroBot.Logic/Tasks/RecycleItemsTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/RecycleItemsTask.cs @@ -1,5 +1,6 @@ #region using directives +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Event; using PoGo.NecroBot.Logic.State; @@ -11,12 +12,16 @@ namespace PoGo.NecroBot.Logic.Tasks { public class RecycleItemsTask { - public static async Task Execute(ISession session) + public static async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + var items = await session.Inventory.GetItemsToRecycle(session.Settings); foreach (var item in items) { + cancellationToken.ThrowIfCancellationRequested(); + await session.Client.Inventory.RecycleItem(item.ItemId, item.Count); session.EventDispatcher.Send(new ItemRecycledEvent {Id = item.ItemId, Count = item.Count}); diff --git a/PoGo.NecroBot.Logic/Tasks/RenamePokemonTask.cs b/PoGo.NecroBot.Logic/Tasks/RenamePokemonTask.cs index 9474d0ed9..05cdf44fe 100644 --- a/PoGo.NecroBot.Logic/Tasks/RenamePokemonTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/RenamePokemonTask.cs @@ -2,6 +2,7 @@ using System; using System.Globalization; +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Event; using PoGo.NecroBot.Logic.PoGoUtils; @@ -14,12 +15,16 @@ namespace PoGo.NecroBot.Logic.Tasks { public class RenamePokemonTask { - public static async Task Execute(ISession session) + public static async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + var pokemons = await session.Inventory.GetPokemons(); foreach (var pokemon in pokemons) { + cancellationToken.ThrowIfCancellationRequested(); + double perfection = Math.Round(PokemonInfo.CalculatePokemonPerfection(pokemon)); string pokemonName = pokemon.PokemonId.ToString(); // iv number + templating part + pokemonName <= 12 diff --git a/PoGo.NecroBot.Logic/Tasks/SnipePokemonTask.cs b/PoGo.NecroBot.Logic/Tasks/SnipePokemonTask.cs index cbf7fbbb6..c810f1c5c 100644 --- a/PoGo.NecroBot.Logic/Tasks/SnipePokemonTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/SnipePokemonTask.cs @@ -12,6 +12,7 @@ using POGOProtos.Enums; using POGOProtos.Networking.Responses; using System.Net.Sockets; +using System.Threading; namespace PoGo.NecroBot.Logic.Tasks { @@ -84,14 +85,15 @@ public static class SnipePokemonTask private static List snipeLocations = new List(); private static DateTime lastSnipe = DateTime.Now; - public static Task AsyncStart(Session session) + public static Task AsyncStart(Session session, CancellationToken cancellationToken = default(CancellationToken)) { - return Task.Run(() => Start(session)); + return Task.Run(() => Start(session, cancellationToken), cancellationToken); } - public static async Task Start(Session session) + public static async Task Start(Session session, CancellationToken cancellationToken) { while (true) { + cancellationToken.ThrowIfCancellationRequested(); try { TcpClient lClient = new TcpClient(); @@ -126,11 +128,11 @@ public static async Task Start(Session session) session.EventDispatcher.Send(new ErrorEvent { Message = ex.ToString() }); } - await Task.Delay(5000); + await Task.Delay(5000, cancellationToken); } } - private static async Task snipe(ISession session, IEnumerable pokemonIds, double latitude, double longitude) + private static async Task snipe(ISession session, IEnumerable pokemonIds, double latitude, double longitude, CancellationToken cancellationToken) { var currentLatitude = session.Client.CurrentLatitude; var currentLongitude = session.Client.CurrentLongitude; @@ -156,6 +158,8 @@ await session.Client.Player.UpdatePlayerLocation(currentLatitude, currentLongitu foreach (var pokemon in catchablePokemon) { + cancellationToken.ThrowIfCancellationRequested(); + await session.Client.Player.UpdatePlayerLocation(latitude, longitude, session.Client.CurrentAltitude); var encounter = session.Client.Encounter.EncounterPokemon(pokemon.EncounterId, pokemon.SpawnPointId).Result; @@ -195,14 +199,14 @@ await session.Client.Player.UpdatePlayerLocation(currentLatitude, currentLongitu !Equals(catchablePokemon.ElementAtOrDefault(catchablePokemon.Count() - 1), pokemon)) { - await Task.Delay(session.LogicSettings.DelayBetweenPokemonCatch); + await Task.Delay(session.LogicSettings.DelayBetweenPokemonCatch, cancellationToken); } } - await Task.Delay(session.LogicSettings.DelayBetweenPlayerActions); + await Task.Delay(session.LogicSettings.DelayBetweenPlayerActions, cancellationToken); } - public static async Task Execute(ISession session) + public static async Task Execute(ISession session, CancellationToken cancellationToken) { if (lastSnipe.AddMilliseconds(session.LogicSettings.MinDelayBetweenSnipes) > DateTime.Now) return; @@ -232,7 +236,7 @@ public static async Task Execute(ISession session) { session.EventDispatcher.Send(new SnipeScanEvent() { Bounds = new Location(location.latitude, location.longitude) }); - await snipe(session, pokemonIds, location.latitude, location.longitude); + await snipe(session, pokemonIds, location.latitude, location.longitude, cancellationToken); locsVisited.Add(new PokemonLocation(location.latitude, location.longitude)); } } @@ -266,7 +270,7 @@ public static async Task Execute(ISession session) locsVisited.Add(pokemonLocation); - await snipe(session, pokemonIds, pokemonLocation.latitude, pokemonLocation.longitude); + await snipe(session, pokemonIds, pokemonLocation.latitude, pokemonLocation.longitude, cancellationToken); } } else diff --git a/PoGo.NecroBot.Logic/Tasks/TransferDuplicatePokemonTask.cs b/PoGo.NecroBot.Logic/Tasks/TransferDuplicatePokemonTask.cs index 48cc66703..23fe70c26 100644 --- a/PoGo.NecroBot.Logic/Tasks/TransferDuplicatePokemonTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/TransferDuplicatePokemonTask.cs @@ -1,6 +1,7 @@ #region using directives using System.Linq; +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Event; using PoGo.NecroBot.Logic.PoGoUtils; @@ -13,8 +14,10 @@ namespace PoGo.NecroBot.Logic.Tasks { public class TransferDuplicatePokemonTask { - public static async Task Execute(ISession session) + public static async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + var duplicatePokemons = await session.Inventory.GetDuplicatePokemonToTransfer(session.LogicSettings.KeepPokemonsThatCanEvolve, @@ -26,6 +29,8 @@ public static async Task Execute(ISession session) foreach (var duplicatePokemon in duplicatePokemons) { + cancellationToken.ThrowIfCancellationRequested(); + if (duplicatePokemon.Cp >= session.Inventory.GetPokemonTransferFilter(duplicatePokemon.PokemonId).KeepMinCp || PokemonInfo.CalculatePokemonPerfection(duplicatePokemon) > session.Inventory.GetPokemonTransferFilter(duplicatePokemon.PokemonId).KeepMinIvPercentage) diff --git a/PoGo.NecroBot.Logic/Tasks/UseIncubatorsTask.cs b/PoGo.NecroBot.Logic/Tasks/UseIncubatorsTask.cs index 02e554721..17c96b9c2 100644 --- a/PoGo.NecroBot.Logic/Tasks/UseIncubatorsTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/UseIncubatorsTask.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; using PoGo.NecroBot.Logic.Event; @@ -17,8 +18,10 @@ namespace PoGo.NecroBot.Logic.Tasks { internal class UseIncubatorsTask { - public static async Task Execute(ISession session) + public static async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + // Refresh inventory so that the player stats are fresh await session.Inventory.RefreshCachedInventory(); @@ -60,6 +63,8 @@ public static async Task Execute(ISession session) foreach (var incubator in incubators) { + cancellationToken.ThrowIfCancellationRequested(); + if (incubator.PokemonId == 0) { // Unlimited incubators prefer short eggs, limited incubators prefer long eggs diff --git a/PoGo.NecroBot.Logic/Tasks/UseNearbyPokestopsTask.cs b/PoGo.NecroBot.Logic/Tasks/UseNearbyPokestopsTask.cs index 29cd49a37..da88a9b0b 100644 --- a/PoGo.NecroBot.Logic/Tasks/UseNearbyPokestopsTask.cs +++ b/PoGo.NecroBot.Logic/Tasks/UseNearbyPokestopsTask.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using PoGo.NecroBot.Logic.Event; using PoGo.NecroBot.Logic.State; @@ -20,12 +21,16 @@ internal class UseNearbyPokestopsTask //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(ISession session) + public static async Task Execute(ISession session, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + var pokestopList = await GetPokeStops(session); while (pokestopList.Any()) { + cancellationToken.ThrowIfCancellationRequested(); + pokestopList = pokestopList.OrderBy( i => @@ -53,11 +58,11 @@ public static async Task Execute(ISession session) }); } - await RecycleItemsTask.Execute(session); + await RecycleItemsTask.Execute(session, cancellationToken); if (session.LogicSettings.TransferDuplicatePokemon) { - await TransferDuplicatePokemonTask.Execute(session); + await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } } } diff --git a/PoGo.NecroBot.Logic/Utils/EggWalker.cs b/PoGo.NecroBot.Logic/Utils/EggWalker.cs index bd7b9c618..fae71cfbf 100644 --- a/PoGo.NecroBot.Logic/Utils/EggWalker.cs +++ b/PoGo.NecroBot.Logic/Utils/EggWalker.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; using PoGo.NecroBot.Logic.State; using PoGo.NecroBot.Logic.Tasks; @@ -17,15 +18,17 @@ public EggWalker(double checkIncubatorsIntervalMeters, ISession session) _session = session; } - public async Task ApplyDistance(double distanceTraveled) + public async Task ApplyDistance(double distanceTraveled, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + if (!_session.LogicSettings.UseEggIncubators) return; _distanceTraveled += distanceTraveled; if (_distanceTraveled > _checkInterval) { - await UseIncubatorsTask.Execute(_session); + await UseIncubatorsTask.Execute(_session, cancellationToken); _distanceTraveled = 0; } }