Пример #1
0
        private static SniperInfo Map(PokemonCaptureEvent pokemonCaptureEvent)
        {
            var sniperInfo = new SniperInfo();

            sniperInfo.ChannelInfo = new ChannelInfo()
            {
                server = Constants.Bot
            };
            sniperInfo.IV         = pokemonCaptureEvent.Perfection;
            sniperInfo.Id         = pokemonCaptureEvent.Id;
            sniperInfo.Latitude   = Math.Round(pokemonCaptureEvent.Latitude, 7);
            sniperInfo.Longitude  = Math.Round(pokemonCaptureEvent.Longitude, 7);
            sniperInfo.Verified   = true;
            sniperInfo.VerifiedOn = DateTime.Now;
            if (pokemonCaptureEvent is NewPokemonCaptureEvent)
            {
                var newPokemonCaptureEvent = (NewPokemonCaptureEvent)pokemonCaptureEvent;
                sniperInfo.ExpirationTimestamp = FromUnixTime(newPokemonCaptureEvent.Expires);
                sniperInfo.SpawnPointId        = newPokemonCaptureEvent.SpawnPointId;
                sniperInfo.Move1       = newPokemonCaptureEvent.Move1;
                sniperInfo.Move2       = newPokemonCaptureEvent.Move2;
                sniperInfo.EncounterId = newPokemonCaptureEvent.EncounterId;
                if (newPokemonCaptureEvent.CatchTypeText != "normal")
                {
                    Log.Trace("Skipping pokemon because it was not a wild pokemon");
                }
            }
            return(sniperInfo);
        }
 public void HandleEvent(PokemonCaptureEvent evt, ISession session)
 {
     if (evt.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
     {
         _stats.TotalExperience += evt.Exp;
         _stats.TotalPokemons++;
         _stats.TotalStardust = evt.Stardust;
         _stats.Dirty(session.Inventory);
     }
 }
Пример #3
0
 public void HandleEvent(PokemonCaptureEvent evt, ISession session)
 {
     if (evt.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
     {
         session.Stats.TotalExperience += evt.Exp;
         session.Stats.TotalPokemons++;
         session.Stats.TotalStardust = evt.Stardust;
         session.Stats.RefreshStatAndCheckLevelup(session);
         session.Stats.RefreshPokeDex(session);
     }
     session.Stats.PokeBalls++;
 }
Пример #4
0
 public CatchPokemonViewModel(PokemonCaptureEvent ev)
 {
     this.UUID        = ev.EncounterId.ToString();
     this.PokemonName = ev.Id.ToString();
     this.IV          = ev.Perfection;
     this.CP          = ev.Cp;
     this.Probability = ev.Probability;
     this.EncounterId = ev.EncounterId;
     this.CatchType   = ev.CatchType;
     this.Move1       = ev.Move1.ToString();
     this.Move2       = ev.Move2.ToString();
     this.CatchStatus = ev.Status.ToString();
     this.PokeBalls   = ev.Pokeball == POGOProtos.Inventory.Item.ItemId.ItemPokeBall? 1: 0;
     this.UltraBalls  = ev.Pokeball == POGOProtos.Inventory.Item.ItemId.ItemUltraBall ? 1 : 0;
     this.GreateBalls = ev.Pokeball == POGOProtos.Inventory.Item.ItemId.ItemGreatBall ? 1 : 0;
 }
Пример #5
0
 public CatchPokemonViewModel(PokemonCaptureEvent ev)
 {
     UUID        = ev.EncounterId.ToString();
     PokemonId   = ev.Id;
     PokemonName = ev.Id.ToString();
     IV          = ev.Perfection;
     CP          = ev.Cp;
     Candy       = ev.Candy;
     Probability = ev.Probability;
     EncounterId = ev.EncounterId;
     CatchType   = ev.CatchType;
     Move1       = ev.Move1.ToString();
     Move2       = ev.Move2.ToString();
     CatchStatus = ev.Status.ToString();
     PokeBalls   = ev.Pokeball == POGOProtos.Inventory.Item.ItemId.ItemPokeBall? 1: 0;
     UltraBalls  = ev.Pokeball == POGOProtos.Inventory.Item.ItemId.ItemUltraBall ? 1 : 0;
     GreatBalls  = ev.Pokeball == POGOProtos.Inventory.Item.ItemId.ItemGreatBall ? 1 : 0;
     Exp         = ev.Exp;
 }
Пример #6
0
        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);
        }
Пример #7
0
 public void OnBotEvent(PokemonCaptureEvent capture)
 {
     this.datacontext.Sidebar.AddOrUpdate(new CatchPokemonViewModel(capture));
 }
