public async Task <PlayerUpdateResponse> HumanLikeWalking(GeoCoordinate targetLocation, double walkingSpeedInKilometersPerHour, Func <Task> functionExecutedWhileWalking, bool fromgoogle = false) { var randomFactor = 0.5f; var randomMin = (int)(walkingSpeedInKilometersPerHour * (1 - randomFactor)); var randomMax = (int)(walkingSpeedInKilometersPerHour * (1 + randomFactor)); var RandomWalkSpeed = RandomDevice.Next(randomMin, randomMax); walkingSpeedInKilometersPerHour = RandomWalkSpeed; var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6; var sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude); var distanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation); Logger.ColoredConsoleWrite(ConsoleColor.DarkCyan, $"Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget / speedInMetersPerSecond:0.##} seconds!"); var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation); var nextWaypointDistance = speedInMetersPerSecond; var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing); //Initial walking var requestSendDateTime = DateTime.Now; var result = await _client.Player.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, waypoint.Altitude); if (functionExecutedWhileWalking != null) { await functionExecutedWhileWalking(); } var locatePokemonWhileWalkingDateTime = DateTime.Now; do { var millisecondsUntilGetUpdatePlayerLocationResponse = (DateTime.Now - requestSendDateTime).TotalMilliseconds; sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude); var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation); if (currentDistanceToTarget < 40) { if (speedInMetersPerSecond > SpeedDownTo) { Logger.ColoredConsoleWrite(ConsoleColor.DarkCyan, $"We are within 40 meters of the target. Slowing down to ~10 km/h to not pass the target."); speedInMetersPerSecond = SpeedDownTo; } } nextWaypointDistance = Math.Min(currentDistanceToTarget, millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond); nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation); waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing); requestSendDateTime = DateTime.Now; result = await _client.Player.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, waypoint.Altitude); if (functionExecutedWhileWalking != null) { await functionExecutedWhileWalking();// look for pokemon } await RandomHelper.RandomDelay(500, 600); }while ((LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30 && !fromgoogle) || LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 2); return(result); }
public override async Task Walk(IGeoLocation targetLocation, Func <Task> functionExecutedWhileWalking, ISession session, CancellationToken cancellationToken, double walkSpeed = 0.0) { cancellationToken.ThrowIfCancellationRequested(); TinyIoC.TinyIoCContainer.Current.Resolve <MultiAccountManager>().ThrowIfSwitchAccountRequested(); var destinaionCoordinate = new GeoCoordinate(targetLocation.Latitude, targetLocation.Longitude); //PlayerUpdateResponse result = null; if (CurrentWalkingSpeed <= 0) { CurrentWalkingSpeed = session.LogicSettings.WalkingSpeedInKilometerPerHour; } if (session.LogicSettings.UseWalkingSpeedVariant && walkSpeed == 0) { CurrentWalkingSpeed = session.Navigation.VariantRandom(session, CurrentWalkingSpeed); } var rw = new Random(); var speedInMetersPerSecond = (walkSpeed > 0 ? walkSpeed : CurrentWalkingSpeed) / 3.6; var sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude); LocationUtils.CalculateDistanceInMeters(sourceLocation, destinaionCoordinate); var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, destinaionCoordinate); var nextWaypointDistance = speedInMetersPerSecond; var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing); var requestSendDateTime = DateTime.Now; var requestVariantDateTime = DateTime.Now; LocationUtils.UpdatePlayerLocationWithAltitude(session, waypoint, (float)speedInMetersPerSecond); double SpeedVariantSec = rw.Next(1000, 10000); base.DoUpdatePositionEvent(session, waypoint.Latitude, waypoint.Longitude, walkSpeed, CurrentWalkingSpeed); do { cancellationToken.ThrowIfCancellationRequested(); TinyIoC.TinyIoCContainer.Current.Resolve <MultiAccountManager>().ThrowIfSwitchAccountRequested(); var millisecondsUntilGetUpdatePlayerLocationResponse = (DateTime.Now - requestSendDateTime).TotalMilliseconds; var millisecondsUntilVariant = (DateTime.Now - requestVariantDateTime).TotalMilliseconds; sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude); var currentDistanceToTarget = LocationUtils .CalculateDistanceInMeters(sourceLocation, destinaionCoordinate); //if (currentDistanceToTarget < 40) //{ // if (speedInMetersPerSecond > SpeedDownTo) // { // //Logger.Write("We are within 40 meters of the target. Speeding down to 10 km/h to not pass the target.", LogLevel.Info); // speedInMetersPerSecond = SpeedDownTo; // } //} if (session.LogicSettings.UseWalkingSpeedVariant && walkSpeed == 0) { CurrentWalkingSpeed = session.Navigation.VariantRandom(session, CurrentWalkingSpeed); speedInMetersPerSecond = CurrentWalkingSpeed / 3.6; } nextWaypointDistance = Math.Min(currentDistanceToTarget, millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond); nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, destinaionCoordinate); waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing); requestSendDateTime = DateTime.Now; LocationUtils.UpdatePlayerLocationWithAltitude(session, waypoint, (float)speedInMetersPerSecond); base.DoUpdatePositionEvent(session, waypoint.Latitude, waypoint.Longitude, CurrentWalkingSpeed); if (functionExecutedWhileWalking != null) { await functionExecutedWhileWalking(); // look for pokemon & hit stops } } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, destinaionCoordinate) >= 2); }
private async Task ExecuteFarmingPokestopsAndPokemons(bool path) { if (!path) { await ExecuteFarmingPokestopsAndPokemons(); } else { var tracks = GetGpxTracks(); var curTrkPt = 0; var curTrk = 0; var maxTrk = tracks.Count - 1; var curTrkSeg = 0; while (curTrk <= maxTrk) { var track = tracks.ElementAt(curTrk); var trackSegments = track.Segments; var maxTrkSeg = trackSegments.Count - 1; while (curTrkSeg <= maxTrkSeg) { var trackPoints = track.Segments.ElementAt(0).TrackPoints; var maxTrkPt = trackPoints.Count - 1; while (curTrkPt <= maxTrkPt) { var nextPoint = trackPoints.ElementAt(curTrkPt); var distanceCheck = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, Convert.ToDouble(nextPoint.Lat), Convert.ToDouble(nextPoint.Lon)); if (distanceCheck > 5000) { Logger.Write( $"Your desired destination of {nextPoint.Lat}, {nextPoint.Lon} is too far from your current position of {_client.CurrentLat}, {_client.CurrentLng}", LogLevel.Error); break; } Logger.Write( $"Your desired destination is {nextPoint.Lat}, {nextPoint.Lon} your location is {_client.CurrentLat}, {_client.CurrentLng}", LogLevel.Warning); if (_clientSettings.UseLuckyEggs) { await UseLuckyEgg(); } if (_clientSettings.UseIncense) { await UseIncense(); } if (!_clientSettings.GPXIgnorePokemon) { await ExecuteCatchAllNearbyPokemons(); } if (!_clientSettings.GPXIgnorePokestops) { var pokeStops = await _inventory.GetPokestops(); var pokestopList = pokeStops.ToList(); while (pokestopList.Any()) { pokestopList = pokestopList.OrderBy( i => LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude)).ToList(); var pokeStop = pokestopList.First(); pokestopList.Remove(pokeStop); var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokeStop.Latitude, pokeStop.Longitude); var fortInfo = await _client.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude); Logger.Write($"Name: {fortInfo.Name} in {distance:0.##} m distance", LogLevel.Pokestop); if (_client.Settings.DebugMode) { Logger.Write($"Latitude: {pokeStop.Latitude} - Longitude: {pokeStop.Longitude}", LogLevel.Debug); } 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 _client.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 (_client.Settings.DebugMode) { Logger.Write($"Seems your Soft-Banned. Trying to Unban via Pokestop Spins. Retry {fortTry} of {retryNumber}", LogLevel.Warning); } await RandomHelper.RandomDelay(75, 100); } else { _stats.AddExperience(fortSearch.ExperienceAwarded); _stats.UpdateConsoleTitle(_client, _inventory); var eggReward = fortSearch.PokemonDataEgg != null ? "1" : "0"; Logger.Write($"XP: {fortSearch.ExperienceAwarded}, Gems: {fortSearch.GemsAwarded}, Eggs: {eggReward}, Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}", LogLevel.Pokestop); _recycleCounter++; 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 (_recycleCounter >= 5) { await RecycleItems(); } } } if (!_clientSettings.GPXIgnorePokemon) { await _navigation.HumanPathWalking(trackPoints.ElementAt(curTrkPt), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons); } else { await _navigation.HumanPathWalking(trackPoints.ElementAt(curTrkPt), _clientSettings.WalkingSpeedInKilometerPerHour, null); } if (curTrkPt >= maxTrkPt) { curTrkPt = 0; } else { curTrkPt++; } } //end trkpts if (curTrkSeg >= maxTrkSeg) { curTrkSeg = 0; } else { curTrkSeg++; } } //end trksegs if (curTrk >= maxTrkSeg) { curTrk = 0; } else { curTrk++; } } //end tracks } }
public static async Task Execute(ISession session, CancellationToken cancellationToken, PokemonId priority = PokemonId.Missingno, bool sessionAllowTransfer = true) { var manager = TinyIoCContainer.Current.Resolve <MultiAccountManager>(); manager.ThrowIfSwitchAccountRequested(); cancellationToken.ThrowIfCancellationRequested(); if (!session.LogicSettings.CatchPokemon) { return; } var totalBalls = (await session.Inventory.GetItems().ConfigureAwait(false)).Where(x => x.ItemId == ItemId.ItemPokeBall || x.ItemId == ItemId.ItemGreatBall || x.ItemId == ItemId.ItemUltraBall).Sum(x => x.Count); if (session.SaveBallForByPassCatchFlee && totalBalls < 130) { return; } if (session.Stats.CatchThresholdExceeds(session)) { if (manager.AllowMultipleBot() && session.LogicSettings.MultipleBotConfig.SwitchOnCatchLimit && manager.AllowSwitch() ) { throw new ActiveSwitchByRuleException() { MatchedRule = SwitchRules.CatchLimitReached, ReachedValue = session.LogicSettings.CatchPokemonLimit }; } return; } Logger.Write(session.Translation.GetTranslation(TranslationString.LookingForPokemon), LogLevel.Debug); var nearbyPokemons = await GetNearbyPokemons(session).ConfigureAwait(false); if (nearbyPokemons == null) { return; } var priorityPokemon = nearbyPokemons.Where(p => p.PokemonId == priority).FirstOrDefault(); var pokemons = nearbyPokemons.Where(p => p.PokemonId != priority).ToList(); //add pokemons to map OnPokemonEncounterEvent(pokemons.ToList()); EncounterResponse encounter = null; //if that is snipe pokemon and inventories if full, execute transfer to get more room for pokemon if (priorityPokemon != null) { pokemons.Insert(0, priorityPokemon); await LocationUtils.UpdatePlayerLocationWithAltitude(session, new GeoCoordinate(priorityPokemon.Latitude, priorityPokemon.Longitude, session.Client.CurrentAltitude), 0).ConfigureAwait(false); // Set speed to 0 for random speed. encounter = await session.Client.Encounter .EncounterPokemon(priorityPokemon.EncounterId, priorityPokemon.SpawnPointId).ConfigureAwait(false); if (encounter.Status == EncounterResponse.Types.Status.PokemonInventoryFull) { if (session.LogicSettings.TransferDuplicatePokemon) { await TransferDuplicatePokemonTask.Execute(session, cancellationToken).ConfigureAwait(false); } if (session.LogicSettings.TransferWeakPokemon) { await TransferWeakPokemonTask.Execute(session, cancellationToken).ConfigureAwait(false); } if (session.LogicSettings.EvolveAllPokemonAboveIv || session.LogicSettings.EvolveAllPokemonWithEnoughCandy || session.LogicSettings.UseLuckyEggsWhileEvolving || session.LogicSettings.KeepPokemonsThatCanEvolve) { await EvolvePokemonTask.Execute(session, cancellationToken).ConfigureAwait(false); } } } foreach (var pokemon in pokemons) { await MSniperServiceTask.Execute(session, cancellationToken).ConfigureAwait(false); if (LocationUtils.CalculateDistanceInMeters(pokemon.Latitude, pokemon.Longitude, session.Client.CurrentLatitude, session.Client.CurrentLongitude) > session.Client.GlobalSettings.MapSettings.EncounterRangeMeters) { Logger.Debug($"THIS POKEMON IS TOO FAR, {pokemon.Latitude}, {pokemon.Longitude}"); continue; } cancellationToken.ThrowIfCancellationRequested(); TinyIoC.TinyIoCContainer.Current.Resolve <MultiAccountManager>().ThrowIfSwitchAccountRequested(); string pokemonUniqueKey = $"{pokemon.EncounterId}"; if (session.Cache.GetCacheItem(pokemonUniqueKey) != null) { continue; //this pokemon has been skipped because not meet with catch criteria before. } var allitems = await session.Inventory.GetItems().ConfigureAwait(false); var pokeBallsCount = allitems.FirstOrDefault(i => i.ItemId == ItemId.ItemPokeBall)?.Count; var greatBallsCount = allitems.FirstOrDefault(i => i.ItemId == ItemId.ItemGreatBall)?.Count; var ultraBallsCount = allitems.FirstOrDefault(i => i.ItemId == ItemId.ItemUltraBall)?.Count; var masterBallsCount = allitems.FirstOrDefault(i => i.ItemId == ItemId.ItemMasterBall)?.Count; masterBallsCount = masterBallsCount == null ? 0 : masterBallsCount; //return null ATM. need this code to logic check work if (pokeBallsCount + greatBallsCount + ultraBallsCount + masterBallsCount < session.LogicSettings.PokeballsToKeepForSnipe && session.CatchBlockTime < DateTime.Now) { session.CatchBlockTime = DateTime.Now.AddMinutes(session.LogicSettings.OutOfBallCatchBlockTime); Logger.Write(session.Translation.GetTranslation(TranslationString.CatchPokemonDisable, session.LogicSettings.OutOfBallCatchBlockTime, session.LogicSettings.PokeballsToKeepForSnipe)); return; } if (session.CatchBlockTime > DateTime.Now) { return; } if ((session.LogicSettings.UsePokemonToCatchLocallyListOnly && !session.LogicSettings.PokemonToCatchLocally.Pokemon.Contains(pokemon.PokemonId)) || (session.LogicSettings.UsePokemonToNotCatchFilter && session.LogicSettings.PokemonsNotToCatch.Contains(pokemon.PokemonId))) { Logger.Write(session.Translation.GetTranslation(TranslationString.PokemonSkipped, session.Translation.GetPokemonTranslation(pokemon.PokemonId))); continue; } var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, pokemon.Latitude, pokemon.Longitude); await Task.Delay(distance > 100? 500 : 100, cancellationToken).ConfigureAwait(false); //to avoid duplicated encounter when snipe priority pokemon if (encounter == null || encounter.Status != EncounterResponse.Types.Status.EncounterSuccess) { await LocationUtils.UpdatePlayerLocationWithAltitude(session, new GeoCoordinate(pokemon.Latitude, pokemon.Longitude, session.Client.CurrentAltitude), 0).ConfigureAwait(false); // Set speed to 0 for random speed. encounter = await session.Client.Encounter.EncounterPokemon(pokemon.EncounterId, pokemon.SpawnPointId).ConfigureAwait(false); } if (encounter.Status == EncounterResponse.Types.Status.EncounterSuccess && session.LogicSettings.CatchPokemon) { // Catch the Pokemon await CatchPokemonTask.Execute(session, cancellationToken, encounter, pokemon, currentFortData : null, sessionAllowTransfer : sessionAllowTransfer).ConfigureAwait(false); } else if (encounter.Status == EncounterResponse.Types.Status.PokemonInventoryFull) { if (session.LogicSettings.TransferDuplicatePokemon || session.LogicSettings.TransferWeakPokemon) { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.InvFullTransferring) }); if (session.LogicSettings.TransferDuplicatePokemon) { await TransferDuplicatePokemonTask.Execute(session, cancellationToken).ConfigureAwait(false); } if (session.LogicSettings.TransferWeakPokemon) { await TransferWeakPokemonTask.Execute(session, cancellationToken).ConfigureAwait(false); } if (session.LogicSettings.EvolveAllPokemonAboveIv || session.LogicSettings.EvolveAllPokemonWithEnoughCandy || session.LogicSettings.UseLuckyEggsWhileEvolving || session.LogicSettings.KeepPokemonsThatCanEvolve) { await EvolvePokemonTask.Execute(session, cancellationToken).ConfigureAwait(false); } } else { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.InvFullTransferManually) }); } } else { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.EncounterProblem, encounter.Status) }); } encounter = null; // 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, cancellationToken).ConfigureAwait(false); } } }
public static async Task Execute(ISession session, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var pokestopList = await GetPokeStops(session); var eggWalker = new EggWalker(1000, session); if (pokestopList.Count <= 0) { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.FarmPokestopsNoUsableFound) }); if (session.ForceMoveJustDone) { session.ForceMoveJustDone = false; } if (session.ForceMoveTo != null) { await ForceMoveTask.Execute(session, cancellationToken); } await Task.Delay(60000, cancellationToken); await session.Navigation.Move(new GeoCoordinate(session.Client.CurrentLatitude + session.Client.rnd.NextInRange(-0.0001, 0.0001), session.Client.CurrentLongitude + session.Client.rnd.NextInRange(-0.0001, 0.0001)), session.LogicSettings.WalkingSpeedMin, session.LogicSettings.WalkingSpeedMax, async() => { // Catch normal map Pokemon await CatchNearbyPokemonsTask.Execute(session, cancellationToken); //Catch Incense Pokemon await CatchIncensePokemonsTask.Execute(session, cancellationToken); return(true); }, async() => { await UseNearbyPokestopsTask.Execute(session, cancellationToken); return(true); }, cancellationToken, session); pokestopList = await GetPokeStops(session); } session.EventDispatcher.Send(new PokeStopListEvent { Forts = pokestopList.Select(x => x.BaseFortData) }); while (pokestopList.Any()) { cancellationToken.ThrowIfCancellationRequested(); if (session.ForceMoveJustDone) { session.ForceMoveJustDone = false; } if (session.ForceMoveTo != null) { await ForceMoveTask.Execute(session, cancellationToken); } var newPokestopList = (await GetPokeStops(session)).OrderBy(i => LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, i.Latitude, i.Longitude)).Where(x => pokestopList.All(i => i.Id != x.Id) && LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, x.Latitude, x.Longitude) < session.LogicSettings.MaxTravelDistanceInMeters).ToList(); session.EventDispatcher.Send(new PokeStopListEvent { Forts = newPokestopList.Select(x => x.BaseFortData) }); pokestopList.AddRange(newPokestopList); var pokeStop = pokestopList.OrderBy(i => LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, i.Latitude, i.Longitude)).First(x => !session.MapCache.CheckPokestopUsed(x)); var tooFarPokestops = pokestopList.Where(i => LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, i.Latitude, i.Longitude) > session.LogicSettings.MaxTravelDistanceInMeters).ToList(); foreach (var tooFar in tooFarPokestops) { pokestopList.Remove(tooFar); } var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, 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 }); if (session.LogicSettings.Teleport) { await session.Client.Player.UpdatePlayerLocation(fortInfo.Latitude, fortInfo.Longitude, session.Client.Settings.DefaultAltitude); } else { await MoveToPokestop(session, cancellationToken, pokeStop); } if (!session.ForceMoveJustDone) { 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 var shownSoftBanMessage = false; do { cancellationToken.ThrowIfCancellationRequested(); if (session.MapCache.CheckPokestopUsed(pokeStop)) { break; //already used somehow } var fortSearch = await session.Client.Fort.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude); if (fortSearch.ExperienceAwarded > 0 && timesZeroXPawarded > 0) { timesZeroXPawarded = 0; } if (fortSearch.ExperienceAwarded == 0) { if (TimesZeroXPawarded == 0) { await MoveToPokestop(session, cancellationToken, pokeStop); } 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 (!shownSoftBanMessage || fortTry % 5 == 0) { session.EventDispatcher.Send(new FortFailedEvent { Name = fortInfo.Name, Try = fortTry, Max = retryNumber - zeroCheck }); shownSoftBanMessage = true; } if (session.LogicSettings.Teleport) { await Task.Delay(session.LogicSettings.DelaySoftbanRetry, cancellationToken); } else { await DelayingUtils.Delay(session.LogicSettings.DelayBetweenPlayerActions, 400); } } else { session.EventDispatcher.Send(new FortUsedEvent { Id = pokeStop.Id, Name = fortInfo.Name, Exp = fortSearch.ExperienceAwarded, Gems = fortSearch.GemsAwarded, Items = StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded), Latitude = pokeStop.Latitude, Longitude = pokeStop.Longitude, InventoryFull = fortSearch.Result == FortSearchResponse.Types.Result.InventoryFull }); session.EventDispatcher.Send(new InventoryNewItemsEvent() { Items = fortSearch.ItemsAwarded.ToItemList() }); session.MapCache.UsedPokestop(pokeStop); RuntimeSettings.StopsHit++; pokeStop.CooldownCompleteTimestampMS = DateTime.UtcNow.AddMinutes(5).ToUnixTime(); await CatchWildPokemonsTask.Execute(session, cancellationToken); 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 (session.LogicSettings.Teleport) { await Task.Delay(session.LogicSettings.DelayPokestop, cancellationToken); } else { await Task.Delay(1000, cancellationToken); } //Catch Lure Pokemon if (pokeStop.LureInfo != null) { await CatchLurePokemonsTask.Execute(session, pokeStop.BaseFortData, cancellationToken); } if (session.LogicSettings.Teleport) { await CatchNearbyPokemonsTask.Execute(session, cancellationToken); } await eggWalker.ApplyDistance(distance, cancellationToken); } if (session.LogicSettings.SnipeAtPokestops || session.LogicSettings.UseSnipeLocationServer) { await SnipePokemonTask.Execute(session, cancellationToken); } } }
public async Task <PlayerUpdateResponse> HumanLikeWalking(GeoCoordinate targetLocation, double walkingSpeedInKilometersPerHour, Func <Task> functionExecutedWhileWalking) { var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6; var sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng); var distanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation); Logger.ColoredConsoleWrite(ConsoleColor.DarkCyan, $"Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget / speedInMetersPerSecond:0.##} seconds!"); var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation); var nextWaypointDistance = speedInMetersPerSecond; var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing); //Initial walking var requestSendDateTime = DateTime.Now; var result = await _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, _client.getSettingHandle().DefaultAltitude); if (functionExecutedWhileWalking != null) { await functionExecutedWhileWalking(); } var locatePokemonWhileWalkingDateTime = DateTime.Now; do { var millisecondsUntilGetUpdatePlayerLocationResponse = (DateTime.Now - requestSendDateTime).TotalMilliseconds; sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng); var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation); if (currentDistanceToTarget < 30) { if (speedInMetersPerSecond > SpeedDownTo) { Logger.ColoredConsoleWrite(ConsoleColor.DarkCyan, $"We are within 30 meters of the target. Speeding down to ~10 km/h to not pass the target."); speedInMetersPerSecond = SpeedDownTo; } } nextWaypointDistance = Math.Min(currentDistanceToTarget, millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond); nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation); waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing); requestSendDateTime = DateTime.Now; result = await _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, _client.getSettingHandle().DefaultAltitude); // Look for pokemon's nearby while walking to destination. var millisecondsSinceLocatePokemonWhileWalking = (DateTime.Now - locatePokemonWhileWalkingDateTime).TotalMilliseconds; if (functionExecutedWhileWalking != null && (millisecondsSinceLocatePokemonWhileWalking >= 500)) { //var timeInSeconds = millisecondsSinceLocatePokemonWhileWalking / 1000; //Logger.ColoredConsoleWrite(ConsoleColor.White, $"Searched for pokemons! Last request was done {timeInSeconds} seconds ago"); locatePokemonWhileWalkingDateTime = DateTime.Now; await functionExecutedWhileWalking(); } await Task.Delay(Math.Min((int)(distanceToTarget / speedInMetersPerSecond * 1000), 3000)); } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30); if (functionExecutedWhileWalking != null) { await functionExecutedWhileWalking(); } return(result); }
public double GetExistingAltitude(double lat, double lon) { //trying to find points closer then 5m from search loc return(_knownAltitude.FirstOrDefault(x => LocationUtils.CalculateDistanceInMeters(x.Lat, x.Lon, lat, lon) < 30)?.Alt ?? RandomExtensions.NextInRange(R, _session.Settings.DefaultAltitudeMin, _session.Settings.DefaultAltitudeMax)); }
/// <summary> /// Because this function sometime being called inside loop, return true it mean we don't want break look, false it mean not need to call this , break a loop from caller function /// </summary> /// <param name="session"></param> /// <param name="cancellationToken"></param> /// <param name="encounter"></param> /// <param name="pokemon"></param> /// <param name="currentFortData"></param> /// <param name="sessionAllowTransfer"></param> /// <returns></returns> public static async Task <bool> Execute(ISession session, CancellationToken cancellationToken, dynamic encounter, MapPokemon pokemon, FortData currentFortData, bool sessionAllowTransfer) { // If the encounter is null nothing will work below, so exit now if (encounter == null) { return(true); } // Exit if user defined max limits reached if (session.Stats.CatchThresholdExceeds(session)) { if (session.LogicSettings.MultipleBotConfig.SwitchOnCatchLimit) { throw new Exceptions.ActiveSwitchByRuleException() { MatchedRule = SwitchRules.CatchLimitReached, ReachedValue = session.LogicSettings.CatchPokemonLimit }; } return(false); } using (var block = new BlockableScope(session, Model.BotActions.Catch)) { if (!await block.WaitToRun()) { return(true); } AmountOfBerries = 0; cancellationToken.ThrowIfCancellationRequested(); float probability = encounter.CaptureProbability?.CaptureProbability_[0]; PokemonData encounteredPokemon; long unixTimeStamp; ulong _encounterId; string _spawnPointId; // Calling from CatchNearbyPokemonTask and SnipePokemonTask if (encounter is EncounterResponse && (encounter?.Status == EncounterResponse.Types.Status.EncounterSuccess)) { encounteredPokemon = encounter.WildPokemon?.PokemonData; unixTimeStamp = encounter.WildPokemon?.LastModifiedTimestampMs + encounter.WildPokemon?.TimeTillHiddenMs; _spawnPointId = encounter.WildPokemon?.SpawnPointId; _encounterId = encounter.WildPokemon?.EncounterId; } // Calling from CatchIncensePokemonTask else if (encounter is IncenseEncounterResponse && (encounter?.Result == IncenseEncounterResponse.Types.Result.IncenseEncounterSuccess)) { encounteredPokemon = encounter?.PokemonData; unixTimeStamp = pokemon.ExpirationTimestampMs; _spawnPointId = pokemon.SpawnPointId; _encounterId = pokemon.EncounterId; } // Calling from CatchLurePokemon else if (encounter is DiskEncounterResponse && encounter?.Result == DiskEncounterResponse.Types.Result.Success && !(currentFortData == null)) { encounteredPokemon = encounter?.PokemonData; unixTimeStamp = currentFortData.LureInfo.LureExpiresTimestampMs; _spawnPointId = currentFortData.Id; _encounterId = currentFortData.LureInfo.EncounterId; } else { return(true); // No success to work with, exit } // Check for pokeballs before proceeding var pokeball = await GetBestBall(session, encounteredPokemon, probability); if (pokeball == ItemId.ItemUnknown) { Logger.Write(session.Translation.GetTranslation(TranslationString.ZeroPokeballInv)); return(false); } // Calculate CP and IV var pokemonCp = encounteredPokemon?.Cp; var pokemonIv = PokemonInfo.CalculatePokemonPerfection(encounteredPokemon); var lv = PokemonInfo.GetLevel(encounteredPokemon); // Calculate distance away var latitude = encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Latitude : currentFortData.Latitude; var longitude = encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Longitude : currentFortData.Longitude; var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, latitude, longitude); if (session.LogicSettings.ActivateMSniper) { var newdata = new MSniperServiceTask.EncounterInfo(); newdata.EncounterId = _encounterId.ToString(); newdata.Iv = Math.Round(pokemonIv, 2); newdata.Latitude = latitude.ToString("G17", CultureInfo.InvariantCulture); newdata.Longitude = longitude.ToString("G17", CultureInfo.InvariantCulture); newdata.PokemonId = (int)(encounteredPokemon?.PokemonId ?? 0); newdata.PokemonName = encounteredPokemon?.PokemonId.ToString(); newdata.SpawnPointId = _spawnPointId; newdata.Move1 = PokemonInfo.GetPokemonMove1(encounteredPokemon).ToString(); newdata.Move2 = PokemonInfo.GetPokemonMove2(encounteredPokemon).ToString(); newdata.Expiration = unixTimeStamp; session.EventDispatcher.Send(newdata); } DateTime expiredDate = new DateTime(1970, 1, 1, 0, 0, 0).AddMilliseconds(Convert.ToDouble(unixTimeStamp)); var encounterEV = new EncounteredEvent() { Latitude = latitude, Longitude = longitude, PokemonId = encounteredPokemon.PokemonId, IV = pokemonIv, Level = (int)lv, Expires = expiredDate.ToUniversalTime(), ExpireTimestamp = unixTimeStamp, SpawnPointId = _spawnPointId, EncounterId = _encounterId.ToString(), Move1 = PokemonInfo.GetPokemonMove1(encounteredPokemon).ToString(), Move2 = PokemonInfo.GetPokemonMove2(encounteredPokemon).ToString(), }; //add catch to avoid snipe duplicate string uniqueCacheKey = $"{session.Settings.PtcUsername}{session.Settings.GoogleUsername}{Math.Round(encounterEV.Latitude, 6)}{encounterEV.PokemonId}{Math.Round(encounterEV.Longitude, 6)}"; session.Cache.Add(uniqueCacheKey, encounterEV, DateTime.Now.AddMinutes(15)); session.EventDispatcher.Send(encounterEV); if (IsNotMetWithCatchCriteria(session, encounteredPokemon, pokemonIv, lv, pokemonCp)) { session.EventDispatcher.Send(new NoticeEvent { Message = session.Translation.GetTranslation(TranslationString.PokemonSkipped, encounteredPokemon.PokemonId) }); session.Cache.Add(_encounterId.ToString(), encounteredPokemon, expiredDate); Logger.Write($"Filter catch not met. {encounteredPokemon.PokemonId.ToString()} IV {pokemonIv} lv {lv} {pokemonCp} move1 {PokemonInfo.GetPokemonMove1(encounteredPokemon)} move 2 {PokemonInfo.GetPokemonMove2(encounteredPokemon)}"); return(true); } ; CatchPokemonResponse caughtPokemonResponse = null; var lastThrow = CatchPokemonResponse.Types.CatchStatus.CatchSuccess; // Initializing lastThrow var attemptCounter = 1; // Main CatchPokemon-loop do { if ((session.LogicSettings.MaxPokeballsPerPokemon > 0 && attemptCounter > session.LogicSettings.MaxPokeballsPerPokemon)) { break; } pokeball = await GetBestBall(session, encounteredPokemon, probability); if (pokeball == ItemId.ItemUnknown) { session.EventDispatcher.Send(new NoPokeballEvent { Id = encounter is EncounterResponse ? pokemon.PokemonId : encounter?.PokemonData.PokemonId, Cp = encounteredPokemon.Cp }); return(false); } // Determine whether to use berries or not if (((session.LogicSettings.UseBerriesOperator.ToLower().Equals("and") && pokemonIv >= session.LogicSettings.UseBerriesMinIv && pokemonCp >= session.LogicSettings.UseBerriesMinCp && probability < session.LogicSettings.UseBerriesBelowCatchProbability) || (session.LogicSettings.UseBerriesOperator.ToLower().Equals("or") && ( pokemonIv >= session.LogicSettings.UseBerriesMinIv || pokemonCp >= session.LogicSettings.UseBerriesMinCp || probability < session.LogicSettings.UseBerriesBelowCatchProbability))) && lastThrow != CatchPokemonResponse.Types.CatchStatus.CatchMissed) // if last throw is a miss, no double berry { AmountOfBerries++; if (AmountOfBerries <= session.LogicSettings.MaxBerriesToUsePerPokemon) { await UseBerry(session, _encounterId, _spawnPointId, cancellationToken); } } bool hitPokemon = true; //default to excellent throw var normalizedRecticleSize = 1.95; //default spin var spinModifier = 1.0; //Humanized throws if (session.LogicSettings.EnableHumanizedThrows) { //thresholds: https://gist.github.com/anonymous/077d6dea82d58b8febde54ae9729b1bf var spinTxt = "Curve"; var hitTxt = "Excellent"; if (pokemonCp > session.LogicSettings.ForceExcellentThrowOverCp || pokemonIv > session.LogicSettings.ForceExcellentThrowOverIv) { normalizedRecticleSize = Random.NextDouble() * (1.95 - 1.7) + 1.7; } else if (pokemonCp >= session.LogicSettings.ForceGreatThrowOverCp || pokemonIv >= session.LogicSettings.ForceGreatThrowOverIv) { normalizedRecticleSize = Random.NextDouble() * (1.95 - 1.3) + 1.3; hitTxt = "Great"; } else { var regularThrow = 100 - (session.LogicSettings.ExcellentThrowChance + session.LogicSettings.GreatThrowChance + session.LogicSettings.NiceThrowChance); var rnd = Random.Next(1, 101); if (rnd <= regularThrow) { normalizedRecticleSize = Random.NextDouble() * (1 - 0.1) + 0.1; hitTxt = "Ordinary"; } else if (rnd <= regularThrow + session.LogicSettings.NiceThrowChance) { normalizedRecticleSize = Random.NextDouble() * (1.3 - 1) + 1; hitTxt = "Nice"; } else if (rnd <= regularThrow + session.LogicSettings.NiceThrowChance + session.LogicSettings.GreatThrowChance) { normalizedRecticleSize = Random.NextDouble() * (1.7 - 1.3) + 1.3; hitTxt = "Great"; } if (Random.NextDouble() * 100 > session.LogicSettings.CurveThrowChance) { spinModifier = 0.0; spinTxt = "Straight"; } } // Round to 2 decimals normalizedRecticleSize = Math.Round(normalizedRecticleSize, 2); // Missed throw check int missChance = Random.Next(1, 101); if (missChance <= session.LogicSettings.ThrowMissPercentage && session.LogicSettings.EnableMissedThrows) { hitPokemon = false; } Logger.Write($"(Threw ball) {hitTxt} throw, {spinTxt}-ball, HitPokemon = {hitPokemon}...", LogLevel.Debug); } caughtPokemonResponse = await session.Client.Encounter.CatchPokemon( encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.EncounterId : _encounterId, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.SpawnPointId : currentFortData.Id, pokeball, normalizedRecticleSize, spinModifier, hitPokemon); await session.Inventory.UpdateInventoryItem(pokeball, -1); var evt = new PokemonCaptureEvent() { Status = caughtPokemonResponse.Status, Latitude = latitude, Longitude = longitude }; lastThrow = caughtPokemonResponse.Status; // sets lastThrow status if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess) { var totalExp = 0; if (encounteredPokemon != null) { encounteredPokemon.Id = caughtPokemonResponse.CapturedPokemonId; await session.Inventory.AddPokemonToCache(encounteredPokemon); } foreach (var xp in caughtPokemonResponse.CaptureAward.Xp) { totalExp += xp; } var profile = await session.Client.Player.GetPlayer(); evt.Exp = totalExp; evt.Stardust = profile.PlayerData.Currencies.ToArray()[1].Amount; evt.UniqueId = caughtPokemonResponse.CapturedPokemonId; var pokemonSettings = await session.Inventory.GetPokemonSettings(); var pokemonFamilies = await session.Inventory.GetPokemonFamilies(); var setting = pokemonSettings.FirstOrDefault(q => pokemon != null && q.PokemonId == pokemon.PokemonId); var family = pokemonFamilies.FirstOrDefault(q => setting != null && q.FamilyId == setting.FamilyId); if (family != null) { await session.Inventory.UpdateCandy(family, caughtPokemonResponse.CaptureAward.Candy.Sum()); family.Candy_ += caughtPokemonResponse.CaptureAward.Candy.Sum(); evt.FamilyCandies = family.Candy_; } else { evt.FamilyCandies = caughtPokemonResponse.CaptureAward.Candy.Sum(); } if (session.LogicSettings.UseCatchLimit) { session.Stats.AddPokemonTimestamp(DateTime.Now.Ticks); Logger.Write($"(CATCH LIMIT) {session.Stats.GetNumPokemonsInLast24Hours()}/{session.LogicSettings.CatchPokemonLimit}", LogLevel.Info, ConsoleColor.Yellow); } } evt.CatchType = encounter is EncounterResponse ? session.Translation.GetTranslation(TranslationString.CatchTypeNormal) : encounter is DiskEncounterResponse ? session.Translation.GetTranslation(TranslationString.CatchTypeLure) : session.Translation.GetTranslation(TranslationString.CatchTypeIncense); evt.CatchTypeText = encounter is EncounterResponse ? "normal" : encounter is DiskEncounterResponse ? "lure" : "incense"; evt.Id = encounter is EncounterResponse ? pokemon.PokemonId : encounter?.PokemonData.PokemonId; evt.EncounterId = _encounterId; evt.Move1 = PokemonInfo.GetPokemonMove1(encounteredPokemon); evt.Move2 = PokemonInfo.GetPokemonMove2(encounteredPokemon); evt.Expires = pokemon?.ExpirationTimestampMs ?? 0; evt.SpawnPointId = _spawnPointId; evt.Level = PokemonInfo.GetLevel(encounteredPokemon); evt.Cp = encounteredPokemon.Cp; evt.MaxCp = PokemonInfo.CalculateMaxCp(encounteredPokemon); evt.Perfection = Math.Round(PokemonInfo.CalculatePokemonPerfection(encounteredPokemon)); evt.Probability = Math.Round(probability * 100, 2); evt.Distance = distance; evt.Pokeball = pokeball; evt.Attempt = attemptCounter; //await session.Inventory.RefreshCachedInventory(); evt.BallAmount = await session.Inventory.GetItemAmountByType(pokeball); evt.Rarity = PokemonGradeHelper.GetPokemonGrade(evt.Id).ToString(); session.EventDispatcher.Send(evt); attemptCounter++; DelayingUtils.Delay(session.LogicSettings.DelayBetweenPlayerActions, 0); } while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed || caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape); if (session.LogicSettings.AllowMultipleBot) { if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchFlee) { CatchFleeContinuouslyCount++; if (CatchFleeContinuouslyCount > session.LogicSettings.MultipleBotConfig.CatchFleeCount) { CatchFleeContinuouslyCount = 0; throw new ActiveSwitchByRuleException() { MatchedRule = SwitchRules.CatchFlee, ReachedValue = session.LogicSettings.MultipleBotConfig.CatchFleeCount }; } } else { //reset if not catch flee. CatchFleeContinuouslyCount = 0; } } session.Actions.RemoveAll(x => x == Model.BotActions.Catch); if (MultipleBotConfig.IsMultiBotActive(session.LogicSettings)) { ExecuteSwitcher(session, encounterEV); } if (session.LogicSettings.TransferDuplicatePokemonOnCapture && session.LogicSettings.TransferDuplicatePokemon && sessionAllowTransfer && caughtPokemonResponse != null && caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess) { if (session.LogicSettings.UseNearActionRandom) { await HumanRandomActionTask.TransferRandom(session, cancellationToken); } else { await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } } } return(true); }
public static async Task Execute(ISession session, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); //Refresh inventory so that the player stats are fresh //await session.Inventory.RefreshCachedInventory(); too much inventory refresh if (!session.LogicSettings.CatchWildPokemon) { return; } session.EventDispatcher.Send(new DebugEvent() { Message = session.Translation.GetTranslation(TranslationString.LookingForPokemon) }); var pokemons = await GetNearbyPokemons(session); if (session.LogicSettings.UsePokemonToNotCatchFilter) { pokemons = pokemons.Where(x => !session.LogicSettings.PokemonsNotToCatch.Contains(x.PokemonId)).ToList(); } session.EventDispatcher.Send(new PokemonsFoundEvent { Pokemons = pokemons.Select(x => x.BaseMapPokemon) }); foreach (var pokemon in pokemons) { cancellationToken.ThrowIfCancellationRequested(); var pokeBallsCount = await session.Inventory.GetItemAmountByType(ItemId.ItemPokeBall); var greatBallsCount = await session.Inventory.GetItemAmountByType(ItemId.ItemGreatBall); var ultraBallsCount = await session.Inventory.GetItemAmountByType(ItemId.ItemUltraBall); var masterBallsCount = await session.Inventory.GetItemAmountByType(ItemId.ItemMasterBall); if (pokeBallsCount + greatBallsCount + ultraBallsCount + masterBallsCount == 0) { session.EventDispatcher.Send(new NoticeEvent() { Message = session.Translation.GetTranslation(TranslationString.ZeroPokeballInv) }); return; } if (session.LogicSettings.UsePokemonToNotCatchFilter && session.LogicSettings.PokemonsNotToCatch.Contains(pokemon.PokemonId)) { if (!pokemon.Caught) { session.EventDispatcher.Send(new NoticeEvent() { Message = session.Translation.GetTranslation(TranslationString.PokemonSkipped, session.Translation.GetPokemonName(pokemon.PokemonId)) }); } pokemon.Caught = true; continue; } var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, pokemon.Latitude, pokemon.Longitude); await Task.Delay(distance > 100? 3000 : 500, cancellationToken); var encounter = await session.Client.Encounter.EncounterPokemon(pokemon.EncounterId, pokemon.SpawnPointId); try { switch (encounter.Status) { case EncounterResponse.Types.Status.EncounterSuccess: await CatchPokemonTask.Execute(session, encounter, pokemon, cancellationToken); break; case EncounterResponse.Types.Status.PokemonInventoryFull: if (session.LogicSettings.TransferDuplicatePokemon) { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.InvFullTransferring) }); await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } else { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.InvFullTransferManually) }); } break; default: session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.EncounterProblem, encounter.Status) }); break; } } catch (Exception) { session.EventDispatcher.Send(new WarnEvent { Message = "Error occured while trying to catch nearby pokemon" }); await Task.Delay(5000, cancellationToken); } session.EventDispatcher.Send(new PokemonDisappearEvent { Pokemon = pokemon.BaseMapPokemon }); // always wait the delay amount between catches, ideally to prevent you from making another call too early after a catch event await Task.Delay(session.LogicSettings.DelayBetweenPokemonCatch, cancellationToken); } return; }
//Please do not change GetPokeStops() in this file, it's specifically set //to only find stops within 40 meters for GPX pathing, as we are not going to the pokestops, //so do not make it more than 40 because it will never get close to those stops. //For non GPX pathing, it returns all pokestops in range. private static async Task <Tuple <List <FortData>, List <FortData> > > GetPokeStops(ISession session) { List <FortData> mapObjects = await UpdateFortsData(session); session.AddForts(mapObjects); if (!session.LogicSettings.UseGpxPathing) { if (mapObjects.Count <= 0) { // only send this for non GPX because otherwise we generate false positives session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.FarmPokestopsNoUsableFound) }); mapEmptyCount++; if (mapEmptyCount == 5) { mapEmptyCount = 0; throw new ActiveSwitchByRuleException() { MatchedRule = SwitchRules.EmptyMap, ReachedValue = 5 }; } } else { mapEmptyCount = 0; } var pokeStops = mapObjects.Where(p => p.Type == FortType.Checkpoint).ToList(); session.AddVisibleForts(pokeStops); session.EventDispatcher.Send(new PokeStopListEvent { Forts = mapObjects }); var gyms = mapObjects.Where(p => p.Type == FortType.Gym).ToList(); // session.EventDispatcher.Send(new PokeStopListEvent { Forts = mapObjects }); return(Tuple.Create(pokeStops, gyms)); } if (mapObjects.Count > 0) { // only send when there are stops for GPX because otherwise we send empty arrays often session.EventDispatcher.Send(new PokeStopListEvent { Forts = mapObjects }); } // Wasn't sure how to make this pretty. Edit as needed. return(Tuple.Create( mapObjects.Where( i => i.Type == FortType.Checkpoint && ( // Make sure PokeStop is within 40 meters or else it is pointless to hit it LocationUtils.CalculateDistanceInMeters( session.Client.CurrentLatitude, session.Client.CurrentLongitude, i.Latitude, i.Longitude) < 40) || session.LogicSettings.MaxTravelDistanceInMeters == 0 ).ToList(), mapObjects.Where(p => p.Type == FortType.Gym && LocationUtils.CalculateDistanceInMeters( session.Client.CurrentLatitude, session.Client.CurrentLongitude, p.Latitude, p.Longitude) < 40).ToList() )); }
public static async Task Execute(ISession session, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (!session.LogicSettings.CatchPokemon) { return; } Logger.Write(session.Translation.GetTranslation(TranslationString.LookingForPokemon), LogLevel.Debug); var pokemons = await GetNearbyPokemons(session); OnPokemonEncounterEvent(pokemons.ToList()); foreach (var pokemon in pokemons) { cancellationToken.ThrowIfCancellationRequested(); var allitems = await session.Inventory.GetItems(); var pokeBallsCount = allitems.FirstOrDefault(i => i.ItemId == ItemId.ItemPokeBall)?.Count; var greatBallsCount = allitems.FirstOrDefault(i => i.ItemId == ItemId.ItemGreatBall)?.Count; var ultraBallsCount = allitems.FirstOrDefault(i => i.ItemId == ItemId.ItemUltraBall)?.Count; var masterBallsCount = allitems.FirstOrDefault(i => i.ItemId == ItemId.ItemMasterBall)?.Count; /* * var pokeBallsCount = await session.Inventory.GetItemAmountByType(ItemId.ItemPokeBall); * var greatBallsCount = await session.Inventory.GetItemAmountByType(ItemId.ItemGreatBall); * var ultraBallsCount = await session.Inventory.GetItemAmountByType(ItemId.ItemUltraBall); * var masterBallsCount = await session.Inventory.GetItemAmountByType(ItemId.ItemMasterBall); */ if (pokeBallsCount + greatBallsCount + ultraBallsCount + masterBallsCount == 0) { Logger.Write(session.Translation.GetTranslation(TranslationString.ZeroPokeballInv)); return; } if ((session.LogicSettings.UsePokemonSniperFilterOnly && !session.LogicSettings.PokemonToSnipe.Pokemon.Contains(pokemon.PokemonId)) || (session.LogicSettings.UsePokemonToNotCatchFilter && session.LogicSettings.PokemonsNotToCatch.Contains(pokemon.PokemonId))) { Logger.Write(session.Translation.GetTranslation(TranslationString.PokemonSkipped, session.Translation.GetPokemonTranslation(pokemon.PokemonId))); continue; } var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, pokemon.Latitude, pokemon.Longitude); await Task.Delay(distance > 100? 500 : 100, cancellationToken); var encounter = await session.Client.Encounter.EncounterPokemon(pokemon.EncounterId, pokemon.SpawnPointId); if (encounter.Status == EncounterResponse.Types.Status.EncounterSuccess && session.LogicSettings.CatchPokemon) { await CatchPokemonTask.Execute(session, cancellationToken, encounter, pokemon); } else if (encounter.Status == EncounterResponse.Types.Status.PokemonInventoryFull) { if (session.LogicSettings.TransferDuplicatePokemon) { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.InvFullTransferring) }); await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } else { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.InvFullTransferManually) }); } } else { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(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, cancellationToken); } } }
internal void UpdateDistance(double lat, double lng) { Distance = LocationUtils.CalculateDistanceInMeters(lat, lng, Latitude, Longitude); RaisePropertyChanged("Distance"); }
public static async Task Execute(ISession session, CancellationToken cancellationToken, dynamic encounter, MapPokemon pokemon, FortData currentFortData = null, ulong encounterId = 0) { AmountOfBerries = 0; cancellationToken.ThrowIfCancellationRequested(); // If the encounter is null nothing will work below, so exit now if (encounter == null) { return; } float probability = encounter.CaptureProbability?.CaptureProbability_[0]; // Check for pokeballs before proceeding var pokeball = await GetBestBall(session, encounter, probability); if (pokeball == ItemId.ItemUnknown) { return; } //Calculate CP and IV var pokemonCp = encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData?.Cp : encounter.PokemonData?.Cp; var pokemonIv = PokemonInfo.CalculatePokemonPerfection(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData); // Calculate distance away var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Latitude : currentFortData.Latitude, encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Longitude : currentFortData.Longitude); CatchPokemonResponse caughtPokemonResponse; var attemptCounter = 1; do { if (session.LogicSettings.MaxPokeballsPerPokemon > 0 && attemptCounter > session.LogicSettings.MaxPokeballsPerPokemon) { break; } pokeball = await GetBestBall(session, encounter, probability); if (pokeball == ItemId.ItemUnknown) { session.EventDispatcher.Send(new NoPokeballEvent { Id = encounter is EncounterResponse ? pokemon.PokemonId : encounter?.PokemonData.PokemonId, Cp = (encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData?.Cp : encounter?.PokemonData?.Cp) ?? 0 }); return; } // Determine whether to use berries or not if ((session.LogicSettings.UseBerriesOperator.ToLower().Equals("and") && pokemonIv >= session.LogicSettings.UseBerriesMinIv && pokemonCp >= session.LogicSettings.UseBerriesMinCp && probability < session.LogicSettings.UseBerriesBelowCatchProbability) || (session.LogicSettings.UseBerriesOperator.ToLower().Equals("or") && ( pokemonIv >= session.LogicSettings.UseBerriesMinIv || pokemonCp >= session.LogicSettings.UseBerriesMinCp || probability < session.LogicSettings.UseBerriesBelowCatchProbability))) { AmountOfBerries++; if (AmountOfBerries <= session.LogicSettings.MaxBerriesToUsePerPokemon) { await UseBerry(session, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.EncounterId : encounterId, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.SpawnPointId : currentFortData?.Id); } } //default to excellent throw var normalizedRecticleSize = 1.95; //default spin var spinModifier = 1.0; //Humanized throws if (session.LogicSettings.EnableHumanizedThrows) { //thresholds: https://gist.github.com/anonymous/077d6dea82d58b8febde54ae9729b1bf var spinTxt = "Curve"; var hitTxt = "Excellent"; if (pokemonCp > session.LogicSettings.ForceExcellentThrowOverCp || pokemonIv > session.LogicSettings.ForceExcellentThrowOverIv) { normalizedRecticleSize = Random.NextDouble() * (1.95 - 1.7) + 1.7; } else if (pokemonCp >= session.LogicSettings.ForceGreatThrowOverCp || pokemonIv >= session.LogicSettings.ForceGreatThrowOverIv) { normalizedRecticleSize = Random.NextDouble() * (1.95 - 1.3) + 1.3; hitTxt = "Great"; } else { var regularThrow = 100 - (session.LogicSettings.ExcellentThrowChance + session.LogicSettings.GreatThrowChance + session.LogicSettings.NiceThrowChance); var rnd = Random.Next(1, 101); if (rnd <= regularThrow) { normalizedRecticleSize = Random.NextDouble() * (1 - 0.1) + 0.1; hitTxt = "Ordinary"; } else if (rnd <= regularThrow + session.LogicSettings.NiceThrowChance) { normalizedRecticleSize = Random.NextDouble() * (1.3 - 1) + 1; hitTxt = "Nice"; } else if (rnd <= regularThrow + session.LogicSettings.NiceThrowChance + session.LogicSettings.GreatThrowChance) { normalizedRecticleSize = Random.NextDouble() * (1.7 - 1.3) + 1.3; hitTxt = "Great"; } if (Random.NextDouble() * 100 > session.LogicSettings.CurveThrowChance) { spinModifier = 0.0; spinTxt = "Straight"; } } //round to 2 decimals normalizedRecticleSize = Math.Round(normalizedRecticleSize, 2); Logger.Write($"(Threw ball) {hitTxt} hit. {spinTxt}-ball...", LogLevel.Debug); } caughtPokemonResponse = await session.Client.Encounter.CatchPokemon( encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.EncounterId : encounterId, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.SpawnPointId : currentFortData.Id, pokeball, normalizedRecticleSize, spinModifier); var lat = encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Latitude : currentFortData.Latitude; var lng = encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Longitude : currentFortData.Longitude; var evt = new PokemonCaptureEvent { Status = caughtPokemonResponse.Status, Latitude = lat, Longitude = lng }; if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess) { var totalExp = 0; foreach (var xp in caughtPokemonResponse.CaptureAward.Xp) { totalExp += xp; } var profile = await session.Client.Player.GetPlayer(); evt.Exp = totalExp; evt.Stardust = profile.PlayerData.Currencies.ToArray()[1].Amount; var pokemonSettings = await session.Inventory.GetPokemonSettings(); var pokemonFamilies = await session.Inventory.GetPokemonFamilies(); var setting = pokemonSettings.FirstOrDefault(q => pokemon != null && q.PokemonId == pokemon.PokemonId); var family = pokemonFamilies.FirstOrDefault(q => setting != null && q.FamilyId == setting.FamilyId); if (family != null) { family.Candy_ += caughtPokemonResponse.CaptureAward.Candy.Sum(); evt.FamilyCandies = family.Candy_; } else { evt.FamilyCandies = caughtPokemonResponse.CaptureAward.Candy.Sum(); } if (session.LogicSettings.TransferDuplicatePokemonOnCapture && session.LogicSettings.TransferDuplicatePokemon) { await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } } evt.CatchType = encounter is EncounterResponse ? session.Translation.GetTranslation(TranslationString.CatchTypeNormal) : encounter is DiskEncounterResponse ? session.Translation.GetTranslation(TranslationString.CatchTypeLure) : session.Translation.GetTranslation(TranslationString.CatchTypeIncense); evt.Id = encounter is EncounterResponse ? pokemon.PokemonId : encounter?.PokemonData.PokemonId; evt.Level = PokemonInfo.GetLevel(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData); evt.Cp = encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData?.Cp : encounter?.PokemonData?.Cp ?? 0; evt.MaxCp = PokemonInfo.CalculateMaxCp(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData); evt.Perfection = Math.Round( PokemonInfo.CalculatePokemonPerfection(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData)); evt.Probability = Math.Round(probability * 100, 2); evt.Distance = distance; evt.Pokeball = pokeball; evt.Attempt = attemptCounter; await session.Inventory.RefreshCachedInventory(); evt.BallAmount = await session.Inventory.GetItemAmountByType(pokeball); session.EventDispatcher.Send(evt); attemptCounter++; DelayingUtils.Delay(session.LogicSettings.DelayBetweenPokemonCatch, 0); } while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed || caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape); }
public async Task <PlayerUpdateResponse> Walk(GeoCoordinate targetLocation, Func <Task <bool> > functionExecutedWhileWalking, ISession session, CancellationToken cancellationToken, double walkSpeed = 0.0) { var curLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude); var dist = LocationUtils.CalculateDistanceInMeters(curLocation, targetLocation); if (dist >= 100) { var nextWaypointDistance = dist * 70 / 100; var nextWaypointBearing = LocationUtils.DegreeBearing(curLocation, targetLocation); var waypoint = LocationUtils.CreateWaypoint(curLocation, nextWaypointDistance, nextWaypointBearing); var sentTime = DateTime.Now; var result = await LocationUtils.UpdatePlayerLocationWithAltitude(session, waypoint); UpdatePositionEvent?.Invoke(waypoint.Latitude, waypoint.Longitude); do { cancellationToken.ThrowIfCancellationRequested(); var millisecondsUntilGetUpdatePlayerLocationResponse = (DateTime.Now - sentTime).TotalMilliseconds; curLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude); var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(curLocation, targetLocation); dist = LocationUtils.CalculateDistanceInMeters(curLocation, targetLocation); if (dist >= 100) { nextWaypointDistance = dist * 70 / 100; } else { nextWaypointDistance = dist; } nextWaypointBearing = LocationUtils.DegreeBearing(curLocation, targetLocation); waypoint = LocationUtils.CreateWaypoint(curLocation, nextWaypointDistance, nextWaypointBearing); sentTime = DateTime.Now; result = await LocationUtils.UpdatePlayerLocationWithAltitude(session, waypoint); UpdatePositionEvent?.Invoke(waypoint.Latitude, waypoint.Longitude); if (functionExecutedWhileWalking != null) { await functionExecutedWhileWalking(); // look for pokemon } } while (LocationUtils.CalculateDistanceInMeters(curLocation, targetLocation) >= 10); return(result); } else { var result = await LocationUtils.UpdatePlayerLocationWithAltitude(session, targetLocation); UpdatePositionEvent?.Invoke(targetLocation.Latitude, targetLocation.Longitude); if (functionExecutedWhileWalking != null) { await functionExecutedWhileWalking(); // look for pokemon } return(result); } }
public static async Task Execute(ISession session, dynamic encounter, MapPokemon pokemon, FortData currentFortData = null, ulong encounterId = 0) { CatchPokemonResponse caughtPokemonResponse; var attemptCounter = 1; do { if (session.LogicSettings.MaxPokeballsPerPokemon > 0 && attemptCounter > session.LogicSettings.MaxPokeballsPerPokemon) { break; } float probability = encounter?.CaptureProbability?.CaptureProbability_[0]; var pokeball = await GetBestBall(session, encounter, probability); if (pokeball == ItemId.ItemUnknown) { session.EventDispatcher.Send(new NoPokeballEvent { Id = encounter is EncounterResponse ? pokemon.PokemonId : encounter?.PokemonData.PokemonId, Cp = (encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData?.Cp : encounter?.PokemonData?.Cp) ?? 0 }); return; } var isLowProbability = probability < 0.35; var isHighCp = encounter != null && (encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData?.Cp : encounter.PokemonData?.Cp) > 400; var isHighPerfection = PokemonInfo.CalculatePokemonPerfection(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData) >= session.LogicSettings.KeepMinIvPercentage; if ((isLowProbability && isHighCp) || isHighPerfection) { await UseBerry(session, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.EncounterId : encounterId, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.SpawnPointId : currentFortData?.Id); } var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Latitude : currentFortData.Latitude, encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Longitude : currentFortData.Longitude); caughtPokemonResponse = await session.Client.Encounter.CatchPokemon( encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.EncounterId : encounterId, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.SpawnPointId : currentFortData.Id, pokeball); var evt = new PokemonCaptureEvent { Status = caughtPokemonResponse.Status }; if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess) { var totalExp = 0; foreach (var xp in caughtPokemonResponse.CaptureAward.Xp) { totalExp += xp; } var profile = await session.Client.Player.GetPlayer(); evt.Exp = totalExp; evt.Stardust = profile.PlayerData.Currencies.ToArray()[1].Amount; var pokemonSettings = await session.Inventory.GetPokemonSettings(); var pokemonFamilies = await session.Inventory.GetPokemonFamilies(); var setting = pokemonSettings.FirstOrDefault(q => pokemon != null && q.PokemonId == pokemon.PokemonId); var family = pokemonFamilies.FirstOrDefault(q => setting != null && q.FamilyId == setting.FamilyId); if (family != null) { family.Candy_ += caughtPokemonResponse.CaptureAward.Candy.Sum(); evt.FamilyCandies = family.Candy_; } else { evt.FamilyCandies = caughtPokemonResponse.CaptureAward.Candy.Sum(); } } evt.CatchType = encounter is EncounterResponse ? session.Translation.GetTranslation(TranslationString.CatchTypeNormal) : encounter is DiskEncounterResponse ? session.Translation.GetTranslation(TranslationString.CatchTypeLure) : session.Translation.GetTranslation(TranslationString.CatchTypeIncense); evt.Id = encounter is EncounterResponse ? pokemon.PokemonId : encounter?.PokemonData.PokemonId; evt.Level = PokemonInfo.GetLevel(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData); evt.Cp = encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData?.Cp : encounter?.PokemonData?.Cp ?? 0; evt.MaxCp = PokemonInfo.CalculateMaxCp(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData); evt.Perfection = Math.Round( PokemonInfo.CalculatePokemonPerfection(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData)); evt.Probability = Math.Round(probability * 100, 2); evt.Distance = distance; evt.Pokeball = pokeball; evt.Attempt = attemptCounter; await session.Inventory.RefreshCachedInventory(); evt.BallAmount = await session.Inventory.GetItemAmountByType(pokeball); session.EventDispatcher.Send(evt); attemptCounter++; DelayingUtils.Delay(session.LogicSettings.DelayBetweenPokemonCatch, 2000); } while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed || caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape); }
public static async Task <FortData> GetNextPokeStop(ISession session) { var priorityTarget = await SetMoveToTargetTask.GetTarget(session).ConfigureAwait(false); if (priorityTarget != null) { return(priorityTarget); } if (session.Forts == null || session.Forts.Count == 0 || session.Forts.Count(p => p.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime()) == 0) { //TODO : A logic need to be add for handle this case? } ; var deployedPokemons = await session.Inventory.GetDeployedPokemons().ConfigureAwait(false); //NOTE : This code is killing perfomance of BOT if GYM is turn on, need to refactor to avoid this hummer call API var forts = session.Forts .Where(p => p.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime()) .Where(f => f.Type == FortType.Checkpoint || (session.LogicSettings.GymConfig.Enable && ( UseGymBattleTask.CanAttackGym(session, f, deployedPokemons) || UseGymBattleTask.CanTrainGym(session, f, deployedPokemons) || UseGymBattleTask.CanDeployToGym(session, f, deployedPokemons)))) .ToList(); if (session.LogicSettings.GymConfig.Enable && ((session.LogicSettings.GymConfig.EnableAttackGym && forts.Where(w => w.Type == FortType.Gym && UseGymBattleTask.CanAttackGym(session, w, deployedPokemons)).Count() == 0) || (session.LogicSettings.GymConfig.EnableGymTraining && forts.Where(w => w.Type == FortType.Gym && UseGymBattleTask.CanTrainGym(session, w, deployedPokemons)).Count() == 0) )) { //Logger.Write("No usable gym found. Trying to refresh list.", LogLevel.Gym, ConsoleColor.Magenta); await GetPokeStops(session).ConfigureAwait(false); } forts = forts.OrderBy( p => session.Navigation.WalkStrategy.CalculateDistance( session.Client.CurrentLatitude, session.Client.CurrentLongitude, p.Latitude, p.Longitude, session) ).ToList(); if (session.LogicSettings.UseGpxPathing) { forts = forts.Where(p => LocationUtils.CalculateDistanceInMeters(p.Latitude, p.Longitude, session.Client.CurrentLatitude, session.Client.CurrentLongitude) < 40).ToList(); } var reviveCount = (await session.Inventory.GetItems().ConfigureAwait(false)).Where(w => w.ItemId == POGOProtos.Inventory.Item.ItemId.ItemRevive || w.ItemId == POGOProtos.Inventory.Item.ItemId.ItemMaxRevive).Select(s => s.Count).Sum(); if (!session.LogicSettings.GymConfig.Enable || session.LogicSettings.GymConfig.MinRevivePotions > reviveCount /*|| session.Inventory.GetPlayerStats().FirstOrDefault().Level <= 5*/ ) { // Filter out the gyms forts = forts.Where(x => x.Type != FortType.Gym).ToList(); } else if (session.LogicSettings.GymConfig.PrioritizeGymOverPokestop) { // Prioritize gyms over pokestops var gyms = forts.Where(x => x.Type == FortType.Gym && LocationUtils.CalculateDistanceInMeters(x.Latitude, x.Longitude, session.Client.CurrentLatitude, session.Client.CurrentLongitude) < session.LogicSettings.GymConfig.MaxDistance); //.OrderBy(x => LocationUtils.CalculateDistanceInMeters(x.Latitude, x.Longitude, session.Client.CurrentLatitude, session.Client.CurrentLongitude)); if (session.LogicSettings.GymConfig.PrioritizeGymWithFreeSlot) { var freeSlots = gyms.Where(w => w.OwnedByTeam == session.Profile.PlayerData.Team && UseGymBattleTask.CanDeployToGym(session, w, deployedPokemons)); if (freeSlots.Count() > 0) { return(freeSlots.First()); } } // Return the first gym in range. if (gyms.Count() > 0) { return(gyms.FirstOrDefault()); } } return(forts.FirstOrDefault()); }
public FortData[] pathByNearestNeighbour(FortData[] pokeStops, double walkingSpeedInKilometersPerHour) { ////Start Gen. alg. //if (pokeStops.Length > 15) //{ // //Config // int ITERATIONS = 100000; // int POPSIZE = pokeStops.Length * 60; // double CROSSPROP = 99; // double MUTPROP = 20; // List<List<int>> population = new List<List<int>>(); // Random rnd = new Random(); // //Create Population // for (var i = POPSIZE; i > 0; --i) // { // List<int> tempChromosome = new List<int>(); // int items = rnd.Next(2, pokeStops.Length * 3 / 4); // do // { // int tempIndex = rnd.Next(0, pokeStops.Length - 1); // //Add only if new Index // while (tempChromosome.Exists(x => x == tempIndex)) // { // tempIndex = rnd.Next(0, pokeStops.Length - 1); // } // tempChromosome.Add(tempIndex); // } while (--items > 0); // if (calcFitness(ref pokeStops, tempChromosome, walkingSpeedInKilometersPerHour) > 0.0) // { // tempChromosome.Add(tempChromosome[0]); // population.Add(tempChromosome); // } // } // if (population.Count > 10) // { // for (int i = 0; i < ITERATIONS; ++i) // { // //Selection // var parents = selection(pokeStops, population, walkingSpeedInKilometersPerHour); // List<int> child1 = parents[0], child2 = parents[1]; // //Crossing // if (rnd.Next(0, 100) < CROSSPROP) // { // child1 = calcCrossing(parents[0], parents[1]); // child2 = calcCrossing(parents[1], parents[0]); // } // //Mutation // if (rnd.Next(0, 100) < MUTPROP) // { // mutate(ref child1); // } // if (rnd.Next(0, 100) < MUTPROP) // { // mutate(ref child2); // } // //Replace // List<int> fittnes = new List<int>(); // int sumPop = 0; // for (int c = 0; c < population.Count; ++c) // { // var temp = calcFitness(ref pokeStops, population[c], walkingSpeedInKilometersPerHour); // sumPop += temp; // fittnes.Add(temp); // } // List<int> fittnesSorted = new List<int>(fittnes); // fittnesSorted.Sort(); // if (fittnesSorted[0] <= calcFitness(ref pokeStops, child1, walkingSpeedInKilometersPerHour)) // { // var tempSelcetedChr = fittnes.FindIndex(x => x == fittnesSorted[0]); // population[tempSelcetedChr] = child1; // } // if (fittnesSorted[1] <= calcFitness(ref pokeStops, child2, walkingSpeedInKilometersPerHour)) // { // var tempSelcetedChr = fittnes.FindIndex(x => x == fittnesSorted[1]); // population[tempSelcetedChr] = child2; // } // //get best Generation // List<int> fittnes2 = new List<int>(); // for (int c = 0; c < population.Count; ++c) // { // var temp = calcFitness(ref pokeStops, population[c], walkingSpeedInKilometersPerHour); // fittnes2.Add(temp); // } // List<int> fittnesSorted2 = new List<int>(fittnes2); // fittnesSorted2.Sort(); // var tempSelcetedChr2 = fittnes2.FindIndex(x => x == fittnesSorted2[fittnesSorted2.Count - 1]); // List<FortData> newPokeStops = new List<FortData>(); // foreach (var element in population[tempSelcetedChr2]) // { // newPokeStops.Add(pokeStops[element]); // } // Logger.ColoredConsoleWrite(ConsoleColor.Yellow, $"{Math.Round(newPokeStops.Count * 3600 / calcTime(ref pokeStops, population[tempSelcetedChr2], walkingSpeedInKilometersPerHour))} PokeStops per Hour."); // return newPokeStops.ToArray(); // } // } //} //End gen. alg //Normal calculation for (var i = 1; i < pokeStops.Length - 1; i++) { var closest = i + 1; var cloestDist = LocationUtils.CalculateDistanceInMeters(pokeStops[i].Latitude, pokeStops[i].Longitude, pokeStops[closest].Latitude, pokeStops[closest].Longitude); for (var j = closest; j < pokeStops.Length; j++) { var initialDist = cloestDist; var newDist = LocationUtils.CalculateDistanceInMeters(pokeStops[i].Latitude, pokeStops[i].Longitude, pokeStops[j].Latitude, pokeStops[j].Longitude); if (initialDist > newDist) { cloestDist = newDist; closest = j; } } var tmpPok = pokeStops[closest]; pokeStops[closest] = pokeStops[i + 1]; pokeStops[i + 1] = tmpPok; } return(pokeStops); }
private static async Task FarmPokestop(ISession session, FortData pokeStop, FortDetailsResponse fortInfo, CancellationToken cancellationToken, bool doNotRetry = false) { var manager = TinyIoC.TinyIoCContainer.Current.Resolve <MultiAccountManager>(); // If the cooldown is in the future than don't farm the pokestop. if (pokeStop.CooldownCompleteTimestampMs > DateTime.UtcNow.ToUnixTime()) { return; } if (session.Stats.SearchThresholdExceeds(session, true)) { if (manager.AllowMultipleBot() && session.LogicSettings.MultipleBotConfig.SwitchOnPokestopLimit) { throw new Exceptions.ActiveSwitchByRuleException(SwitchRules.SpinPokestopReached, session.LogicSettings.PokeStopLimit); } return; } //await session.Client.Map.GetMapObjects().ConfigureAwait(false); FortSearchResponse fortSearch; var timesZeroXPawarded = 0; var fortTry = 0; //Current check int retryNumber = session.LogicSettings.ByPassSpinCount; //How many times it needs to check to clear softban int zeroCheck = Math.Min(5, retryNumber); //How many times it checks fort before it thinks it's softban var distance = LocationUtils.CalculateDistanceInMeters(pokeStop.Latitude, pokeStop.Longitude, session.Client.CurrentLatitude, session.Client.CurrentLongitude); if (distance > 30) { await LocationUtils.UpdatePlayerLocationWithAltitude(session, new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude), 0).ConfigureAwait(false); await session.Client.Misc.RandomAPICall().ConfigureAwait(false); } do { cancellationToken.ThrowIfCancellationRequested(); TinyIoC.TinyIoCContainer.Current.Resolve <MultiAccountManager>().ThrowIfSwitchAccountRequested(); int retry = 3; double latitude = pokeStop.Latitude; double longitude = pokeStop.Longitude; do { fortSearch = await session.Client.Fort.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude).ConfigureAwait(false); if (fortSearch.Result == FortSearchResponse.Types.Result.OutOfRange) { if (retry > 2) { await Task.Delay(500).ConfigureAwait(false); } else { await session.Client.Map.GetMapObjects(true).ConfigureAwait(false); } Logger.Debug($"Loot pokestop result: {fortSearch.Result}, distance to pokestop:[{pokeStop.Latitude}, {pokeStop.Longitude}] {distance:0.00}m, retry: #{4 - retry}"); latitude += 0.000003; longitude += 0.000005; await LocationUtils.UpdatePlayerLocationWithAltitude(session, new GeoCoordinate(latitude, longitude), 0).ConfigureAwait(false); retry--; } }while (fortSearch.Result == FortSearchResponse.Types.Result.OutOfRange && retry > 0); Logger.Debug($"Loot pokestop result: {fortSearch.Result}"); if (fortSearch.ExperienceAwarded > 0 && timesZeroXPawarded > 0) { timesZeroXPawarded = 0; } if (fortSearch.ExperienceAwarded == 0 && fortSearch.Result != FortSearchResponse.Types.Result.InventoryFull) { timesZeroXPawarded++; if (timesZeroXPawarded > zeroCheck) { if ((int)fortSearch.CooldownCompleteTimestampMs != 0) { break; // Check if successfully looted, if so program can continue as this was "false alarm". } fortTry += 1; session.EventDispatcher.Send(new FortFailedEvent { Name = fortInfo.Name, Try = fortTry, Max = retryNumber - zeroCheck, Looted = false }); if (doNotRetry) { break; } if (!session.LogicSettings.FastSoftBanBypass) { await DelayingUtils.DelayAsync(session.LogicSettings.DelayBetweenPlayerActions, 0, session.CancellationTokenSource.Token).ConfigureAwait(false); } } } else { softbanCount = 0; if (fortTry != 0) { session.EventDispatcher.Send(new FortFailedEvent { Name = fortInfo.Name, Try = fortTry + 1, Max = retryNumber - zeroCheck, Looted = true }); } session.EventDispatcher.Send(new FortUsedEvent { Id = pokeStop.Id, Name = fortInfo.Name, Exp = fortSearch.ExperienceAwarded, Gems = fortSearch.GemsAwarded, Items = StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded), Latitude = pokeStop.Latitude, Longitude = pokeStop.Longitude, Altitude = session.Client.CurrentAltitude, InventoryFull = fortSearch.Result == FortSearchResponse.Types.Result.InventoryFull, Fort = pokeStop }); if (fortSearch.Result == FortSearchResponse.Types.Result.Success) { mapEmptyCount = 0; foreach (var item in fortSearch.ItemsAwarded) { await session.Inventory.UpdateInventoryItem(item.ItemId).ConfigureAwait(false); } if (fortSearch.PokemonDataEgg != null) { fortSearch.PokemonDataEgg.IsEgg = true; } // Update the cache var fortFromCache = session.Client.Map.LastGetMapObjectResponse.MapCells.SelectMany(x => x.Forts).FirstOrDefault(f => f.Id == pokeStop.Id); long newCooldown = TimeUtil.GetCurrentTimestampInMilliseconds() + (5 * 60 * 1000); /* 5 min */ fortFromCache.CooldownCompleteTimestampMs = newCooldown; pokeStop.CooldownCompleteTimestampMs = newCooldown; if (session.SaveBallForByPassCatchFlee) { var totalBalls = (await session.Inventory.GetItems().ConfigureAwait(false)).Where(x => x.ItemId == ItemId.ItemPokeBall || x.ItemId == ItemId.ItemGreatBall || x.ItemId == ItemId.ItemUltraBall).Sum(x => x.Count); Logger.Write($"Ball requires for by pass catch flee {totalBalls}/{CatchPokemonTask.BALL_REQUIRED_TO_BYPASS_CATCHFLEE}"); } else { MSniperServiceTask.UnblockSnipe(false); } } if (fortSearch.Result == FortSearchResponse.Types.Result.InventoryFull) { await RecycleItemsTask.Execute(session, cancellationToken).ConfigureAwait(false); _storeRi = 1; } if (session.LogicSettings.UsePokeStopLimit) { session.Stats.AddPokestopTimestamp(DateTime.Now.Ticks); session.EventDispatcher.Send(new PokestopLimitUpdate(session.Stats.GetNumPokestopsInLast24Hours(), session.LogicSettings.PokeStopLimit)); } //add pokeStops to Map OnLootPokestopEvent(pokeStop); //end pokeStop to Map 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 (manager.AllowMultipleBot()) { if (fortTry >= retryNumber - zeroCheck) { softbanCount++; //only check if PokestopSoftbanCount > 0 if (MultipleBotConfig.IsMultiBotActive(session.LogicSettings, manager) && session.LogicSettings.MultipleBotConfig.PokestopSoftbanCount > 0 && session.LogicSettings.MultipleBotConfig.PokestopSoftbanCount <= softbanCount && TinyIoCContainer.Current.Resolve <MultiAccountManager>().AllowSwitch()) { softbanCount = 0; //Activate switcher by pokestop throw new ActiveSwitchByRuleException() { MatchedRule = SwitchRules.PokestopSoftban, ReachedValue = session.LogicSettings.MultipleBotConfig.PokestopSoftbanCount }; } } } else { softbanCount = 0; //reset softban count } if (session.LogicSettings.RandomlyPauseAtStops && !doNotRetry) { if (++_randomStop >= _randomNumber) { _randomNumber = _rc.Next(4, 11); _randomStop = 0; int randomWaitTime = _rc.Next(30, 120); await Task.Delay(randomWaitTime, cancellationToken).ConfigureAwait(false); } } }
public bool CheckForExistingAltitude(double lat, double lon) { var knownTemp = _knownAltitude.ToArray(); return(knownTemp.Any(x => LocationUtils.CalculateDistanceInMeters(x.Lat, x.Lon, lat, lon) < 30)); }
public void HumanLikeWalking(GeoCoordinate targetLocation, double walkingSpeedInKilometersPerHour, Func <bool> functionExecutedWhileWalking, bool fromgoogle = false, bool log = true) { /* removing random factors*/ /*const float randomFactor = 0.5f; * var randomMin = (int)(walkingSpeedInKilometersPerHour * (1 - randomFactor)); * var randomMax = (int)(walkingSpeedInKilometersPerHour * (1 + randomFactor)); * walkingSpeedInKilometersPerHour = RandomDevice.Next(randomMin, randomMax);*/ var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6; //Logger.Debug("speed In Meters Per Seconds to use: " + speedInMetersPerSecond); var sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude); var distanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation); //Logger.Debug($"Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget / speedInMetersPerSecond:0.##} seconds!"); //Logger.ColoredConsoleWrite(ConsoleColor.Green, $"Distance to target location at {distanceToTarget:0.##} meters will take {distanceToTarget / speedInMetersPerSecond:0.##} seconds at {speedInMetersPerSecond} m/s ({walkingSpeedInKilometersPerHour} Km/h)."); var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation); var nextWaypointDistance = speedInMetersPerSecond; var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing); //Initial walking var requestSendDateTime = DateTime.Now; LocationUtils.updatePlayerLocation(_client, waypoint.Latitude, waypoint.Longitude, waypoint.Altitude); if (functionExecutedWhileWalking != null) { functionExecutedWhileWalking(); } do { //update user location on map Task.Factory.StartNew(() => Logic.Instance.infoObservable.PushNewGeoLocations(new GeoCoordinate(waypoint.Latitude, waypoint.Longitude))); sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude); var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation); //Logger.Debug( $"Distance to destination: {currentDistanceToTarget.ToString("F", CultureInfo.InvariantCulture)}m " + // $"({speedInMetersPerSecond.ToString("F", CultureInfo.InvariantCulture)}m/s) " + // $"=> {(currentDistanceToTarget / speedInMetersPerSecond).ToString("F", CultureInfo.InvariantCulture)}s"); if (currentDistanceToTarget < 40) { if (speedInMetersPerSecond > SpeedDownTo) { Logger.Warning("We are within 40 meters of the target. Slowing down to ~10 km/h to not pass the target."); speedInMetersPerSecond = SpeedDownTo; } } var millisecondsUntilGetUpdatePlayerLocationResponse = (DateTime.Now - requestSendDateTime).TotalMilliseconds; nextWaypointDistance = Math.Min(currentDistanceToTarget, millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond); requestSendDateTime = DateTime.Now; nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation); waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing); SetCoordinates(waypoint.Latitude, waypoint.Longitude, waypoint.Altitude); if (functionExecutedWhileWalking != null && !_botSettings.PauseTheWalking) { functionExecutedWhileWalking(); } if (GlobalVars.SnipeOpts.Enabled) { Logic.Instance.sniperLogic.Execute((PokemonId)GlobalVars.SnipeOpts.ID, GlobalVars.SnipeOpts.Location); } //RandomHelper.RandomSleep(1000, 1200); }while ((LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30 && !fromgoogle) || LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 2 && fromgoogle); }
public static async Task <bool> Execute(ISession session, dynamic encounter, PokemonCacheItem pokemon, CancellationToken cancellationToken, FortData currentFortData = null, ulong encounterId = 0) { if (!await CheckBotStateTask.Execute(session, cancellationToken)) { return(false); } if (encounter is EncounterResponse && pokemon == null) { throw new ArgumentException("Parameter pokemon must be set, if encounter is of type EncounterResponse", nameof(pokemon)); } var prevState = session.State; session.State = BotState.Catch; var canUseBerry = true; CatchPokemonResponse caughtPokemonResponse; var attemptCounter = 1; do { if (session.LogicSettings.MaxPokeballsPerPokemon > 0 && attemptCounter > session.LogicSettings.MaxPokeballsPerPokemon) { break; } float probability = encounter?.CaptureProbability?.CaptureProbability_[0]; ItemId pokeball = await GetBestBall(session, encounter, probability); if (pokeball == ItemId.ItemUnknown) { session.EventDispatcher.Send(new NoPokeballEvent { Id = encounter is EncounterResponse ? pokemon.PokemonId : encounter?.PokemonData.PokemonId, Cp = (encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData?.Cp : encounter?.PokemonData?.Cp) ?? 0 }); session.State = prevState; return(false); } var useBerryBelowCatchProbability = session.LogicSettings.UseBerryBelowCatchProbability > 1 ? session.LogicSettings.UseBerryBelowCatchProbability / 100 : session.LogicSettings.UseBerryBelowCatchProbability; var isLowProbability = probability < useBerryBelowCatchProbability; var isHighCp = encounter != null && (encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData?.Cp : encounter.PokemonData?.Cp) > session.LogicSettings.UseBerryMinCp; var isHighPerfection = PokemonInfo.CalculatePokemonPerfection(encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData) >= session.LogicSettings.UseBerryMinIv; if (isLowProbability && ((session.LogicSettings.PrioritizeIvOverCp && isHighPerfection) || isHighCp) && canUseBerry) { await UseBerry(session, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.EncounterId : encounterId, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.SpawnPointId : currentFortData?.Id); canUseBerry = false; await DelayingUtils.Delay(session.LogicSettings.DelayBetweenPlayerActions, 1000); } var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Latitude : currentFortData.Latitude, encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Longitude : currentFortData.Longitude); double normalizedRecticleSize, spinModifier; if (session.LogicSettings.HumanizeThrows) { normalizedRecticleSize = Rng.NextInRange(session.LogicSettings.ThrowAccuracyMin, session.LogicSettings.ThrowAccuracyMax) * 1.85 + 0.1; // 0.1..1.95 if (normalizedRecticleSize > 1.95) { normalizedRecticleSize = 1.95; } else if (normalizedRecticleSize < 0.1) { normalizedRecticleSize = 0.1; } spinModifier = Rng.NextDouble() > session.LogicSettings.ThrowSpinFrequency ? 0.0 : 1.0; } else { normalizedRecticleSize = 1.95; spinModifier = 1.00; } Func <ItemId, string> returnRealBallName = a => { switch (a) { case ItemId.ItemPokeBall: return(session.Translation.GetTranslation(TranslationString.Pokeball)); case ItemId.ItemGreatBall: return(session.Translation.GetTranslation(TranslationString.GreatPokeball)); case ItemId.ItemUltraBall: return(session.Translation.GetTranslation(TranslationString.UltraPokeball)); case ItemId.ItemMasterBall: return(session.Translation.GetTranslation(TranslationString.MasterPokeball)); default: return(session.Translation.GetTranslation(TranslationString.CommonWordUnknown)); } }; Func <double, string> getThrowType = a => { if (a < 1.0) { return("Normal "); } if (a < 1.3) { return("Nice! "); } if (a < 1.7) { return("Great! "); } return(a > 1.6 ? "Excellent! " : "unknown "); }; var hit = Rng.NextDouble() > session.LogicSettings.MissChance; Logger.Write($"Throwing {(Math.Abs(spinModifier - 1) < 0.00001 ?"Spinning " : "" )}{getThrowType(normalizedRecticleSize)}{returnRealBallName(pokeball)} - {(hit ? "WILL HIT" : "WILL MISS")}", Logging.LogLevel.Caught, session: session); caughtPokemonResponse = await session.Client.Encounter.CatchPokemon( encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.EncounterId : encounterId, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.SpawnPointId : currentFortData.Id, pokeball, normalizedRecticleSize, spinModifier, hitPokemon : hit); session.EventDispatcher.Send(new ItemLostEvent { Id = pokeball, Count = 1 }); var lat = encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Latitude : currentFortData.Latitude; var lng = encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Longitude : currentFortData.Longitude; var evt = new PokemonCaptureEvent { Status = caughtPokemonResponse.Status, Latitude = lat, Longitude = lng }; if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess) { if (pokemon != null) { pokemon.Caught = true; } evt.Uid = caughtPokemonResponse.CapturedPokemonId; var totalExp = caughtPokemonResponse.CaptureAward.Xp.Sum(); var profile = await session.Client.Player.GetPlayer(); evt.Exp = totalExp; evt.Stardust = profile.PlayerData.Currencies.ToArray()[1].Amount; var pokemonSettings = await session.Inventory.GetPokemonSettings(); var pokemonFamilies = await session.Inventory.GetPokemonFamilies(); var setting = pokemonSettings.FirstOrDefault(q => q.PokemonId == pokemon?.PokemonId); var family = pokemonFamilies.FirstOrDefault(q => setting != null && q.FamilyId == setting.FamilyId); if (family != null) { family.Candy_ += caughtPokemonResponse.CaptureAward.Candy.Sum(); evt.Family = family.FamilyId; evt.FamilyCandies = family.Candy_; evt.Type1 = setting.Type; evt.Type2 = setting.Type2; evt.Stats = setting.Stats; PokemonData poke = encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData; if (poke != null) { evt.Stamina = poke.Stamina; evt.MaxStamina = poke.StaminaMax; } } else { evt.FamilyCandies = caughtPokemonResponse.CaptureAward.Candy.Sum(); } session.MapCache.PokemonCaught(pokemon); Logger.Write($"[Catch Dump] Caught {pokemon.PokemonId} - Coords[Lat: {lat} - Lng: {lng}]"); } else if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchFlee) { pokemon.Caught = true; } else if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape) { canUseBerry = true; } evt.CatchType = encounter is EncounterResponse ? session.Translation.GetTranslation(TranslationString.CatchTypeNormal) : encounter is DiskEncounterResponse ? session.Translation.GetTranslation(TranslationString.CatchTypeLure) : session.Translation.GetTranslation(TranslationString.CatchTypeIncense); evt.Id = encounter is EncounterResponse ? pokemon.PokemonId : encounter?.PokemonData.PokemonId; var pokeData = (encounter is EncounterResponse ? encounter.WildPokemon?.PokemonData : encounter?.PokemonData) as PokemonData; if (pokeData != null) { evt.Level = PokemonInfo.GetLevel(pokeData); evt.Cp = pokeData.Cp; evt.MaxCp = (int)PokemonInfo.GetMaxCpAtTrainerLevel(pokeData, session.Runtime.CurrentLevel); evt.Perfection = Math.Round(pokeData.CalculatePokemonPerfection(), 2); evt.Probability = Math.Round(probability * 100, 2); evt.Move1 = pokeData.Move1; evt.Move2 = pokeData.Move2; } evt.Distance = distance; evt.Pokeball = pokeball; evt.Attempt = attemptCounter; //await session.Inventory.RefreshCachedInventory(); evt.BallAmount = await session.Inventory.GetItemAmountByType(pokeball); session.EventDispatcher.Send(evt); attemptCounter++; await Task.Delay(session.LogicSettings.DelayCatchPokemon, cancellationToken); } while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed || caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape); session.State = prevState; return(true); }
public static async Task Execute(ISession session, CancellationToken cancellationToken) { var tracks = GetGpxTracks(session); var curTrkPt = 0; var curTrk = 0; var maxTrk = tracks.Count - 1; var curTrkSeg = 0; 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 { Message = session.Translation.GetTranslation(Common.TranslationString.DesiredDestTooFar, nextPoint.Lat, nextPoint.Lon, session.Client.CurrentLatitude, session.Client.CurrentLongitude) }); break; } var pokestopList = await GetPokeStops(session); session.EventDispatcher.Send(new PokeStopListEvent { Forts = pokestopList }); while (pokestopList.Any()) // warning: this is never entered due to ps cooldowns from UseNearbyPokestopsTask { cancellationToken.ThrowIfCancellationRequested(); pokestopList = pokestopList.OrderBy( i => LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, i.Latitude, i.Longitude)).ToList(); var pokeStop = pokestopList[0]; pokestopList.RemoveAt(0); var fortInfo = await session.Client.Fort.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude); if (pokeStop.LureInfo != null) { await CatchLurePokemonsTask.Execute(session, pokeStop, cancellationToken); } var fortSearch = await session.Client.Fort.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude); if (fortSearch.ExperienceAwarded > 0) { session.EventDispatcher.Send(new FortUsedEvent { Id = pokeStop.Id, Name = fortInfo.Name, Exp = fortSearch.ExperienceAwarded, Gems = fortSearch.GemsAwarded, Items = StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded), Latitude = pokeStop.Latitude, Longitude = pokeStop.Longitude }); } if (fortSearch.ItemsAwarded.Count > 0) { await session.Inventory.RefreshCachedInventory(); } } if (DateTime.Now > lastTasksCall) { lastTasksCall = DateTime.Now.AddMilliseconds(Math.Min(session.LogicSettings.DelayBetweenPlayerActions, 3000)); await RecycleItemsTask.Execute(session, cancellationToken); await ManualSnipePokemonTask.Execute(session, cancellationToken); if (session.LogicSettings.SnipeAtPokestops) { await SnipePokemonTask.Execute(session, cancellationToken); } if (session.LogicSettings.EvolveAllPokemonWithEnoughCandy || session.LogicSettings.EvolveAllPokemonAboveIv) { await EvolvePokemonTask.Execute(session, cancellationToken); } if (session.LogicSettings.TransferDuplicatePokemon) { await TransferDuplicatePokemonTask.Execute(session, cancellationToken); } if (session.LogicSettings.RenameAboveIv) { await RenamePokemonTask.Execute(session, cancellationToken); } } 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, cancellationToken); if (curTrkPt >= maxTrkPt) { curTrkPt = 0; } else { curTrkPt++; } } //end trkpts if (curTrkSeg >= maxTrkSeg) { curTrkSeg = 0; } else { curTrkSeg++; } } //end trksegs if (curTrk >= maxTrkSeg) { curTrk = 0; } else { curTrk++; } } //end tracks }
public static async Task <PlayerUpdateResponse> Execute(ISession session, CancellationToken cancellationToken, bool silent = false) { cancellationToken.ThrowIfCancellationRequested(); if (session.LogicSettings.UseEggIncubators && !session.EggWalker.Inited) { await session.EggWalker.InitEggWalker(cancellationToken); } var moveToCoords = session.ForceMoveTo; var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, moveToCoords.Latitude, moveToCoords.Longitude); if (!silent) { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.ForceMove, session.ForceMoveTo.Latitude, session.ForceMoveTo.Longitude, distance.ToString("N1")) }); } PlayerUpdateResponse result; session.ForceMoveToResume = session.ForceMoveTo; session.ForceMoveTo = null; session.State = BotState.Walk; if (session.LogicSettings.Teleport) { result = await session.Client.Player.UpdatePlayerLocation(moveToCoords.Latitude, moveToCoords.Longitude, session.Client.Settings.DefaultAltitude); } else { result = await session.Navigation.Move(new GeoCoordinate(moveToCoords.Latitude, moveToCoords.Longitude), session.LogicSettings.WalkingSpeedMin, session.LogicSettings.WalkingSpeedMax, async() => { // Catch normal map Pokemon await CatchNearbyPokemonsTask.Execute(session, cancellationToken); //Catch Incense Pokemon await CatchIncensePokemonsTask.Execute(session, cancellationToken); return(true); }, async() => { await UseNearbyPokestopsTask.Execute(session, cancellationToken, true); return(true); }, cancellationToken, session); } if (!silent) { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.ForceMoveDone) }); } session.State = BotState.Idle; session.ForceMoveJustDone = true; session.ForceMoveTo = null; session.ForceMoveToResume = null; session.EventDispatcher.Send(new ForceMoveDoneEvent()); if (session.LogicSettings.Teleport) { await Task.Delay(session.LogicSettings.DelayPokestop, cancellationToken); } else { await Task.Delay(1000, cancellationToken); } if (session.LogicSettings.SnipeAtPokestops || session.LogicSettings.UseSnipeLocationServer) { await SnipePokemonTask.Execute(session, cancellationToken); } return(result); }
public async Task <IState> Execute(ISession session, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var coordsPath = Path.Combine(session.LogicSettings.ProfileConfigPath, "LastPos.ini"); if (File.Exists(coordsPath)) { var latLngFromFile = LoadPositionFromDisk(session); if (latLngFromFile != null) { var distance = LocationUtils.CalculateDistanceInMeters(latLngFromFile.Item1, latLngFromFile.Item2, session.Settings.DefaultLatitude, session.Settings.DefaultLongitude); var lastModified = File.Exists(coordsPath) ? (DateTime?)File.GetLastWriteTime(coordsPath) : null; if (lastModified != null) { var hoursSinceModified = (DateTime.Now - lastModified).HasValue ? (double?)((DateTime.Now - lastModified).Value.Minutes / 60.0) : null; if (hoursSinceModified != null && hoursSinceModified != 0) { var kmph = distance / 1000 / (double)hoursSinceModified; if (kmph < 80) // If speed required to get to the default location is < 80km/hr { File.Delete(coordsPath); session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.RealisticTravelDetected) }); } else { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.NotRealisticTravel, kmph) }); } } } } } session.EventDispatcher.Send(new UpdatePositionEvent { Latitude = session.Client.CurrentLatitude, Longitude = session.Client.CurrentLongitude }); session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.WelcomeWarning, session.Client.CurrentLatitude, session.Client.CurrentLongitude), RequireInput = session.LogicSettings.StartupWelcomeDelay }); // Bugfix: Make sure to wait for keypress if (session.LogicSettings.StartupWelcomeDelay) { Console.ReadKey(); } if (session.LogicSettings.UseGoogleWalk && !session.LogicSettings.UseGpxPathing) { if (string.IsNullOrWhiteSpace(session.LogicSettings.GoogleApiKey)) { session.EventDispatcher.Send(new WarnEvent { Message = session.Translation.GetTranslation(TranslationString.GoogleAPIWarning) }); } } List <Int64> list = new List <Int64>(); // for pokestops try { var path = Path.Combine(session.LogicSettings.ProfileConfigPath, "PokestopTS.txt"); if (File.Exists(path)) { var content = File.ReadLines(path); foreach (var c in content) { if (c.Length > 0) { list.Add(Convert.ToInt64(c)); } } } } catch (Exception) { session.EventDispatcher.Send(new ErrorEvent { Message = "Garbage information in PokestopTS.txt" }); } foreach (var l in list) { session.Stats.PokeStopTimestamps.Add(l); } // for pokemons list = new List <Int64>(); try { var path = Path.Combine(session.LogicSettings.ProfileConfigPath, "PokemonTS.txt"); if (File.Exists(path)) { var content = File.ReadLines(path); foreach (var c in content) { if (c.Length > 0) { list.Add(Convert.ToInt64(c)); } } } } catch (Exception) { session.EventDispatcher.Send(new ErrorEvent { Message = "Garbage information in PokemonTS.txt" }); } foreach (var l in list) { session.Stats.PokemonTimestamps.Add(l); } await Task.Delay(100, cancellationToken); return(new InfoState()); }
public override double CalculateDistance(double sourceLat, double sourceLng, double destinationLat, double destinationLng, ISession session = null) { return(LocationUtils.CalculateDistanceInMeters(sourceLat, sourceLng, destinationLat, destinationLng)); }
public async Task <PlayerUpdateResponse> DoWalk(List <GeoCoordinate> points, ISession session, Func <Task <bool> > functionExecutedWhileWalking, GeoCoordinate sourceLocation, GeoCoordinate targetLocation, CancellationToken cancellationToken) { PlayerUpdateResponse result = null; var currentLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude, _client.CurrentAltitude); //filter google defined waypoints and remove those that are too near to the previous ones var waypointsDists = new Dictionary <Tuple <GeoCoordinate, GeoCoordinate>, double>(); var minWaypointsDistance = RandomizeStepLength(_minStepLengthInMeters); for (var i = 0; i < points.Count; i++) { if (i > 0) { var dist = LocationUtils.CalculateDistanceInMeters(points[i - 1], points[i]); waypointsDists[new Tuple <GeoCoordinate, GeoCoordinate>(points[i - 1], points[i])] = dist; } } var tooNearPoints = waypointsDists.Where(kvp => kvp.Value < minWaypointsDistance).Select(kvp => kvp.Key.Item1).ToList(); foreach (var tooNearPoint in tooNearPoints) { points.Remove(tooNearPoint); } if (points.Any()) //check if first waypoint is the current location (this is what google returns), in such case remove it! { var firstStep = points.First(); if (firstStep == currentLocation) { points.Remove(points.First()); } } var walkedPointsList = new List <GeoCoordinate>(); foreach (var nextStep in points) { currentLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude); if (_currentWalkingSpeed <= 0) { _currentWalkingSpeed = session.LogicSettings.WalkingSpeedInKilometerPerHour; } if (session.LogicSettings.UseWalkingSpeedVariant) { _currentWalkingSpeed = session.Navigation.VariantRandom(session, _currentWalkingSpeed); } var speedInMetersPerSecond = _currentWalkingSpeed / 3.6; var nextStepBearing = LocationUtils.DegreeBearing(currentLocation, nextStep); //particular steps are limited by minimal length, first step is calculated from the original speed per second (distance in 1s) var nextStepDistance = Math.Max(RandomizeStepLength(_minStepLengthInMeters), speedInMetersPerSecond); var waypoint = LocationUtils.CreateWaypoint(currentLocation, nextStepDistance, nextStepBearing); walkedPointsList.Add(waypoint); var previousLocation = currentLocation; //store the current location for comparison and correction purposes var requestSendDateTime = DateTime.Now; result = await LocationUtils.UpdatePlayerLocationWithAltitude(session, waypoint); var realDistanceToTarget = LocationUtils.CalculateDistanceInMeters(currentLocation, targetLocation); if (realDistanceToTarget < 30) { break; } do { cancellationToken.ThrowIfCancellationRequested(); var msToPositionChange = (DateTime.Now - requestSendDateTime).TotalMilliseconds; currentLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude); var currentDistanceToWaypoint = LocationUtils.CalculateDistanceInMeters(currentLocation, nextStep); realDistanceToTarget = LocationUtils.CalculateDistanceInMeters(currentLocation, targetLocation); var realSpeedinMperS = nextStepDistance / (msToPositionChange / 1000); var realDistanceWalked = LocationUtils.CalculateDistanceInMeters(previousLocation, currentLocation); //if the real calculated speed is lower than the one expected, we will raise the speed for the following step double speedRaise = 0; if (realSpeedinMperS < speedInMetersPerSecond) { speedRaise = speedInMetersPerSecond - realSpeedinMperS; } double distanceRaise = 0; if (realDistanceWalked < nextStepDistance) { distanceRaise = nextStepDistance - realDistanceWalked; } var realDistanceToTargetSpeedDown = LocationUtils.CalculateDistanceInMeters(currentLocation, targetLocation); if (realDistanceToTargetSpeedDown < 40) { if (speedInMetersPerSecond > SpeedDownTo) { speedInMetersPerSecond = SpeedDownTo; } } if (session.LogicSettings.UseWalkingSpeedVariant) { _currentWalkingSpeed = session.Navigation.VariantRandom(session, _currentWalkingSpeed); speedInMetersPerSecond = _currentWalkingSpeed / 3.6; } speedInMetersPerSecond += speedRaise; nextStepBearing = LocationUtils.DegreeBearing(currentLocation, nextStep); //setting next step distance is limited by the target and the next waypoint distance (we don't want to miss them) //also the minimal step length is used as we don't want to spend minutes jumping by cm lengths nextStepDistance = Math.Min(Math.Min(realDistanceToTarget, currentDistanceToWaypoint), //also add the distance raise (bot overhead corrections) to the normal step length Math.Max(RandomizeStepLength(_minStepLengthInMeters) + distanceRaise, (msToPositionChange / 1000) * speedInMetersPerSecond) + distanceRaise); waypoint = LocationUtils.CreateWaypoint(currentLocation, nextStepDistance, nextStepBearing); walkedPointsList.Add(waypoint); previousLocation = currentLocation; //store the current location for comparison and correction purposes requestSendDateTime = DateTime.Now; result = await LocationUtils.UpdatePlayerLocationWithAltitude(session, waypoint); UpdatePositionEvent?.Invoke(waypoint.Latitude, waypoint.Longitude); if (functionExecutedWhileWalking != null) { await functionExecutedWhileWalking(); // look for pokemon } } while (LocationUtils.CalculateDistanceInMeters(currentLocation, nextStep) >= 2); UpdatePositionEvent?.Invoke(nextStep.Latitude, nextStep.Longitude); } return(result); }
public static void RunBotWithParameters(Action <ISession, StatisticsAggregator> onBotStarted, string[] args) { var ioc = TinyIoC.TinyIoCContainer.Current; Application.EnableVisualStyles(); var strCulture = Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName; var culture = CultureInfo.CreateSpecificCulture("en"); CultureInfo.DefaultThreadCurrentCulture = culture; Thread.CurrentThread.CurrentCulture = culture; AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionEventHandler; Console.Title = @"NecroBot2"; Console.CancelKeyPress += (sender, eArgs) => { QuitEvent.Set(); eArgs.Cancel = true; }; // Command line parsing var commandLine = new Arguments(args); // Look for specific arguments values if (commandLine["subpath"] != null && commandLine["subpath"].Length > 0) { _subPath = commandLine["subpath"]; } if (commandLine["jsonvalid"] != null && commandLine["jsonvalid"].Length > 0) { switch (commandLine["jsonvalid"]) { case "true": _enableJsonValidation = true; break; case "false": _enableJsonValidation = false; break; } } if (commandLine["killswitch"] != null && commandLine["killswitch"].Length > 0) { switch (commandLine["killswitch"]) { case "true": _ignoreKillSwitch = false; break; case "false": _ignoreKillSwitch = true; break; } } bool excelConfigAllow = false; if (commandLine["provider"] != null && commandLine["provider"] == "excel") { excelConfigAllow = true; } Logger.AddLogger(new ConsoleLogger(LogLevel.Service), _subPath); Logger.AddLogger(new FileLogger(LogLevel.Service), _subPath); Logger.AddLogger(new WebSocketLogger(LogLevel.Service), _subPath); var profilePath = Path.Combine(Directory.GetCurrentDirectory(), _subPath); var profileConfigPath = Path.Combine(profilePath, "config"); var configFile = Path.Combine(profileConfigPath, "config.json"); var excelConfigFile = Path.Combine(profileConfigPath, "config.xlsm"); GlobalSettings settings; var boolNeedsSetup = false; if (File.Exists(configFile)) { // Load the settings from the config file settings = GlobalSettings.Load(_subPath, _enableJsonValidation); if (excelConfigAllow) { if (!File.Exists(excelConfigFile)) { Logger.Write( "Migrating existing json confix to excel config, please check the config.xlsm in your config folder" ); ExcelConfigHelper.MigrateFromObject(settings, excelConfigFile); } else { settings = ExcelConfigHelper.ReadExcel(settings, excelConfigFile); } Logger.Write("Bot will run with your excel config, loading excel config"); } } else { settings = new GlobalSettings { ProfilePath = profilePath, ProfileConfigPath = profileConfigPath, GeneralConfigPath = Path.Combine(Directory.GetCurrentDirectory(), "config"), ConsoleConfig = { TranslationLanguageCode = strCulture } }; boolNeedsSetup = true; } if (commandLine["latlng"] != null && commandLine["latlng"].Length > 0) { var crds = commandLine["latlng"].Split(','); try { var lat = double.Parse(crds[0]); var lng = double.Parse(crds[1]); settings.LocationConfig.DefaultLatitude = lat; settings.LocationConfig.DefaultLongitude = lng; } catch (Exception) { // ignored } } var lastPosFile = Path.Combine(profileConfigPath, "LastPos.ini"); if (File.Exists(lastPosFile) && settings.LocationConfig.StartFromLastPosition) { var text = File.ReadAllText(lastPosFile); var crds = text.Split(':'); try { var lat = double.Parse(crds[0]); var lng = double.Parse(crds[1]); settings.LocationConfig.DefaultLatitude = lat; settings.LocationConfig.DefaultLongitude = lng; } catch (Exception) { // ignored } } if (!_ignoreKillSwitch) { if (CheckKillSwitch() || CheckMKillSwitch()) { return; } } var logicSettings = new LogicSettings(settings); var translation = Translation.Load(logicSettings); TinyIoC.TinyIoCContainer.Current.Register <ITranslation>(translation); if (settings.GPXConfig.UseGpxPathing) { var xmlString = File.ReadAllText(settings.GPXConfig.GpxFile); var readgpx = new GpxReader(xmlString, translation); var nearestPt = readgpx.Tracks.SelectMany( (trk, trkindex) => trk.Segments.SelectMany( (seg, segindex) => seg.TrackPoints.Select( (pt, ptindex) => new { TrackPoint = pt, TrackIndex = trkindex, SegIndex = segindex, PtIndex = ptindex, Latitude = Convert.ToDouble(pt.Lat, CultureInfo.InvariantCulture), Longitude = Convert.ToDouble(pt.Lon, CultureInfo.InvariantCulture), Distance = LocationUtils.CalculateDistanceInMeters( settings.LocationConfig.DefaultLatitude, settings.LocationConfig.DefaultLongitude, Convert.ToDouble(pt.Lat, CultureInfo.InvariantCulture), Convert.ToDouble(pt.Lon, CultureInfo.InvariantCulture) ) } ) ) ) .OrderBy(pt => pt.Distance) .FirstOrDefault(pt => pt.Distance <= 5000); if (nearestPt != null) { settings.LocationConfig.DefaultLatitude = nearestPt.Latitude; settings.LocationConfig.DefaultLongitude = nearestPt.Longitude; settings.LocationConfig.ResumeTrack = nearestPt.TrackIndex; settings.LocationConfig.ResumeTrackSeg = nearestPt.SegIndex; settings.LocationConfig.ResumeTrackPt = nearestPt.PtIndex; } } IElevationService elevationService = new ElevationService(settings); //validation auth.config if (boolNeedsSetup) { AuthAPIForm form = new AuthAPIForm(true); if (form.ShowDialog() == DialogResult.OK) { settings.Auth.APIConfig = form.Config; } } else { var apiCfg = settings.Auth.APIConfig; if (apiCfg.UsePogoDevAPI) { if (string.IsNullOrEmpty(apiCfg.AuthAPIKey)) { Logger.Write( "You select pogodev API but not provide API Key, please press any key to exit and correct you auth.json, \r\n The Pogodev API key call be purchased at - https://talk.pogodev.org/d/51-api-hashing-service-by-pokefarmer", LogLevel.Error ); Console.ReadKey(); Environment.Exit(0); } } else if (apiCfg.UseLegacyAPI) { Logger.Write( "API 0.45 was shutdown by Niantic, bot no longer work with your current setup, please consider to use paid API instead.", LogLevel.Error ); Console.ReadLine(); Application.Exit(); #if RELEASE Thread.Sleep(15000); #endif } else { Logger.Write( "At least 1 authentication method is selected, please correct your auth.json, ", LogLevel.Error ); Console.ReadKey(); Environment.Exit(0); } } _session = new Session( new ClientSettings(settings, elevationService), logicSettings, elevationService, translation ); ioc.Register <ISession>(_session); Logger.SetLoggerContext(_session); if (boolNeedsSetup) { StarterConfigForm configForm = new StarterConfigForm(_session, settings, elevationService, configFile); if (configForm.ShowDialog() == DialogResult.OK) { var fileName = Assembly.GetExecutingAssembly().Location; Process.Start(fileName); Environment.Exit(0); } //if (GlobalSettings.PromptForSetup(_session.Translation)) //{ // _session = GlobalSettings.SetupSettings(_session, settings, elevationService, configFile); // var fileName = Assembly.GetExecutingAssembly().Location; // Process.Start(fileName); // Environment.Exit(0); //} else { GlobalSettings.Load(_subPath, _enableJsonValidation); Logger.Write("Press a Key to continue...", LogLevel.Warning); Console.ReadKey(); return; } if (excelConfigAllow) { ExcelConfigHelper.MigrateFromObject(settings, excelConfigFile); } } ProgressBar.Start("NecroBot2 is starting up", 10); if (settings.WebsocketsConfig.UseWebsocket) { var websocket = new WebSocketInterface(settings.WebsocketsConfig.WebSocketPort, _session); _session.EventDispatcher.EventReceived += evt => websocket.Listen(evt, _session); } ProgressBar.Fill(20); var machine = new StateMachine(); var stats = _session.RuntimeStatistics; ProgressBar.Fill(30); var strVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(4); stats.DirtyEvent += () => Console.Title = $"[Necrobot2 v{strVersion}] " + stats.GetTemplatedStats( _session.Translation.GetTranslation(TranslationString.StatsTemplateString), _session.Translation.GetTranslation(TranslationString.StatsXpTemplateString)); ProgressBar.Fill(40); var aggregator = new StatisticsAggregator(stats); if (onBotStarted != null) { onBotStarted(_session, aggregator); } ProgressBar.Fill(50); var listener = new ConsoleEventListener(); ProgressBar.Fill(60); var snipeEventListener = new SniperEventListener(); _session.EventDispatcher.EventReceived += evt => listener.Listen(evt, _session); _session.EventDispatcher.EventReceived += evt => aggregator.Listen(evt, _session); _session.EventDispatcher.EventReceived += evt => snipeEventListener.Listen(evt, _session); ProgressBar.Fill(70); machine.SetFailureState(new LoginState()); ProgressBar.Fill(80); ProgressBar.Fill(90); _session.Navigation.WalkStrategy.UpdatePositionEvent += (session, lat, lng, speed) => _session.EventDispatcher.Send(new UpdatePositionEvent { Latitude = lat, Longitude = lng, Speed = speed }); _session.Navigation.WalkStrategy.UpdatePositionEvent += LoadSaveState.SaveLocationToDisk; ProgressBar.Fill(100); var accountManager = new MultiAccountManager(logicSettings.Bots); var mainAccount = accountManager.Add(settings.Auth.AuthConfig); ioc.Register <MultiAccountManager>(accountManager); var bot = accountManager.GetStartUpAccount(); _session.ReInitSessionWithNextBot(bot); machine.AsyncStart(new VersionCheckState(), _session, _subPath, excelConfigAllow); try { Console.Clear(); } catch (IOException) { } if (settings.TelegramConfig.UseTelegramAPI) { _session.Telegram = new TelegramService(settings.TelegramConfig.TelegramAPIKey, _session); } if (_session.LogicSettings.UseSnipeLocationServer || _session.LogicSettings.HumanWalkingSnipeUsePogoLocationFeeder) { SnipePokemonTask.AsyncStart(_session); } if (_session.LogicSettings.EnableHumanWalkingSnipe && _session.LogicSettings.HumanWalkingSnipeUseFastPokemap) { // jjskuld - Ignore CS4014 warning for now. #pragma warning disable 4014 HumanWalkSnipeTask.StartFastPokemapAsync(_session, _session.CancellationTokenSource.Token); // that need to keep data live #pragma warning restore 4014 } if (_session.LogicSettings.DataSharingConfig.EnableSyncData) { BotDataSocketClient.StartAsync(_session); _session.EventDispatcher.EventReceived += evt => BotDataSocketClient.Listen(evt, _session); } settings.CheckProxy(_session.Translation); if (_session.LogicSettings.ActivateMSniper) { ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; //temporary disable MSniper connection because site under attacking. //MSniperServiceTask.ConnectToService(); //_session.EventDispatcher.EventReceived += evt => MSniperServiceTask.AddToList(evt); } var trackFile = Path.GetTempPath() + "\\necrobot2.io"; if (!File.Exists(trackFile) || File.GetLastWriteTime(trackFile) < DateTime.Now.AddDays(-1)) { Thread.Sleep(10000); Thread mThread = new Thread(delegate() { var infoForm = new InfoForm(); infoForm.ShowDialog(); }); File.WriteAllText(trackFile, DateTime.Now.Ticks.ToString()); mThread.SetApartmentState(ApartmentState.STA); mThread.Start(); } QuitEvent.WaitOne(); }
//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(ISession session, CancellationToken cancellationToken, bool sendPokeStopsEvent = false) { cancellationToken.ThrowIfCancellationRequested(); if (!await CheckBotStateTask.Execute(session, cancellationToken)) { return; } var pokestopList = await GetPokeStops(session); if (sendPokeStopsEvent) { session.EventDispatcher.Send(new PokeStopListEvent { Forts = pokestopList.Select(x => x.BaseFortData).ToList() }); } while (pokestopList.Any()) { cancellationToken.ThrowIfCancellationRequested(); pokestopList = pokestopList.OrderBy( i => LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, i.Latitude, i.Longitude)).ToList(); var pokeStop = pokestopList[0]; pokestopList.RemoveAt(0); if (pokeStop.Used) { continue; } if (!session.LogicSettings.LootPokestops) { session.MapCache.UsedPokestop(pokeStop, session); continue; } var fortInfo = await session.Client.Fort.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude); await DelayingUtils.Delay(session.LogicSettings.DelayBetweenPlayerActions, 2000); var fortSearch = await session.Client.Fort.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude); await DelayingUtils.Delay(session.LogicSettings.DelayPokestop, 5000); if (fortSearch.ExperienceAwarded > 0) { session.Runtime.StopsHit++; session.Runtime.PokestopsToCheckGym--; session.EventDispatcher.Send(new FortUsedEvent { Id = pokeStop.Id, Name = fortInfo.Name, Exp = fortSearch.ExperienceAwarded, Gems = fortSearch.GemsAwarded, Items = StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded), Latitude = pokeStop.Latitude, Longitude = pokeStop.Longitude }); session.MapCache.UsedPokestop(pokeStop, session); session.EventDispatcher.Send(new InventoryNewItemsEvent() { Items = fortSearch.ItemsAwarded.ToItemList() }); if (session.Runtime.PokeBallsToCollect > 0) { session.Runtime.PokeBallsToCollect -= fortSearch.ItemsAwarded.ToItemList() .Where(x => x.Item1 == ItemId.ItemPokeBall || x.Item1 == ItemId.ItemGreatBall || x.Item1 == ItemId.ItemUltraBall || x.Item1 == ItemId.ItemMasterBall).Sum(x => x.Item2); } } if (pokeStop.LureInfo != null) {//because we're all f*****g idiots for not catching this sooner await CatchLurePokemonsTask.Execute(session, pokeStop.BaseFortData, cancellationToken); } } }
private async Task ExecuteFarmingPokestopsAndPokemons() { var distanceFromStart = LocationUtils.CalculateDistanceInMeters( _clientSettings.DefaultLatitude, _clientSettings.DefaultLongitude, _client.CurrentLat, _client.CurrentLng); // Edge case for when the client somehow ends up outside the defined radius if (_clientSettings.MaxTravelDistanceInMeters != 0 && distanceFromStart > _clientSettings.MaxTravelDistanceInMeters) { Logger.Write( $"You're outside of your defined radius! Walking to start ({distanceFromStart:0.##}m away) in 5 seconds. Is your LastCoords.ini file correct?", LogLevel.Warning); await Task.Delay(5000); Logger.Write("Moving to start location now."); await _navigation.HumanLikeWalking( new GeoUtils(_clientSettings.DefaultLatitude, _clientSettings.DefaultLongitude), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons); } var pokeStops = await _inventory.GetPokestops(); var pokestopList = pokeStops.ToList(); if (pokestopList.Count <= 0) { Logger.Write("No usable PokeStops found in your area. Is your maximum distance too small?", LogLevel.Warning); } else { Logger.Write($"Found {pokeStops.Count()} {(pokeStops.Count() == 1 ? "Pokestop" : "Pokestops")}", LogLevel.Info); } while (pokestopList.Any()) { if (_clientSettings.UseLuckyEggs) { await UseLuckyEgg(); } if (_clientSettings.UseIncense) { await UseIncense(); } await ExecuteCatchAllNearbyPokemons(); pokestopList = pokestopList.OrderBy( i => LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude)).ToList(); var pokeStop = pokestopList.First(); pokestopList.Remove(pokeStop); var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokeStop.Latitude, pokeStop.Longitude); var fortInfo = await _client.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude); var latlngDebug = string.Empty; if (_clientSettings.DebugMode) { latlngDebug = $"| Latitude: {pokeStop.Latitude} - Longitude: {pokeStop.Longitude}"; } Logger.Write($"Name: {fortInfo.Name} in {distance:0.##} m distance {latlngDebug}", LogLevel.Pokestop); if (_clientSettings.UseTeleportInsteadOfWalking) { await _client.UpdatePlayerLocation(pokeStop.Latitude, pokeStop.Longitude, _clientSettings.DefaultAltitude); Logger.Write($"Using Teleport instead of Walking!", LogLevel.Debug); } else { await _navigation.HumanLikeWalking(new GeoUtils(pokeStop.Latitude, pokeStop.Longitude), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons); } 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 _client.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 (_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 { _stats.AddExperience(fortSearch.ExperienceAwarded); _stats.UpdateConsoleTitle(_client, _inventory); var eggReward = fortSearch.PokemonDataEgg != null ? "1" : "0"; Logger.Write($"XP: {fortSearch.ExperienceAwarded}, Gems: {fortSearch.GemsAwarded}, Eggs: {eggReward}, Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}", LogLevel.Pokestop); _recycleCounter++; 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 (_recycleCounter >= 5) { await RecycleItems(); } } }
/// <summary> /// Because this function sometime being called inside loop, return true it mean we don't want break look, false it mean not need to call this , break a loop from caller function /// </summary> /// <param name="session"></param> /// <param name="cancellationToken"></param> /// <param name="encounter"></param> /// <param name="pokemon"></param> /// <param name="currentFortData"></param> /// <param name="sessionAllowTransfer"></param> /// <returns></returns> public static async Task <bool> Execute(ISession session, CancellationToken cancellationToken, dynamic encounter, MapPokemon pokemon, FortData currentFortData, bool sessionAllowTransfer) { var manager = TinyIoCContainer.Current.Resolve <MultiAccountManager>(); manager.ThrowIfSwitchAccountRequested(); // If the encounter is null nothing will work below, so exit now if (encounter == null) { return(true); } var totalBalls = (await session.Inventory.GetItems().ConfigureAwait(false)).Where(x => x.ItemId == ItemId.ItemPokeBall || x.ItemId == ItemId.ItemGreatBall || x.ItemId == ItemId.ItemUltraBall).Sum(x => x.Count); if (session.SaveBallForByPassCatchFlee && totalBalls < BALL_REQUIRED_TO_BYPASS_CATCHFLEE) { return(false); } // Exit if user defined max limits reached if (session.Stats.CatchThresholdExceeds(session)) { if (manager.AllowMultipleBot() && session.LogicSettings.MultipleBotConfig.SwitchOnCatchLimit && TinyIoCContainer.Current.Resolve <MultiAccountManager>().AllowSwitch()) { throw new ActiveSwitchByRuleException() { MatchedRule = SwitchRules.CatchLimitReached, ReachedValue = session.LogicSettings.CatchPokemonLimit }; } return(false); } using (var block = new BlockableScope(session, BotActions.Catch)) { if (!await block.WaitToRun().ConfigureAwait(false)) { return(true); } AmountOfBerries = new Dictionary <ItemId, int>(); cancellationToken.ThrowIfCancellationRequested(); float probability = encounter.CaptureProbability?.CaptureProbability_[0]; PokemonData encounteredPokemon; long unixTimeStamp; ulong _encounterId; string _spawnPointId; // Calling from CatchNearbyPokemonTask and SnipePokemonTask if (encounter is EncounterResponse && (encounter?.Status == EncounterResponse.Types.Status.EncounterSuccess)) { encounteredPokemon = encounter.WildPokemon?.PokemonData; unixTimeStamp = encounter.WildPokemon?.LastModifiedTimestampMs + encounter.WildPokemon?.TimeTillHiddenMs; _spawnPointId = encounter.WildPokemon?.SpawnPointId; _encounterId = encounter.WildPokemon?.EncounterId; } // Calling from CatchIncensePokemonTask else if (encounter is IncenseEncounterResponse && (encounter?.Result == IncenseEncounterResponse.Types.Result.IncenseEncounterSuccess)) { encounteredPokemon = encounter?.PokemonData; unixTimeStamp = pokemon.ExpirationTimestampMs; _spawnPointId = pokemon.SpawnPointId; _encounterId = pokemon.EncounterId; } // Calling from CatchLurePokemon else if (encounter is DiskEncounterResponse && encounter?.Result == DiskEncounterResponse.Types.Result.Success && !(currentFortData == null)) { encounteredPokemon = encounter?.PokemonData; unixTimeStamp = currentFortData.LureInfo.LureExpiresTimestampMs; _spawnPointId = currentFortData.Id; _encounterId = currentFortData.LureInfo.EncounterId; } else { return(true); // No success to work with, exit } // Check for pokeballs before proceeding var pokeball = await GetBestBall(session, encounteredPokemon, probability).ConfigureAwait(false); if (pokeball == ItemId.ItemUnknown) { Logger.Write(session.Translation.GetTranslation(TranslationString.ZeroPokeballInv)); return(false); } // Calculate CP and IV var pokemonCp = encounteredPokemon?.Cp; var pokemonIv = PokemonInfo.CalculatePokemonPerfection(encounteredPokemon); var lv = PokemonInfo.GetLevel(encounteredPokemon); // Calculate distance away var latitude = encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Latitude : currentFortData.Latitude; var longitude = encounter is EncounterResponse || encounter is IncenseEncounterResponse ? pokemon.Longitude : currentFortData.Longitude; var distance = LocationUtils.CalculateDistanceInMeters(session.Client.CurrentLatitude, session.Client.CurrentLongitude, latitude, longitude); if (session.LogicSettings.ActivateMSniper) { var newdata = new MSniperServiceTask.EncounterInfo() { EncounterId = _encounterId.ToString(), Iv = Math.Round(pokemonIv, 2), Latitude = latitude.ToString("G17", CultureInfo.InvariantCulture), Longitude = longitude.ToString("G17", CultureInfo.InvariantCulture), PokemonId = (int)(encounteredPokemon?.PokemonId ?? 0), PokemonName = encounteredPokemon?.PokemonId.ToString(), SpawnPointId = _spawnPointId, Move1 = PokemonInfo.GetPokemonMove1(encounteredPokemon).ToString(), Move2 = PokemonInfo.GetPokemonMove2(encounteredPokemon).ToString(), Expiration = unixTimeStamp }; session.EventDispatcher.Send(newdata); } DateTime expiredDate = new DateTime(1970, 1, 1, 0, 0, 0).AddMilliseconds(Convert.ToDouble(unixTimeStamp)); var encounterEV = new EncounteredEvent() { Latitude = latitude, Longitude = longitude, PokemonId = encounteredPokemon.PokemonId, IV = pokemonIv, Level = (int)lv, Expires = expiredDate.ToUniversalTime(), ExpireTimestamp = unixTimeStamp, SpawnPointId = _spawnPointId, EncounterId = _encounterId.ToString(), Move1 = PokemonInfo.GetPokemonMove1(encounteredPokemon).ToString(), Move2 = PokemonInfo.GetPokemonMove2(encounteredPokemon).ToString(), }; //add catch to avoid snipe duplicate string uniqueCacheKey = CatchPokemonTask.GetUsernameGeoLocationCacheKey(session.Settings.Username, encounterEV.PokemonId, encounterEV.Latitude, encounterEV.Longitude); session.Cache.Add(uniqueCacheKey, encounterEV, DateTime.Now.AddMinutes(30)); session.EventDispatcher.Send(encounterEV); if (IsNotMetWithCatchCriteria(session, encounteredPokemon, pokemonIv, lv, pokemonCp)) { session.EventDispatcher.Send(new NoticeEvent { Message = session.Translation.GetTranslation(TranslationString.PokemonSkipped, encounteredPokemon.PokemonId) }); session.Cache.Add(CatchPokemonTask.GetEncounterCacheKey(_encounterId), encounteredPokemon, expiredDate); Logger.Write( $"Filter catch not met. {encounteredPokemon.PokemonId.ToString()} IV {pokemonIv} lv {lv} {pokemonCp} move1 {PokemonInfo.GetPokemonMove1(encounteredPokemon)} move 2 {PokemonInfo.GetPokemonMove2(encounteredPokemon)}"); return(true); } CatchPokemonResponse caughtPokemonResponse = null; var lastThrow = CatchPokemonResponse.Types.CatchStatus.CatchSuccess; // Initializing lastThrow var attemptCounter = 1; // Main CatchPokemon-loop do { if (session.LogicSettings.UseHumanlikeDelays) { await DelayingUtils.DelayAsync(session.LogicSettings.BeforeCatchDelay, 0, session.CancellationTokenSource.Token).ConfigureAwait(false); } if ((session.LogicSettings.MaxPokeballsPerPokemon > 0 && attemptCounter > session.LogicSettings.MaxPokeballsPerPokemon)) { break; } pokeball = await GetBestBall(session, encounteredPokemon, probability).ConfigureAwait(false); if (pokeball == ItemId.ItemUnknown) { session.EventDispatcher.Send(new NoPokeballEvent { Id = encounter is EncounterResponse ? pokemon.PokemonId : encounter?.PokemonData.PokemonId, Cp = encounteredPokemon.Cp }); return(false); } // Determine whether to use berries or not if (lastThrow != CatchPokemonResponse.Types.CatchStatus.CatchMissed) { //AmountOfBerries++; //if (AmountOfBerries <= session.LogicSettings.MaxBerriesToUsePerPokemon) await UseBerry(session, encounterEV.PokemonId, _encounterId, _spawnPointId, pokemonIv, pokemonCp ?? 10000, //unknown CP pokemon, want to use berry encounterEV.Level, probability, cancellationToken).ConfigureAwait(false); } bool hitPokemon = true; //default to excellent throw var normalizedRecticleSize = 1.95; //default spin var spinModifier = 1.0; //Humanized throws if (session.LogicSettings.EnableHumanizedThrows) { //thresholds: https://gist.github.com/anonymous/077d6dea82d58b8febde54ae9729b1bf var spinTxt = "Curve"; var hitTxt = "Excellent"; if (pokemonCp > session.LogicSettings.ForceExcellentThrowOverCp || pokemonIv > session.LogicSettings.ForceExcellentThrowOverIv) { normalizedRecticleSize = Random.NextDouble() * (1.95 - 1.7) + 1.7; } else if (pokemonCp >= session.LogicSettings.ForceGreatThrowOverCp || pokemonIv >= session.LogicSettings.ForceGreatThrowOverIv) { normalizedRecticleSize = Random.NextDouble() * (1.95 - 1.3) + 1.3; hitTxt = "Great"; } else { var regularThrow = 100 - (session.LogicSettings.ExcellentThrowChance + session.LogicSettings.GreatThrowChance + session.LogicSettings.NiceThrowChance); var rnd = Random.Next(1, 101); if (rnd <= regularThrow) { normalizedRecticleSize = Random.NextDouble() * (1 - 0.1) + 0.1; hitTxt = "Ordinary"; } else if (rnd <= regularThrow + session.LogicSettings.NiceThrowChance) { normalizedRecticleSize = Random.NextDouble() * (1.3 - 1) + 1; hitTxt = "Nice"; } else if (rnd <= regularThrow + session.LogicSettings.NiceThrowChance + session.LogicSettings.GreatThrowChance) { normalizedRecticleSize = Random.NextDouble() * (1.7 - 1.3) + 1.3; hitTxt = "Great"; } if (Random.NextDouble() * 100 > session.LogicSettings.CurveThrowChance) { spinModifier = 0.0; spinTxt = "Straight"; } } // Round to 2 decimals normalizedRecticleSize = Math.Round(normalizedRecticleSize, 2); // Missed throw check int missChance = Random.Next(1, 101); if (missChance <= session.LogicSettings.ThrowMissPercentage && session.LogicSettings.EnableMissedThrows) { hitPokemon = false; } Logger.Write($"(Threw ball) {hitTxt} throw, {spinTxt}-ball, HitPokemon = {hitPokemon}...", LogLevel.Debug); } if (CatchFleeContinuouslyCount >= 3 && session.LogicSettings.ByPassCatchFlee) { MSniperServiceTask.BlockSnipe(); if (totalBalls <= BALL_REQUIRED_TO_BYPASS_CATCHFLEE) { Logger.Write("You don't have enough balls to bypass catchflee"); return(false); } List <ItemId> ballToByPass = new List <ItemId>(); var numPokeBalls = await session.Inventory.GetItemAmountByType(ItemId.ItemPokeBall).ConfigureAwait(false); for (int i = 0; i < numPokeBalls - 1; i++) { ballToByPass.Add(ItemId.ItemPokeBall); } var numGreatBalls = await session.Inventory.GetItemAmountByType(ItemId.ItemGreatBall).ConfigureAwait(false); for (int i = 0; i < numGreatBalls - 1; i++) { ballToByPass.Add(ItemId.ItemGreatBall); } var numUltraBalls = await session.Inventory.GetItemAmountByType(ItemId.ItemUltraBall).ConfigureAwait(false); for (int i = 0; i < numUltraBalls - 1; i++) { ballToByPass.Add(ItemId.ItemUltraBall); } bool catchMissed = true; Random r = new Random(); for (int i = 0; i < ballToByPass.Count - 1; i++) { if (i > 130 && r.Next(0, 100) <= 30) { catchMissed = false; } else { catchMissed = true; } caughtPokemonResponse = await session.Client.Encounter.CatchPokemon( encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.EncounterId : _encounterId, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.SpawnPointId : currentFortData.Id, ballToByPass[i], 1.0, 1.0, !catchMissed).ConfigureAwait(false); await session.Inventory.UpdateInventoryItem(ballToByPass[i]).ConfigureAwait(false); await Task.Delay(100).ConfigureAwait(false); Logger.Write($"CatchFlee By pass : {ballToByPass[i].ToString()} , Attempt {i}, result {caughtPokemonResponse.Status}"); if (caughtPokemonResponse.Status != CatchPokemonResponse.Types.CatchStatus.CatchMissed) { session.SaveBallForByPassCatchFlee = false; CatchFleeContinuouslyCount = 0; break; } } } else { caughtPokemonResponse = await session.Client.Encounter.CatchPokemon( encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.EncounterId : _encounterId, encounter is EncounterResponse || encounter is IncenseEncounterResponse ?pokemon.SpawnPointId : currentFortData.Id, pokeball, normalizedRecticleSize, spinModifier, hitPokemon).ConfigureAwait(false); await session.Inventory.UpdateInventoryItem(pokeball).ConfigureAwait(false); } var evt = new PokemonCaptureEvent() { Status = caughtPokemonResponse.Status, CaptureReason = caughtPokemonResponse.CaptureReason, Latitude = latitude, Longitude = longitude }; lastThrow = caughtPokemonResponse.Status; // sets lastThrow status if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess) { evt.Shiny = (await session.Inventory.GetPokemons().ConfigureAwait(false)).First(x => x.Id == caughtPokemonResponse.CapturedPokemonId).PokemonDisplay.Shiny ? "Yes" : "No"; evt.Form = (await session.Inventory.GetPokemons().ConfigureAwait(false)).First(x => x.Id == caughtPokemonResponse.CapturedPokemonId).PokemonDisplay.Form.ToString().Replace("Unown", "").Replace("Unset", "Normal"); evt.Costume = (await session.Inventory.GetPokemons().ConfigureAwait(false)).First(x => x.Id == caughtPokemonResponse.CapturedPokemonId).PokemonDisplay.Costume.ToString().Replace("Unset", "Regular"); evt.Gender = (await session.Inventory.GetPokemons().ConfigureAwait(false)).First(x => x.Id == caughtPokemonResponse.CapturedPokemonId).PokemonDisplay.Gender.ToString(); var totalExp = 0; var stardust = caughtPokemonResponse.CaptureAward.Stardust.Sum(); var totalStarDust = session.Inventory.UpdateStarDust(stardust); var CaptuerXP = caughtPokemonResponse.CaptureAward.Xp.Sum(); if (encounteredPokemon != null) { encounteredPokemon.Id = caughtPokemonResponse.CapturedPokemonId; } foreach (var xp in caughtPokemonResponse.CaptureAward.Xp) { totalExp += xp; } //This accounts for XP for CatchFlee if (totalExp < 1) { totalExp = 25; } evt.Exp = totalExp; evt.Stardust = stardust; evt.UniqueId = caughtPokemonResponse.CapturedPokemonId; evt.Candy = await session.Inventory.GetCandyFamily(pokemon.PokemonId).ConfigureAwait(false); evt.totalStarDust = totalStarDust; if (session.LogicSettings.AutoFavoriteShinyOnCatch) { if (evt.Shiny == "Yes") { await FavoritePokemonTask.Execute(session, encounteredPokemon.Id, true); Logger.Write($"You've caught a Shiny Pokemon ({encounteredPokemon.Nickname}) and it has been Favorited."); } } } if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess || caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchFlee) { // Also count catch flee against the catch limit if (session.LogicSettings.UseCatchLimit) { session.Stats.AddPokemonTimestamp(DateTime.Now.Ticks); session.EventDispatcher.Send(new CatchLimitUpdate(session.Stats.GetNumPokemonsInLast24Hours(), session.LogicSettings.CatchPokemonLimit)); } } evt.CatchType = encounter is EncounterResponse ? session.Translation.GetTranslation(TranslationString.CatchTypeNormal) : encounter is DiskEncounterResponse ? session.Translation.GetTranslation(TranslationString.CatchTypeLure) : session.Translation.GetTranslation(TranslationString.CatchTypeIncense); evt.CatchTypeText = encounter is EncounterResponse ? "normal" : encounter is DiskEncounterResponse ? "lure" : "incense"; evt.Id = encounter is EncounterResponse ? pokemon.PokemonId : encounter?.PokemonData.PokemonId; evt.EncounterId = _encounterId; evt.Move1 = PokemonInfo.GetPokemonMove1(encounteredPokemon); evt.Move2 = PokemonInfo.GetPokemonMove2(encounteredPokemon); evt.Expires = pokemon?.ExpirationTimestampMs ?? 0; evt.SpawnPointId = _spawnPointId; evt.Level = PokemonInfo.GetLevel(encounteredPokemon); evt.Cp = encounteredPokemon.Cp; evt.MaxCp = PokemonInfo.CalculateMaxCp(encounteredPokemon.PokemonId); evt.Perfection = Math.Round(PokemonInfo.CalculatePokemonPerfection(encounteredPokemon)); evt.Probability = Math.Round(probability * 100, 2); evt.Distance = distance; evt.Pokeball = pokeball; evt.Attempt = attemptCounter; //await session.Inventory.RefreshCachedInventory().ConfigureAwait(false); evt.BallAmount = await session.Inventory.GetItemAmountByType(pokeball).ConfigureAwait(false); evt.Rarity = PokemonGradeHelper.GetPokemonGrade(evt.Id).ToString(); session.EventDispatcher.Send(evt); attemptCounter++; // If Humanlike delays are used if (session.LogicSettings.UseHumanlikeDelays) { switch (caughtPokemonResponse.Status) { case CatchPokemonResponse.Types.CatchStatus.CatchError: await DelayingUtils.DelayAsync(session.LogicSettings.CatchErrorDelay, 0, session.CancellationTokenSource.Token).ConfigureAwait(false); break; case CatchPokemonResponse.Types.CatchStatus.CatchSuccess: await DelayingUtils.DelayAsync(session.LogicSettings.CatchSuccessDelay, 0, session.CancellationTokenSource.Token).ConfigureAwait(false); break; case CatchPokemonResponse.Types.CatchStatus.CatchEscape: await DelayingUtils.DelayAsync(session.LogicSettings.CatchEscapeDelay, 0, session.CancellationTokenSource.Token).ConfigureAwait(false); break; case CatchPokemonResponse.Types.CatchStatus.CatchFlee: await DelayingUtils.DelayAsync(session.LogicSettings.CatchFleeDelay, 0, session.CancellationTokenSource.Token).ConfigureAwait(false); break; case CatchPokemonResponse.Types.CatchStatus.CatchMissed: await DelayingUtils.DelayAsync(session.LogicSettings.CatchMissedDelay, 0, session.CancellationTokenSource.Token).ConfigureAwait(false); break; default: break; } } else { await DelayingUtils.DelayAsync(session.LogicSettings.DelayBetweenPlayerActions, 0, session.CancellationTokenSource.Token).ConfigureAwait(false); } } while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed || caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape); if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchFlee) { CatchFleeContinuouslyCount++; if (CatchFleeContinuouslyCount >= 3 && session.LogicSettings.ByPassCatchFlee) { session.SaveBallForByPassCatchFlee = true; Logger.Write("Seem that bot has been catch flee softban, Bot will start save 100 balls to by pass it."); } if (manager.AllowMultipleBot() && !session.LogicSettings.ByPassCatchFlee) { if (CatchFleeContinuouslyCount > session.LogicSettings.MultipleBotConfig.CatchFleeCount && TinyIoCContainer.Current.Resolve <MultiAccountManager>().AllowSwitch()) { CatchFleeContinuouslyCount = 0; session.SaveBallForByPassCatchFlee = false; throw new ActiveSwitchByRuleException() { MatchedRule = SwitchRules.CatchFlee, ReachedValue = session.LogicSettings.MultipleBotConfig.CatchFleeCount }; } } } else { //reset if not catch flee. if (caughtPokemonResponse.Status != CatchPokemonResponse.Types.CatchStatus.CatchMissed) { CatchFleeContinuouslyCount = 0; MSniperServiceTask.UnblockSnipe(); } } session.Actions.RemoveAll(x => x == BotActions.Catch); if (MultipleBotConfig.IsMultiBotActive(session.LogicSettings, manager)) { ExecuteSwitcher(session, encounterEV); } if (session.LogicSettings.TransferDuplicatePokemonOnCapture && session.LogicSettings.TransferDuplicatePokemon && sessionAllowTransfer && caughtPokemonResponse != null && caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess) { if (session.LogicSettings.UseNearActionRandom) { await HumanRandomActionTask.TransferRandom(session, cancellationToken).ConfigureAwait(false); } else { await TransferDuplicatePokemonTask.Execute(session, cancellationToken).ConfigureAwait(false); } } } return(true); }