/// <summary> /// </summary> /// <param name="parameter">FortData containing the Pokestop that we're visiting</param> /// <param name="mode"></param> /// <param name="suspensionState"></param> /// <returns></returns> public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary <string, object> suspensionState) { if (suspensionState.Any()) { // Recovering the state CurrentPokestopInfo = new FortDetailsResponse(); CurrentSearchResponse = new FortSearchResponse(); CurrentPokestop = JsonConvert.DeserializeObject <FortDataWrapper>((string)suspensionState[nameof(CurrentPokestop)]); CurrentPokestopInfo.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(CurrentPokestop)]).CreateCodedInput()); CurrentSearchResponse.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(CurrentSearchResponse)]).CreateCodedInput()); } else { // Navigating from game page, so we need to actually load the Pokestop Busy.SetBusy(true, "Loading Pokestop"); CurrentPokestop = (FortDataWrapper)NavigationHelper.NavigationState[nameof(CurrentPokestop)]; NavigationHelper.NavigationState.Remove(nameof(CurrentPokestop)); Logger.Write($"Searching {CurrentPokestop.Id}"); CurrentPokestopInfo = await GameClient.GetFort(CurrentPokestop.Id, CurrentPokestop.Latitude, CurrentPokestop.Longitude); Busy.SetBusy(false); // If timeout is expired we can go to to pokestop page if (CurrentPokestop.CooldownCompleteTimestampMs >= DateTime.UtcNow.ToUnixTime()) { // Timeout is not expired yet, player can't get items from the fort SearchInCooldown?.Invoke(null, null); } } }
public static async Task FortFarmed(FortSearchResponse resp, FortData fortData) { OnFortFarmed(null, new FortFarmedArgs() { SearchResponse = resp, Fort = fortData }); await FortFarmedReset.WaitAsync(); FortFarmedReset.Reset(); }
public static string GetSummedFriendlyNameOfItemAwardList(FortSearchResponse items) { var enumerable = items.ItemsAwarded as RepeatedField <POGOProtos.Inventory.Item.ItemAward>; if (!enumerable.Any()) { return(string.Empty); } return (enumerable.GroupBy(i => i.ItemId) .Select(kvp => new { ItemName = kvp.Key.ToString(), Amount = kvp.Sum(x => x.ItemCount) }) .Select(y => $"{y.Amount} x {y.ItemName}") .Aggregate((a, b) => $"{a}, {b}")); }
private async Task <MethodResult> SearchPokestop(FortData pokestop) { try { FortSearchResponse fortResponse = null; int maxFortAttempts = 5; for (int i = 0; i < maxFortAttempts; i++) { fortResponse = await _client.Fort.SearchFort(pokestop.Id, pokestop.Latitude, pokestop.Longitude); if (fortResponse.Result == FortSearchResponse.Types.Result.OutOfRange) { if (_potentialPokeStopBan) { if (AccountState != Enums.AccountState.PokestopBanTemp && AccountState != Enums.AccountState.PokemonBanAndPokestopBanTemp) { LogCaller(new LoggerEventArgs("Pokestop ban detected. Marking state", LoggerTypes.Warning)); } //Already pokemon banned if (AccountState == Enums.AccountState.PokemonBanTemp || AccountState == Enums.AccountState.PokemonBanAndPokestopBanTemp) { AccountState = Enums.AccountState.PokemonBanAndPokestopBanTemp; } else { AccountState = Enums.AccountState.PokestopBanTemp; } //Check for auto stop bot if ((UserSettings.StopAtMinAccountState == Enums.AccountState.PokestopBanTemp || UserSettings.StopAtMinAccountState == Enums.AccountState.PokemonBanOrPokestopBanTemp) || (UserSettings.StopAtMinAccountState == Enums.AccountState.PokemonBanAndPokestopBanTemp && AccountState == Enums.AccountState.PokemonBanAndPokestopBanTemp)) { LogCaller(new LoggerEventArgs("Auto stopping bot ...", LoggerTypes.Info)); Stop(); } } else //This error should never happen normally, so assume temp ban { _potentialPokeStopBan = true; _proxyIssue = true; //Display error only on first notice LogCaller(new LoggerEventArgs("Pokestop out of range. Potential temp pokestop ban or IP ban", LoggerTypes.Warning)); } //Let it continue down } else if (fortResponse.Result != FortSearchResponse.Types.Result.Success && fortResponse.Result != FortSearchResponse.Types.Result.InventoryFull) { LogCaller(new LoggerEventArgs(String.Format("Failed to search fort. Response: {0}", fortResponse.Result), LoggerTypes.Warning)); return(new MethodResult { Message = "Failed to search fort" }); } string message = String.Format("Searched Fort. Exp: {0}. Items: {1}.", fortResponse.ExperienceAwarded, StringUtil.GetSummedFriendlyNameOfItemAwardList(fortResponse.ItemsAwarded.ToList())); if (fortResponse.Result != FortSearchResponse.Types.Result.OutOfRange) { //Successfully grabbed stop if (AccountState == Enums.AccountState.PokemonBanAndPokestopBanTemp || AccountState == Enums.AccountState.PokestopBanTemp) { if (AccountState == Enums.AccountState.PokemonBanAndPokestopBanTemp) { AccountState = Enums.AccountState.PokemonBanTemp; } else { AccountState = Enums.AccountState.Good; } LogCaller(new LoggerEventArgs("Pokestop ban was removed", LoggerTypes.Info)); } ExpIncrease(fortResponse.ExperienceAwarded); TotalPokeStopExp += fortResponse.ExperienceAwarded; ++PokestopsFarmed; if (fortResponse.ExperienceAwarded == 0) { //Softban on the fleeing pokemon. Reset. _fleeingPokemonResponses = 0; _potentialPokemonBan = false; ++_totalZeroExpStops; message += String.Format(" No exp gained. Attempt {0} of {1}", i + 1, maxFortAttempts); } LogCaller(new LoggerEventArgs(message, LoggerTypes.Success)); } if (fortResponse.ExperienceAwarded != 0 || fortResponse.Result == FortSearchResponse.Types.Result.OutOfRange) { if (!_potentialPokemonBan && _fleeingPokemonResponses >= _fleeingPokemonUntilBan) { LogCaller(new LoggerEventArgs("Potential pokemon ban detected. Setting flee count to 0 avoid false positives", LoggerTypes.Warning)); _potentialPokemonBan = true; _fleeingPokemonResponses = 0; } else if (_fleeingPokemonResponses >= _fleeingPokemonUntilBan) { //Already pokestop banned if (AccountState == Enums.AccountState.PokestopBanTemp || AccountState == Enums.AccountState.PokemonBanAndPokestopBanTemp) { _potentialPokemonBan = false; AccountState = Enums.AccountState.PokemonBanAndPokestopBanTemp; } else { _potentialPokemonBan = false; AccountState = Enums.AccountState.PokemonBanTemp; } if (AccountState != Enums.AccountState.PokemonBanTemp) { //Only occurs when out of range is found if (fortResponse.ExperienceAwarded == 0) { LogCaller(new LoggerEventArgs("Pokemon fleeing and failing to grab stops. Potential pokemon & pokestop ban.", LoggerTypes.Warning)); } else { LogCaller(new LoggerEventArgs("Pokemon fleeing, yet grabbing stops. Potential pokemon ban.", LoggerTypes.Warning)); } } if (UserSettings.StopAtMinAccountState == Enums.AccountState.PokemonBanTemp || UserSettings.StopAtMinAccountState == Enums.AccountState.PokemonBanOrPokestopBanTemp || (UserSettings.StopAtMinAccountState == Enums.AccountState.PokemonBanAndPokestopBanTemp && AccountState == Enums.AccountState.PokemonBanAndPokestopBanTemp)) { LogCaller(new LoggerEventArgs("Auto stopping bot ...", LoggerTypes.Info)); Stop(); } return(new MethodResult { Message = "Bans detected", Success = true }); } break; } await Task.Delay(CalculateDelay(UserSettings.DelayBetweenPlayerActions, UserSettings.PlayerActionDelayRandom)); } if (fortResponse != null && fortResponse.ExperienceAwarded == 0) { ++_totalZeroExpStops; if (_totalZeroExpStops >= 15 || _fleeingPokemonResponses >= _fleeingPokemonUntilBan) { _totalZeroExpStops = 0; LogCaller(new LoggerEventArgs("Potential softban detected. Attempting to bypass ...", LoggerTypes.Warning)); int totalAttempts = 0; int maxAttempts = 40; FortSearchResponse bypassResponse = null; do { ++totalAttempts; if (totalAttempts >= 5 && totalAttempts % 5 == 0) { LogCaller(new LoggerEventArgs(String.Format("Softban bypass attempt {0} of {1}", totalAttempts, maxAttempts), LoggerTypes.Info)); } bypassResponse = await _client.Fort.SearchFort(pokestop.Id, pokestop.Latitude, pokestop.Longitude); await Task.Delay(CalculateDelay(UserSettings.DelayBetweenPlayerActions, UserSettings.PlayerActionDelayRandom)); } while (bypassResponse.ExperienceAwarded == 0 && totalAttempts <= maxAttempts); if (bypassResponse.ExperienceAwarded != 0) { //Fleeing pokemon was a softban, reset count _fleeingPokemonResponses = 0; _potentialPokemonBan = false; string message = String.Format("Searched Fort. Exp: {0}. Items: {1}.", bypassResponse.ExperienceAwarded, StringUtil.GetSummedFriendlyNameOfItemAwardList(bypassResponse.ItemsAwarded.ToList())); ExpIncrease(fortResponse.ExperienceAwarded); PokestopsFarmed++; //_expGained += fortResponse.ExperienceAwarded; LogCaller(new LoggerEventArgs(message, LoggerTypes.Success)); LogCaller(new LoggerEventArgs("Softban removed", LoggerTypes.Success)); } else { LogCaller(new LoggerEventArgs("Softban still active. Continuing ...", LoggerTypes.Info)); } } } else { _totalZeroExpStops = 0; } await Task.Delay(CalculateDelay(UserSettings.DelayBetweenPlayerActions, UserSettings.PlayerActionDelayRandom)); return(new MethodResult { Success = true, Message = "Success" }); } catch (Exception ex) { LogCaller(new LoggerEventArgs("Failed to search fort", LoggerTypes.Exception, ex)); return(new MethodResult { Message = "Failed to search fort" }); } }
private async Task <MethodResult> SearchPokestop(FortData pokestop) { try { FortSearchResponse fortResponse = null; const int maxFortAttempts = 5; for (int i = 0; i < maxFortAttempts; i++) { var response = await _client.ClientSession.RpcClient.SendRemoteProcedureCallAsync(new Request { RequestType = RequestType.FortSearch, RequestMessage = new FortSearchMessage { FortId = pokestop.Id, FortLatitude = pokestop.Latitude, FortLongitude = pokestop.Longitude, PlayerLatitude = _client.ClientSession.Player.Latitude, PlayerLongitude = _client.ClientSession.Player.Longitude }.ToByteString() }); try { fortResponse = FortSearchResponse.Parser.ParseFrom(response); } catch (Exception) { return(new MethodResult()); } if (fortResponse.Result == FortSearchResponse.Types.Result.OutOfRange) { if (_potentialPokeStopBan) { if (AccountState != Enums.AccountState.SoftBan) { LogCaller(new LoggerEventArgs("Pokestop ban detected. Marking state", LoggerTypes.Warning)); } AccountState = Enums.AccountState.SoftBan; //Check for auto stop bot if (UserSettings.StopAtMinAccountState == Enums.AccountState.SoftBan) { LogCaller(new LoggerEventArgs("Auto stopping bot ...", LoggerTypes.Info)); Stop(); } } else //This error should never happen normally, so assume temp ban { _potentialPokeStopBan = true; _proxyIssue = true; //Display error only on first notice LogCaller(new LoggerEventArgs("Pokestop out of range. Potential temp pokestop ban or IP ban", LoggerTypes.Warning)); } //Let it continue down } else if (fortResponse.Result != FortSearchResponse.Types.Result.Success) { LogCaller(new LoggerEventArgs(String.Format("Failed to search fort. Response: {0}", fortResponse.Result), LoggerTypes.Warning)); return(new MethodResult { Message = "Failed to search fort" }); } string message = String.Format("Searched Fort. Exp: {0}. Items: {1}.", // Badge: {2}. BonusLoot: {3}. Gems: {4}. Loot: {5}, Eggs: {6:0.0}. RaidTickets: {7}. TeamBonusLoot: {8}", fortResponse.ExperienceAwarded, StringUtil.GetSummedFriendlyNameOfItemAwardList(fortResponse.ItemsAwarded.ToList()) /*, * fortResponse.AwardedGymBadge.ToString(), * fortResponse.BonusLoot.LootItem.ToString(), * fortResponse.GemsAwarded.ToString(), * fortResponse.Loot.LootItem.ToString(), * fortResponse.PokemonDataEgg.EggKmWalkedStart, * fortResponse.RaidTickets.ToString(), * fortResponse.TeamBonusLoot.LootItem.ToString()*/); var itemDictionary = new Dictionary <ItemId, ItemData>(); if (fortResponse.Result != FortSearchResponse.Types.Result.OutOfRange) { //Successfully grabbed stop UpdateInventory(); // <- should not be needed if (AccountState == Enums.AccountState.SoftBan) { AccountState = Enums.AccountState.Good; LogCaller(new LoggerEventArgs("Soft ban was removed", LoggerTypes.Info)); } ExpIncrease(fortResponse.ExperienceAwarded); TotalPokeStopExp += fortResponse.ExperienceAwarded; Tracker.AddValues(0, 1); if (fortResponse.ExperienceAwarded == 0) { //Softban on the fleeing pokemon. Reset. _fleeingPokemonResponses = 0; _potentialPokemonBan = false; ++_totalZeroExpStops; message += String.Format(" No exp gained. Attempt {0} of {1}", i + 1, maxFortAttempts); } LogCaller(new LoggerEventArgs(message, LoggerTypes.Success)); } if (fortResponse.ExperienceAwarded != 0 || fortResponse.Result == FortSearchResponse.Types.Result.OutOfRange) { if (!_potentialPokemonBan && _fleeingPokemonResponses >= _fleeingPokemonUntilBan) { LogCaller(new LoggerEventArgs("Potential pokemon ban detected. Setting flee count to 0 avoid false positives", LoggerTypes.Warning)); _potentialPokemonBan = true; _fleeingPokemonResponses = 0; } else if (_fleeingPokemonResponses >= _fleeingPokemonUntilBan) { //Already pokestop banned if (AccountState == Enums.AccountState.SoftBan) { _potentialPokemonBan = false; _potentialPokemonBan = false; } if (AccountState != Enums.AccountState.SoftBan) { //Only occurs when out of range is found if (fortResponse.ExperienceAwarded == 0) { LogCaller(new LoggerEventArgs("Pokemon fleeing and failing to grab stops. Potential pokemon & pokestop ban.", LoggerTypes.Warning)); } else { LogCaller(new LoggerEventArgs("Pokemon fleeing, yet grabbing stops. Potential pokemon ban.", LoggerTypes.Warning)); } } if (UserSettings.StopAtMinAccountState == Enums.AccountState.SoftBan) { LogCaller(new LoggerEventArgs("Auto stopping bot ...", LoggerTypes.Info)); Stop(); } return(new MethodResult { Message = "Bans detected", Success = true }); } } await Task.Delay(CalculateDelay(UserSettings.DelayBetweenPlayerActions, UserSettings.PlayerActionDelayRandom)); if (fortResponse.Result == FortSearchResponse.Types.Result.Success) { return(new MethodResult { Success = true, Message = "Success" }); } } return(new MethodResult { Success = true, Message = "Success" }); } catch (Exception ex) { LogCaller(new LoggerEventArgs("Failed to search fort", LoggerTypes.Exception, ex)); return(new MethodResult { Message = "Failed to search fort" }); } }
private async Task <MethodResult> SearchPokestop(FortData pokestop) { if (pokestop == null) { return(new MethodResult()); } FortSearchResponse fortResponse = null; const int maxFortAttempts = 5; string fort = pokestop.Type == FortType.Checkpoint ? "Fort" : "Gym"; try { for (int i = 0; i < maxFortAttempts; i++) { if (!_client.LoggedIn) { MethodResult result = await AcLogin(); if (!result.Success) { return(result); } } var response = await _client.ClientSession.RpcClient.SendRemoteProcedureCallAsync(new Request { RequestType = RequestType.FortSearch, RequestMessage = new FortSearchMessage { FortId = pokestop.Id, FortLatitude = pokestop.Latitude, FortLongitude = pokestop.Longitude, PlayerLatitude = _client.ClientSession.Player.Latitude, PlayerLongitude = _client.ClientSession.Player.Longitude }.ToByteString() }); if (response == null) { return(new MethodResult()); } fortResponse = FortSearchResponse.Parser.ParseFrom(response); switch (fortResponse.Result) { case FortSearchResponse.Types.Result.ExceededDailyLimit: LogCaller(new LoggerEventArgs(String.Format("Failed to search {0}. Response: {1}. Stoping ...", fort, fortResponse.Result), LoggerTypes.Warning)); Stop(); break; case FortSearchResponse.Types.Result.InCooldownPeriod: LogCaller(new LoggerEventArgs(String.Format("Failed to search {0}. Response: {1}", fort, fortResponse.Result), LoggerTypes.Warning)); return(new MethodResult()); //break; case FortSearchResponse.Types.Result.InventoryFull: LogCaller(new LoggerEventArgs(String.Format("Failed to search {0}. Response: {1}", fort, fortResponse.Result), LoggerTypes.Warning)); break; case FortSearchResponse.Types.Result.NoResultSet: LogCaller(new LoggerEventArgs(String.Format("Failed to search {0}. Response: {1}", fort, fortResponse.Result), LoggerTypes.Warning)); break; case FortSearchResponse.Types.Result.OutOfRange: if (_potentialPokeStopBan) { if (AccountState != AccountState.SoftBan) { LogCaller(new LoggerEventArgs("Pokestop ban detected. Marking state", LoggerTypes.Warning)); } AccountState = AccountState.SoftBan; if (fortResponse.ExperienceAwarded != 0) { if (!_potentialPokemonBan && _fleeingPokemonResponses >= _fleeingPokemonUntilBan) { LogCaller(new LoggerEventArgs("Potential pokemon ban detected. Setting flee count to 0 avoid false positives", LoggerTypes.Warning)); _potentialPokemonBan = true; _fleeingPokemonResponses = 0; } else if (_fleeingPokemonResponses >= _fleeingPokemonUntilBan) { //Already pokestop banned if (AccountState == AccountState.SoftBan) { _potentialPokemonBan = true; _potentialPokeStopBan = true; } if (AccountState != AccountState.SoftBan) { //Only occurs when out of range is found if (fortResponse.ExperienceAwarded == 0) { LogCaller(new LoggerEventArgs("Pokemon fleeing and failing to grab stops. Potential pokemon & pokestop ban or daily limit reached.", LoggerTypes.Warning)); } else { LogCaller(new LoggerEventArgs("Pokemon fleeing, yet grabbing stops. Potential pokemon ban or daily limit reached.", LoggerTypes.Warning)); } } if (UserSettings.StopAtMinAccountState == AccountState.SoftBan) { LogCaller(new LoggerEventArgs("Auto stopping bot ...", LoggerTypes.Info)); Stop(); } return(new MethodResult { Message = "Bans detected", }); } } } else //This error should never happen normally, so assume temp ban { //_potentialPokeStopBan = true; //_proxyIssue = true; //Display error only on first notice LogCaller(new LoggerEventArgs("Pokestop out of range. Potential temp pokestop ban or IP ban or daily limit reached.", LoggerTypes.Warning)); } _failedPokestopResponse++; //Let it continue down continue; case FortSearchResponse.Types.Result.PoiInaccessible: LogCaller(new LoggerEventArgs(String.Format("Failed to search {0}. Response: {1}", fort, fortResponse.Result), LoggerTypes.Warning)); break; case FortSearchResponse.Types.Result.Success: string message = String.Format("Searched {0}. Exp: {1}. Items: {2}.", // Badge: {3}. BonusLoot: {4}. Gems: {5}. Loot: {6}, Eggs: {7:0.0}. RaidTickets: {8}. TeamBonusLoot: {9}", fort, fortResponse.ExperienceAwarded, StringUtil.GetSummedFriendlyNameOfItemAwardList(fortResponse.ItemsAwarded.ToList()) /*, * fortResponse.AwardedGymBadge.ToString(), * fortResponse.BonusLoot.LootItem.ToString(), * fortResponse.GemsAwarded.ToString(), * fortResponse.Loot.LootItem.ToString(), * fortResponse.PokemonDataEgg.EggKmWalkedStart, * fortResponse.RaidTickets.ToString(), * fortResponse.TeamBonusLoot.LootItem.ToString()*/); //Successfully grabbed stop if (AccountState == AccountState.SoftBan) // || AccountState == Enums.AccountState.HashIssues) { AccountState = AccountState.Good; LogCaller(new LoggerEventArgs("Soft ban was removed", LoggerTypes.Info)); } ExpIncrease(fortResponse.ExperienceAwarded); TotalPokeStopExp += fortResponse.ExperienceAwarded; Tracker.AddValues(0, 1); if (fortResponse.ExperienceAwarded == 0) { //Softban on the fleeing pokemon. Reset. _fleeingPokemonResponses = 0; _potentialPokemonBan = false; ++_totalZeroExpStops; message += String.Format(" No exp gained. Attempt {0} of {1}", i + 1, maxFortAttempts); continue; } LogCaller(new LoggerEventArgs(message, LoggerTypes.Success)); await Task.Delay(CalculateDelay(UserSettings.DelayBetweenPlayerActions, UserSettings.PlayerActionDelayRandom)); return(new MethodResult { Success = true, Message = "Success" }); } } } catch (SessionStateException ex) { throw new SessionStateException(ex.Message); } return(new MethodResult()); }
private void PrintPokestopTakeInfos(FortDetailsResponse fortInfo, FortSearchResponse fortSearch) { StringWriter PokeStopOutput = new StringWriter(); if (fortSearch.ExperienceAwarded == 0) { ColoredConsoleWrite(Color.Cyan, "Wait for unlock catchs ..."); return; } PokeStopOutput.Write($""); if (fortInfo.Name != string.Empty) PokeStopOutput.Write("PokeStop: " + fortInfo.Name); if (fortSearch.ExperienceAwarded != 0) PokeStopOutput.Write($", XP: {fortSearch.ExperienceAwarded}"); if (fortSearch.GemsAwarded != 0) PokeStopOutput.Write($", Gems: {fortSearch.GemsAwarded}"); if (fortSearch.PokemonDataEgg != null) PokeStopOutput.Write($", Eggs: {fortSearch.PokemonDataEgg}"); if (GetFriendlyItemsString(fortSearch.ItemsAwarded) != string.Empty) PokeStopOutput.Write($", Items: {GetFriendlyItemsString(fortSearch.ItemsAwarded)} "); ColoredConsoleWrite(Color.Cyan, PokeStopOutput.ToString()); if (fortSearch.ExperienceAwarded != 0) TotalExperience += (fortSearch.ExperienceAwarded); PokeStopOutput.Dispose(); }
/// <summary> /// Provides a safe way to invoke the <see cref="FortSearchReceived" /> event. /// </summary> /// <param name="value"></param> public void RaiseFortSearchReceived(FortSearchResponse value) => FortSearchReceived?.Invoke(this, value);
private async Task <MethodResult> SearchPokestop(FortData pokestop) { try { FortSearchResponse fortResponse = null; int maxFortAttempts = 5; for (int i = 0; i < maxFortAttempts; i++) { fortResponse = await _client.Fort.SearchFort(pokestop.Id, pokestop.Latitude, pokestop.Longitude); if (fortResponse.Result != FortSearchResponse.Types.Result.Success && fortResponse.Result != FortSearchResponse.Types.Result.InventoryFull) { LogCaller(new LoggerEventArgs(String.Format("Failed to search fort. Response: {0}", fortResponse.Result), LoggerTypes.Warning)); return(new MethodResult { Message = "Failed to search fort" }); } string message = String.Format("Searched Fort. Exp: {0}. Items: {1}.", fortResponse.ExperienceAwarded, StringUtil.GetSummedFriendlyNameOfItemAwardList(fortResponse.ItemsAwarded.ToList())); ExpIncrease(fortResponse.ExperienceAwarded); //_expGained += fortResponse.ExperienceAwarded; if (fortResponse.ExperienceAwarded == 0) { ++_totalZeroExpStops; message += String.Format(" No exp gained. Attempt {0} of {1}", i + 1, maxFortAttempts); } LogCaller(new LoggerEventArgs(message, LoggerTypes.Success)); if (fortResponse.ExperienceAwarded != 0) { break; } await Task.Delay(500); } if (fortResponse != null && fortResponse.ExperienceAwarded == 0) { ++_totalZeroExpStops; if (_totalZeroExpStops >= 15) { _totalZeroExpStops = 0; LogCaller(new LoggerEventArgs("Potential softban detected. Attempting to bypass ...", LoggerTypes.Warning)); int totalAttempts = 0; int maxAttempts = 40; FortSearchResponse bypassResponse = null; do { ++totalAttempts; if (totalAttempts >= 5 && totalAttempts % 5 == 0) { LogCaller(new LoggerEventArgs(String.Format("Softban bypass attempt {0} of {1}", totalAttempts, maxAttempts), LoggerTypes.Info)); } bypassResponse = await _client.Fort.SearchFort(pokestop.Id, pokestop.Latitude, pokestop.Longitude); await Task.Delay(300); } while (bypassResponse.ExperienceAwarded == 0 && totalAttempts <= maxAttempts); if (bypassResponse.ExperienceAwarded != 0) { string message = String.Format("Searched Fort. Exp: {0}. Items: {1}.", bypassResponse.ExperienceAwarded, StringUtil.GetSummedFriendlyNameOfItemAwardList(bypassResponse.ItemsAwarded.ToList())); ExpIncrease(fortResponse.ExperienceAwarded); //_expGained += fortResponse.ExperienceAwarded; LogCaller(new LoggerEventArgs(message, LoggerTypes.Success)); LogCaller(new LoggerEventArgs("Softban removed", LoggerTypes.Success)); } else { LogCaller(new LoggerEventArgs("Softban still active. Continuing ...", LoggerTypes.Info)); } } } else { _totalZeroExpStops = 0; } await Task.Delay(500); return(new MethodResult { Success = true, Message = "Success" }); } catch (Exception ex) { LogCaller(new LoggerEventArgs("Failed to search fort", LoggerTypes.Exception, ex)); return(new MethodResult { Message = "Failed to search fort" }); } }