Пример #8
0
        private static void HandleEvent(PokemonCaptureEvent pokemonCaptureEvent, ISession session)
        {
            Func <ItemId, string> returnRealBallName = a =>
            {
                // ReSharper disable once SwitchStatementMissingSomeCases
                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));
                }
            };

            var catchType = pokemonCaptureEvent.CatchType;

            string strStatus;

            switch (pokemonCaptureEvent.Status)
            {
            case CatchPokemonResponse.Types.CatchStatus.CatchError:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusError);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchEscape:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusEscape);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchFlee:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusFlee);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchMissed:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusMissed);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchSuccess:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusSuccess);
                break;

            default:
                strStatus = pokemonCaptureEvent.Status.ToString();
                break;
            }

            var catchStatus = pokemonCaptureEvent.Attempt > 1
                ? session.Translation.GetTranslation(TranslationString.CatchStatusAttempt, strStatus,
                                                     pokemonCaptureEvent.Attempt)
                : session.Translation.GetTranslation(TranslationString.CatchStatus, strStatus);

            var familyCandies = pokemonCaptureEvent.Candy?.Candy_ > 0
                ? session.Translation.GetTranslation(TranslationString.Candies, pokemonCaptureEvent.Candy.Candy_)
                : "";

            string message;

            if (pokemonCaptureEvent.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
            {
                if (session.LogicSettings.NotificationConfig.EnablePushBulletNotification == true && pokemonCaptureEvent.Shiny == "Yes")
                {
                    PushNotificationClient.SendNotification(session, $"Shiny Pokemon Captured", $"{session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id)}\nLvl:{pokemonCaptureEvent.Level}\n" +
                                                            $"CP:  {pokemonCaptureEvent.Cp}/{pokemonCaptureEvent.MaxCp}\n" +
                                                            $"IV:  {pokemonCaptureEvent.Perfection.ToString("0.00")}\n" +
                                                            $"Lat: {pokemonCaptureEvent.Latitude.ToString("0.000000")}\n" +
                                                            $"Lon: {pokemonCaptureEvent.Longitude.ToString("0.000000")}", true).ConfigureAwait(false);
                }

                if (session.LogicSettings.NotificationConfig.EnablePushBulletNotification == true && pokemonCaptureEvent.Perfection >= session.LogicSettings.FavoriteMinIvPercentage)
                {
                    PushNotificationClient.SendNotification(session, $"High IV Pokemon Captured", $"{session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id)}({pokemonCaptureEvent.Perfection.ToString("0.00")}% IV)\n" +
                                                            $"Lvl: {pokemonCaptureEvent.Level}\n" +
                                                            $"CP:  {pokemonCaptureEvent.Cp}/{pokemonCaptureEvent.MaxCp}\n" +
                                                            $"Lat: {pokemonCaptureEvent.Latitude.ToString("0.000000")}\n" +
                                                            $"Lon: {pokemonCaptureEvent.Longitude.ToString("0.000000")}", true).ConfigureAwait(false);
                }

                message = session.Translation.GetTranslation(TranslationString.EventPokemonCaptureSuccess, catchStatus,
                                                             catchType,
                                                             session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id).PadRight(12, ' '),
                                                             pokemonCaptureEvent.Level.ToString("0.0").PadLeft(4, ' '),
                                                             pokemonCaptureEvent.Cp.ToString("0").PadLeft(4, ' '),
                                                             pokemonCaptureEvent.MaxCp.ToString("0").PadLeft(4, ' '),
                                                             pokemonCaptureEvent.Perfection.ToString("0.00").PadLeft(6, ' '),
                                                             pokemonCaptureEvent.Probability.ToString("0.00").PadLeft(6, ' '),
                                                             pokemonCaptureEvent.Distance.ToString("F2"),
                                                             returnRealBallName(pokemonCaptureEvent.Pokeball).PadRight(10, ' '),
                                                             pokemonCaptureEvent.BallAmount.ToString("0").PadLeft(3, ' '),
                                                             pokemonCaptureEvent.Exp.ToString("0").PadLeft(4, ' '),
                                                             pokemonCaptureEvent.Stardust.ToString("0").PadLeft(4, ' '),
                                                             familyCandies,
                                                             pokemonCaptureEvent.Latitude.ToString("0.000000"),
                                                             pokemonCaptureEvent.Longitude.ToString("0.000000"),
                                                             pokemonCaptureEvent.Move1.ToString().PadRight(16, ' '),
                                                             pokemonCaptureEvent.Move2.ToString().PadRight(16, ' '),
                                                             pokemonCaptureEvent.Rarity.ToString().PadRight(10, ' '),
                                                             pokemonCaptureEvent.CaptureReason,
                                                             pokemonCaptureEvent.Shiny.ToString().PadRight(3, ' '),
                                                             pokemonCaptureEvent.Form,
                                                             pokemonCaptureEvent.Costume,
                                                             pokemonCaptureEvent.Gender
                                                             );
                Logger.Write(message, LogLevel.Caught);
            }
            else
            {
                if (pokemonCaptureEvent.Status == CatchPokemonResponse.Types.CatchStatus.CatchFlee)
                {
                    if (session.LogicSettings.NotificationConfig.EnablePushBulletNotification == true && pokemonCaptureEvent.Shiny == "Yes")
                    {
                        PushNotificationClient.SendNotification(session, $"Shiny Pokemon Ran Away", $"{session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id)}\n" +
                                                                $"Lvl: {pokemonCaptureEvent.Level}\n" +
                                                                $"CP:  {pokemonCaptureEvent.Cp}/{pokemonCaptureEvent.MaxCp}\n" +
                                                                $"IV:  {pokemonCaptureEvent.Perfection.ToString("0.00")}\n" +
                                                                $"Lat: {pokemonCaptureEvent.Latitude.ToString("0.000000")}\n" +
                                                                $"Lon: {pokemonCaptureEvent.Longitude.ToString("0.000000")}", true).ConfigureAwait(false);
                    }

                    if (session.LogicSettings.NotificationConfig.EnablePushBulletNotification == true && pokemonCaptureEvent.Perfection >= session.LogicSettings.FavoriteMinIvPercentage)
                    {
                        PushNotificationClient.SendNotification(session, $"High IV Pokemon Ran Away", $"{session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id)}({pokemonCaptureEvent.Perfection.ToString("0.00")}% IV)\n" +
                                                                $"Lvl: {pokemonCaptureEvent.Level}\n" +
                                                                $"CP:  {pokemonCaptureEvent.Cp}/{pokemonCaptureEvent.MaxCp}\n" +
                                                                $"Lat: {pokemonCaptureEvent.Latitude.ToString("0.000000")}\n" +
                                                                $"Lon: {pokemonCaptureEvent.Longitude.ToString("0.000000")}", true).ConfigureAwait(false);
                    }
                }
                message = session.Translation.GetTranslation(TranslationString.EventPokemonCaptureFailed, catchStatus,
                                                             catchType,
                                                             session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id).PadRight(12, ' '),
                                                             pokemonCaptureEvent.Level.ToString("0.0").PadLeft(4, ' '),
                                                             pokemonCaptureEvent.Cp.ToString("0").PadLeft(4, ' '),
                                                             pokemonCaptureEvent.MaxCp.ToString("0").PadLeft(4, ' '),
                                                             pokemonCaptureEvent.Perfection.ToString("0.00").PadLeft(6, ' '),
                                                             pokemonCaptureEvent.Probability.ToString("0.00").PadLeft(6, ' '),
                                                             pokemonCaptureEvent.Distance.ToString("F2"),
                                                             returnRealBallName(pokemonCaptureEvent.Pokeball).PadRight(10, ' '),
                                                             pokemonCaptureEvent.BallAmount.ToString("0").PadLeft(3, ' '),
                                                             pokemonCaptureEvent.Exp.ToString("0").PadLeft(4, ' '),
                                                             pokemonCaptureEvent.Latitude.ToString("0.000000"),
                                                             pokemonCaptureEvent.Longitude.ToString("0.000000"),
                                                             pokemonCaptureEvent.Move1.ToString().PadRight(15, ' '),
                                                             pokemonCaptureEvent.Move2.ToString().PadRight(15, ' '),
                                                             pokemonCaptureEvent.Rarity.ToString().PadRight(10, ' ')
                                                             );
                Logger.Write(message, LogLevel.Flee);
            }
        }
Пример #9
0
        /// <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.AllowMultipleBot &&
                    session.LogicSettings.MultipleBotConfig.SwitchOnCatchLimit)
                {
                    throw new ActiveSwitchByRuleException()
                          {
                              MatchedRule  = SwitchRules.CatchLimitReached,
                              ReachedValue = session.LogicSettings.CatchPokemonLimit
                          };
                }

                return(false);
            }
            using (var block = new BlockableScope(session, 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))) &&
                        // if last throw is a miss, no double berry
                        lastThrow != CatchPokemonResponse.Types.CatchStatus.CatchMissed)
                    {
                        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;
                        var totalStartDust = caughtPokemonResponse.CaptureAward.Stardust.Sum();
                        if (encounteredPokemon != null)
                        {
                            encounteredPokemon.Id = caughtPokemonResponse.CapturedPokemonId;
                            await session.Inventory.AddPokemonToCache(encounteredPokemon);
                        }
                        foreach (var xp in caughtPokemonResponse.CaptureAward.Xp)
                        {
                            totalExp += xp;
                        }
                        var stardust = session.Inventory.UpdateStartDust(totalStartDust);

                        evt.Exp      = totalExp;
                        evt.Stardust = stardust;
                        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;
                        MSniperServiceTask.UnblockSnipe();
                    }
                }

                session.Actions.RemoveAll(x => x == 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);
        }
Пример #10
0
 private static void HandleEvent(PokemonCaptureEvent pokemonCaptureEvent, ISession session)
 {
     //remove pokemon from list
     HumanWalkSnipeTask.UpdateCatchPokemon(pokemonCaptureEvent.Latitude,
                                           pokemonCaptureEvent.Longitude, pokemonCaptureEvent.Id);
 }
Пример #11
0
        public void Start(int port)
        {
            while (true)
            {
                var supportsDiscover = false;
                var running          = true;

                using (var client = new WebSocket($"wss://localhost:{port}", "basic", WebSocketVersion.Rfc6455))
                {
                    System.Net.ServicePointManager.ServerCertificateValidationCallback =
                        (sender, certificate, chain, errors) => true;

                    client.AllowUnstrustedCertificate = false;
                    client.Opened += (s, e) =>
                    {
                        Log.Debug($"Connected to bot on {port}");
                    };

                    client.Closed += (s, e) =>
                    {
                        Log.Debug($"Disconnect from bot on {port}");
                        running = false;
                    };
                    client.MessageReceived += (s, e) =>
                    {
                        try
                        {
                            if (e.Message.Contains("PokemonCaptureEvent") && !supportsDiscover)
                            {
                                PokemonCaptureEvent pokemonCaptureEvent = null;
                                try
                                {
                                    pokemonCaptureEvent =
                                        JsonConvert.DeserializeObject <NewPokemonCaptureEvent>(e.Message,
                                                                                               new JsonSerializerSettingsCultureInvariant());
                                }
                                catch (Exception exception)
                                {
                                    pokemonCaptureEvent = JsonConvert.DeserializeObject <PokemonCaptureEvent>(e.Message,
                                                                                                              new JsonSerializerSettingsCultureInvariant());
                                }
                                if (pokemonCaptureEvent != null && pokemonCaptureEvent.Attempt == 1)
                                {
                                    InputService.Instance.BotCapture(Map(pokemonCaptureEvent));
                                }
                            }
                            else if (e.Message.Contains("PokemonDiscoverEvent"))
                            {
                                supportsDiscover = true;
                                var pokemonDiscoveredEvent =
                                    JsonConvert.DeserializeObject <PokemonDiscoverEvent>(e.Message,
                                                                                         new JsonSerializerSettingsCultureInvariant());
                                if (pokemonDiscoveredEvent != null && pokemonDiscoveredEvent.CatchTypeText == "normal")
                                {
                                    InputService.Instance.BotCapture(Map(pokemonDiscoveredEvent));
                                }
                            }
                        }
                        catch (Exception messageException)
                        {
                            Log.Warn($"Error during receiving message from the bot on {port}", messageException);
                        }
                    };
                    client.Error += (s, e) =>
                    {
                    };
                    client.Open();
                    while (running)
                    {
                        Thread.Sleep(10000);
                    }
                    Log.Debug("Waiting 30 seconds to try to reconnect to the bot");
                    Thread.Sleep(30 * 1000);
                }
            }
        }
Пример #12
0
        public void HandleEvent(PokemonCaptureEvent evt, ISession session)
        {
            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));
                }
            };

            var      catchType = evt.CatchType;
            LogLevel caughtEscapeFlee;

            string strStatus;

            switch (evt.Status)
            {
            case CatchPokemonResponse.Types.CatchStatus.CatchError:
                strStatus        = session.Translation.GetTranslation(TranslationString.CatchStatusError);
                caughtEscapeFlee = LogLevel.Error;
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchEscape:
                strStatus        = session.Translation.GetTranslation(TranslationString.CatchStatusEscape);
                caughtEscapeFlee = LogLevel.Escape;
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchFlee:
                strStatus        = session.Translation.GetTranslation(TranslationString.CatchStatusFlee);
                caughtEscapeFlee = LogLevel.Flee;
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchMissed:
                strStatus        = session.Translation.GetTranslation(TranslationString.CatchStatusMissed);
                caughtEscapeFlee = LogLevel.Escape;
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchSuccess:
                strStatus        = session.Translation.GetTranslation(TranslationString.CatchStatusSuccess);
                caughtEscapeFlee = LogLevel.Caught;
                Logger.PushToUi("pm_new", session, evt.Uid, evt.Id, evt.Cp, evt.Perfection, evt.Family, evt.FamilyCandies, evt.Level, evt.Move1, evt.Move2, evt.Type1, evt.Type2, evt.MaxCp, evt.Stamina, evt.MaxStamina, evt.PossibleCp, evt.CandyToEvolve);
                break;

            default:
                strStatus        = evt.Status.ToString();
                caughtEscapeFlee = LogLevel.Error;
                break;
            }

            var catchStatus = evt.Attempt > 1
                ? session.Translation.GetTranslation(TranslationString.CatchStatusAttempt, strStatus, evt.Attempt)
                : session.Translation.GetTranslation(TranslationString.CatchStatus, strStatus);

            var familyCandies = evt.FamilyCandies > 0
                ? session.Translation.GetTranslation(TranslationString.Candies, evt.FamilyCandies)
                : "";

            Logger.Write(
                session.Translation.GetTranslation(TranslationString.EventPokemonCapture, catchStatus, catchType,
                                                   session.Translation.GetPokemonName(evt.Id),
                                                   evt.Level, evt.Cp, evt.MaxCp, evt.Perfection.ToString("0.00"), evt.Probability,
                                                   evt.Distance.ToString("F2"),
                                                   returnRealBallName(evt.Pokeball), evt.BallAmount, evt.Exp, familyCandies), caughtEscapeFlee, session: session);
        }
Пример #13
0
        public static async Task Execute(ISession session, CancellationToken cancellationToken, dynamic encounter, MapPokemon pokemon,
                                         FortData currentFortData = null, ulong encounterId = 0, bool sessionAllowTransfer = true)
        {
            AmountOfBerries = 0;

            cancellationToken.ThrowIfCancellationRequested();

            // If the encounter is null nothing will work below, so exit now
            if (encounter == null)
            {
                return;
            }

            if (CatchThresholdExceeds(session))
            {
                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 lastThrow      = CatchPokemonResponse.Types.CatchStatus.CatchSuccess; // Initializing lastThrow
            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))) &&
                    lastThrow != CatchPokemonResponse.Types.CatchStatus.CatchMissed) // if last throw is a miss, no double berry
                {
                    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);
                    }
                }

                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);

                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
                };

                lastThrow = caughtPokemonResponse.Status; // sets lastThrow 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;
                    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)
                    {
                        family.Candy_    += caughtPokemonResponse.CaptureAward.Candy.Sum();
                        evt.FamilyCandies = family.Candy_;
                    }
                    else
                    {
                        evt.FamilyCandies = caughtPokemonResponse.CaptureAward.Candy.Sum();
                    }

                    if (session.LogicSettings.UseCatchLimit)
                    {
                        session.Stats.PokemonTimestamps.Add(DateTime.Now.Ticks);
                        UpdateTimeStampsPokemon?.Invoke();
                        Logger.Write($"(CATCH LIMIT) {session.Stats.PokemonTimestamps.Count}/{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 = encounter is EncounterResponse || encounter is IncenseEncounterResponse
                    ? pokemon.EncounterId
                    : encounterId;
                evt.Move1 = PokemonInfo.GetPokemonMove1(encounter is EncounterResponse
                    ? encounter.WildPokemon?.PokemonData
                    : encounter?.PokemonData);
                evt.Move2 = PokemonInfo.GetPokemonMove2(encounter is EncounterResponse
                    ? encounter.WildPokemon?.PokemonData
                    : encounter?.PokemonData);
                evt.Expires      = pokemon?.ExpirationTimestampMs ?? 0;
                evt.SpawnPointId = encounter is EncounterResponse || encounter is IncenseEncounterResponse
                    ? pokemon.SpawnPointId
                    : currentFortData?.Id;
                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);

                evt.Rarity = PokemonGradeHelper.GetPokemonGrade(evt.Id).ToString();
                session.EventDispatcher.Send(evt);

                attemptCounter++;

                DelayingUtils.Delay(session.LogicSettings.DelayBetweenPlayerActions, 0);

                if (session.LogicSettings.TransferDuplicatePokemonOnCapture && session.LogicSettings.TransferDuplicatePokemon &&
                    sessionAllowTransfer && caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
                {
                    if (session.LogicSettings.UseNearActionRandom)
                    {
                        await HumanRandomActionTask.TransferRandom(session, cancellationToken);
                    }
                    else
                    {
                        await TransferDuplicatePokemonTask.Execute(session, cancellationToken);
                    }
                }
            } while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed ||
                     caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape);
        }
Пример #14
0
        public void HandleEvent(PokemonCaptureEvent pokemonCaptureEvent, ISession session)
        {
            Func <ItemId, string> returnRealBallName = a =>
            {
                // ReSharper disable once SwitchStatementMissingSomeCases
                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));
                }
            };

            PokemonID = pokemonNameToId[pokemonCaptureEvent.Id.ToString()];

            var catchType = pokemonCaptureEvent.CatchType;

            string strStatus;

            switch (pokemonCaptureEvent.Status)
            {
            case CatchPokemonResponse.Types.CatchStatus.CatchError:
                strStatus     = session.Translation.GetTranslation(TranslationString.CatchStatusError);
                PokemonID     = pokemonNameToId[pokemonCaptureEvent.Id.ToString()];
                PokemonName   = session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id);
                liveHappening = "fight";
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchEscape:
                liveHappening = "fight";
                PokemonID     = pokemonNameToId[pokemonCaptureEvent.Id.ToString()];
                PokemonName   = session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id);
                strStatus     = session.Translation.GetTranslation(TranslationString.CatchStatusEscape);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchFlee:
                liveHappening = "fight";
                PokemonID     = pokemonNameToId[pokemonCaptureEvent.Id.ToString()];
                PokemonName   = session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id);
                strStatus     = session.Translation.GetTranslation(TranslationString.CatchStatusFlee);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchMissed:
                PokemonID     = pokemonNameToId[pokemonCaptureEvent.Id.ToString()];
                PokemonName   = session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id);
                strStatus     = session.Translation.GetTranslation(TranslationString.CatchStatusMissed);
                liveHappening = "fight";
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchSuccess:
                liveHappening = "caught";
                strStatus     = session.Translation.GetTranslation(TranslationString.CatchStatusSuccess);
                break;

            default:
                strStatus = pokemonCaptureEvent.Status.ToString();
                break;
            }

            var catchStatus = pokemonCaptureEvent.Attempt > 1
                ? session.Translation.GetTranslation(TranslationString.CatchStatusAttempt, strStatus, pokemonCaptureEvent.Attempt)
                : session.Translation.GetTranslation(TranslationString.CatchStatus, strStatus);

            var familyCandies = pokemonCaptureEvent.FamilyCandies > 0
                ? session.Translation.GetTranslation(TranslationString.Candies, pokemonCaptureEvent.FamilyCandies)
                : "";

            string message;

            if (pokemonCaptureEvent.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
            {
                coords[0]   = pokemonCaptureEvent.Latitude;
                coords[1]   = pokemonCaptureEvent.Longitude;
                PokemonName = session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id);
                Pokemon.setAll(PokemonName, pokemonCaptureEvent.Cp + " / " + pokemonCaptureEvent.MaxCp, pokemonCaptureEvent.Perfection.ToString("0.00") + " % ", pokemonCaptureEvent.FamilyCandies.ToString(), pokemonCaptureEvent.UniqueId, "", "", "");
                message = session.Translation.GetTranslation(TranslationString.EventPokemonCaptureSuccess, catchStatus, catchType, session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id),
                                                             pokemonCaptureEvent.Level, pokemonCaptureEvent.Cp, pokemonCaptureEvent.MaxCp, pokemonCaptureEvent.Perfection.ToString("0.00"), pokemonCaptureEvent.Probability,
                                                             pokemonCaptureEvent.Distance.ToString("F2"),
                                                             returnRealBallName(pokemonCaptureEvent.Pokeball), pokemonCaptureEvent.BallAmount,
                                                             pokemonCaptureEvent.Exp, familyCandies, pokemonCaptureEvent.Latitude.ToString("0.000000"), pokemonCaptureEvent.Longitude.ToString("0.000000"));
                Write(message, LogLevel.Caught);
            }
            else
            {
                message = session.Translation.GetTranslation(TranslationString.EventPokemonCaptureFailed, catchStatus, catchType, session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id),
                                                             pokemonCaptureEvent.Level, pokemonCaptureEvent.Cp, pokemonCaptureEvent.MaxCp, pokemonCaptureEvent.Perfection.ToString("0.00"), pokemonCaptureEvent.Probability,
                                                             pokemonCaptureEvent.Distance.ToString("F2"),
                                                             returnRealBallName(pokemonCaptureEvent.Pokeball), pokemonCaptureEvent.BallAmount,
                                                             pokemonCaptureEvent.Latitude.ToString("0.000000"), pokemonCaptureEvent.Longitude.ToString("0.000000"));
                Write(message, LogLevel.Flee);
            }
        }
Пример #15
0
        public static async Task Execute(ISession session, dynamic encounter, MapPokemon pokemon,
                                         FortData currentFortData = null, ulong encounterId = 0)
        {
            if (encounter is EncounterResponse && pokemon == null)
            {
                throw new ArgumentException("Parameter pokemon must be set, if encounter is of type EncounterResponse", "pokemon");
            }

            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 < session.LogicSettings.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))
                {
                    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);

                double normalizedRecticleSize, spinModifier;
                if (session.LogicSettings.HumanizeThrows)
                {
                    normalizedRecticleSize =
                        Rng.NextInRange(session.LogicSettings.ThrowAccuracyMin, session.LogicSettings.ThrowAccuracyMax) *
                        1.85 + 0.1; // 0.1..1.95
                    spinModifier = Rng.NextDouble() > session.LogicSettings.ThrowSpinFrequency ? 0.0 : 1.0;
                }
                else
                {
                    normalizedRecticleSize = 1.95;
                    spinModifier           = 1.00;
                }
                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();
                    }
                }


                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), 2);
                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++;
                if (session.LogicSettings.Teleport)
                {
                    await Task.Delay(session.LogicSettings.DelayCatchPokemon);
                }
                else
                {
                    await DelayingUtils.Delay(session.LogicSettings.DelayBetweenPokemonCatch, 2000);
                }
            } while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed ||
                     caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape);
        }
Пример #16
0
        public void HandleEvent(PokemonCaptureEvent evt, ISession session)
        {
            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));
                }
            };

            var catchType = evt.CatchType;

            string strStatus;

            switch (evt.Status)
            {
            case CatchPokemonResponse.Types.CatchStatus.CatchError:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusError);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchEscape:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusEscape);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchFlee:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusFlee);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchMissed:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusMissed);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchSuccess:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusSuccess);
                break;

            default:
                strStatus = evt.Status.ToString();
                break;
            }

            var catchStatus = evt.Attempt > 1
                ? session.Translation.GetTranslation(TranslationString.CatchStatusAttempt, strStatus, evt.Attempt)
                : session.Translation.GetTranslation(TranslationString.CatchStatus, strStatus);

            var familyCandies = evt.FamilyCandies > 0
                ? session.Translation.GetTranslation(TranslationString.Candies, evt.FamilyCandies)
                : "";

            if (evt.Id == POGOProtos.Enums.PokemonId.Snorlax ||
                evt.Id == POGOProtos.Enums.PokemonId.Dragonite ||
                evt.Id == POGOProtos.Enums.PokemonId.Venusaur ||
                evt.Id == POGOProtos.Enums.PokemonId.Charizard ||
                evt.Id == POGOProtos.Enums.PokemonId.Blastoise ||
                evt.Id == POGOProtos.Enums.PokemonId.Kangaskhan ||
                evt.Id == POGOProtos.Enums.PokemonId.Farfetchd ||
                evt.Id == POGOProtos.Enums.PokemonId.MrMime ||
                evt.Id == POGOProtos.Enums.PokemonId.Gyarados ||
                evt.Id == POGOProtos.Enums.PokemonId.Lapras ||
                evt.Id == POGOProtos.Enums.PokemonId.Ditto ||
                evt.Id == POGOProtos.Enums.PokemonId.Vaporeon ||
                evt.Id == POGOProtos.Enums.PokemonId.Jolteon ||
                evt.Id == POGOProtos.Enums.PokemonId.Flareon ||
                evt.Id == POGOProtos.Enums.PokemonId.Porygon ||
                evt.Id == POGOProtos.Enums.PokemonId.Articuno ||
                evt.Id == POGOProtos.Enums.PokemonId.Zapdos ||
                evt.Id == POGOProtos.Enums.PokemonId.Moltres ||
                evt.Id == POGOProtos.Enums.PokemonId.Mew ||
                evt.Id == POGOProtos.Enums.PokemonId.Mewtwo)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
            }
            else if (catchType == "Lure" || catchType == "Incense")
            {
                Console.ForegroundColor = ConsoleColor.Green;
            }
            else if (evt.Cp >= 2000)
            {
                Console.ForegroundColor = ConsoleColor.DarkYellow;
            }
            else if (evt.Cp >= 1250)
            {
                Console.ForegroundColor = ConsoleColor.Cyan;
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.White;
            }
            Logger.Write(
                session.Translation.GetTranslation(TranslationString.EventPokemonCapture, catchStatus, catchType, evt.Id,
                                                   evt.Level, evt.Cp, evt.MaxCp, evt.Perfection.ToString("0.00"), evt.Probability,
                                                   evt.Distance.ToString("F2"),
                                                   returnRealBallName(evt.Pokeball), evt.BallAmount, evt.Exp, familyCandies), evt.Distance > 10000 ? LogLevel.Snipe : LogLevel.Caught);
        }
Пример #17
0
        private void HandleEvent(PokemonCaptureEvent pokemonCaptureEvent, ISession session)
        {
            Func <ItemId, string> returnRealBallName = a =>
            {
                // ReSharper disable once SwitchStatementMissingSomeCases
                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));
                }
            };

            var catchType = pokemonCaptureEvent.CatchType;

            string strStatus;

            switch (pokemonCaptureEvent.Status)
            {
            case CatchPokemonResponse.Types.CatchStatus.CatchError:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusError);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchEscape:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusEscape);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchFlee:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusFlee);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchMissed:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusMissed);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchSuccess:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusSuccess);
                break;

            default:
                strStatus = pokemonCaptureEvent.Status.ToString();
                break;
            }

            var catchStatus = pokemonCaptureEvent.Attempt > 1
                ? session.Translation.GetTranslation(TranslationString.CatchStatusAttempt, strStatus, pokemonCaptureEvent.Attempt)
                : session.Translation.GetTranslation(TranslationString.CatchStatus, strStatus);

            var familyCandies = pokemonCaptureEvent.FamilyCandies > 0
                ? pokemonCaptureEvent.FamilyCandies.ToString()
                : "";

            string message;

            if (pokemonCaptureEvent.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
            {
                message = String.Format("({0}) | ({1}) {2} \n - Lvl: {3}\n - CP: ({4}/{5})\n - IV: {6}%\n - Chance: {7}%\n - from {8}m dist with a {9} ({10} left).\n - {11} EXP earned\n - {12}\n - lat: {13}, long: {14}", catchStatus, catchType, session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id),
                                        pokemonCaptureEvent.Level, pokemonCaptureEvent.Cp, pokemonCaptureEvent.MaxCp, pokemonCaptureEvent.Perfection.ToString("0.00"), pokemonCaptureEvent.Probability,
                                        pokemonCaptureEvent.Distance.ToString("F2"),
                                        returnRealBallName(pokemonCaptureEvent.Pokeball), pokemonCaptureEvent.BallAmount,
                                        pokemonCaptureEvent.Exp, familyCandies, pokemonCaptureEvent.Latitude.ToString("0.000000"), pokemonCaptureEvent.Longitude.ToString("0.000000"));
                Logger.Write(message, LogLevel.Caught);

                this.gui.addPokemonCaught(new string[] {
                    $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}",
                    catchStatus,
                    session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id),
                    pokemonCaptureEvent.Level.ToString(),
                    $"{pokemonCaptureEvent.Cp} / {pokemonCaptureEvent.MaxCp}",
                    pokemonCaptureEvent.Perfection.ToString("0.00") + "%",
                    pokemonCaptureEvent.Probability.ToString("0.00") + "%",
                    pokemonCaptureEvent.Distance.ToString("F2") + "m",
                    catchType,
                    $"{returnRealBallName(pokemonCaptureEvent.Pokeball)} ({pokemonCaptureEvent.BallAmount} left)",
                    pokemonCaptureEvent.Exp.ToString() + "xp",
                    familyCandies
                });
                this.gui.sendEvent("Catch", "success", pokemonCaptureEvent.Id.ToString(), pokemonCaptureEvent.Cp);
            }
            else
            {
                message = session.Translation.GetTranslation(TranslationString.EventPokemonCaptureFailed, catchStatus, catchType, session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id),
                                                             pokemonCaptureEvent.Level, pokemonCaptureEvent.Cp, pokemonCaptureEvent.MaxCp, pokemonCaptureEvent.Perfection.ToString("0.00"), pokemonCaptureEvent.Probability,
                                                             pokemonCaptureEvent.Distance.ToString("F2"),
                                                             returnRealBallName(pokemonCaptureEvent.Pokeball), pokemonCaptureEvent.BallAmount,
                                                             pokemonCaptureEvent.Latitude.ToString("0.000000"), pokemonCaptureEvent.Longitude.ToString("0.000000"));
                Logger.Write(message, LogLevel.Flee);
            }
        }
Пример #18
0
        /// <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), 2);
                    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);
        }
Пример #19
0
        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
                    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;
                Logging.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_;
                    }
                    else
                    {
                        evt.FamilyCandies = caughtPokemonResponse.CaptureAward.Candy.Sum();
                    }
                    session.MapCache.PokemonCaught(pokemon);
                }
                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       = PokemonInfo.CalculateMaxCp(pokeData);
                    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);
            } while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed ||
                     caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape);
            session.State = prevState;
            return(true);
        }
Пример #20
0
        private static void HandleEvent(PokemonCaptureEvent pokemonCaptureEvent, ISession session)
        {
            Func <ItemId, string> returnRealBallName = a =>
            {
                // ReSharper disable once SwitchStatementMissingSomeCases
                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));
                }
            };

            var catchType = pokemonCaptureEvent.CatchType;

            string strStatus;

            switch (pokemonCaptureEvent.Status)
            {
            case CatchPokemonResponse.Types.CatchStatus.CatchError:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusError);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchEscape:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusEscape);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchFlee:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusFlee);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchMissed:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusMissed);
                break;

            case CatchPokemonResponse.Types.CatchStatus.CatchSuccess:
                strStatus = session.Translation.GetTranslation(TranslationString.CatchStatusSuccess);
                break;

            default:
                strStatus = pokemonCaptureEvent.Status.ToString();
                break;
            }

            var catchStatus = pokemonCaptureEvent.Attempt > 1
                ? session.Translation.GetTranslation(TranslationString.CatchStatusAttempt, strStatus,
                                                     pokemonCaptureEvent.Attempt)
                : session.Translation.GetTranslation(TranslationString.CatchStatus, strStatus);

            var familyCandies = pokemonCaptureEvent.Candy?.Candy_ > 0
                ? session.Translation.GetTranslation(TranslationString.Candies, pokemonCaptureEvent.Candy.Candy_)
                : "";

            string message;

            if (pokemonCaptureEvent.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
            {
                message = session.Translation.GetTranslation(TranslationString.EventPokemonCaptureSuccess, catchStatus,
                                                             catchType, session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id),
                                                             pokemonCaptureEvent.Level, pokemonCaptureEvent.Cp, pokemonCaptureEvent.MaxCp,
                                                             pokemonCaptureEvent.Perfection.ToString("0.00"), pokemonCaptureEvent.Probability,
                                                             pokemonCaptureEvent.Distance.ToString("F2"),
                                                             returnRealBallName(pokemonCaptureEvent.Pokeball), pokemonCaptureEvent.BallAmount,
                                                             pokemonCaptureEvent.Exp, familyCandies, pokemonCaptureEvent.Latitude.ToString("0.000000"),
                                                             pokemonCaptureEvent.Longitude.ToString("0.000000"),
                                                             pokemonCaptureEvent.Move1, pokemonCaptureEvent.Move2, pokemonCaptureEvent.Rarity,
                                                             pokemonCaptureEvent.CaptureReason,
                                                             pokemonCaptureEvent.Gender
                                                             );
                Logger.Write(message, LogLevel.Caught);
            }
            else
            {
                message = session.Translation.GetTranslation(TranslationString.EventPokemonCaptureFailed, catchStatus,
                                                             catchType, session.Translation.GetPokemonTranslation(pokemonCaptureEvent.Id),
                                                             pokemonCaptureEvent.Level, pokemonCaptureEvent.Cp, pokemonCaptureEvent.MaxCp,
                                                             pokemonCaptureEvent.Perfection.ToString("0.00"), pokemonCaptureEvent.Probability,
                                                             pokemonCaptureEvent.Distance.ToString("F2"),
                                                             returnRealBallName(pokemonCaptureEvent.Pokeball), pokemonCaptureEvent.BallAmount,
                                                             pokemonCaptureEvent.Latitude.ToString("0.000000"),
                                                             pokemonCaptureEvent.Longitude.ToString("0.000000"),
                                                             pokemonCaptureEvent.Move1, pokemonCaptureEvent.Move2, pokemonCaptureEvent.Rarity
                                                             );
                Logger.Write(message, LogLevel.Flee);
            }
        }
Пример #21
0
        public static async Task Execute(ISession session, CancellationToken cancellationToken, dynamic encounter, MapPokemon pokemon,
                                         FortData currentFortData = null, ulong encounterId = 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);

            // 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)))
            {
                await
                UseBerry(session,
                         encounter is EncounterResponse || encounter is IncenseEncounterResponse
                         ?pokemon.EncounterId
                         : encounterId,
                         encounter is EncounterResponse || encounter is IncenseEncounterResponse
                         ?pokemon.SpawnPointId
                         : currentFortData?.Id);
            }

            // 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;
                }

                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 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, 2000);
            } while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed ||
                     caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape);
        }