Skip to content

Commit

Permalink
Merge pull request #153 from AlginMaduro/master
Browse files Browse the repository at this point in the history
Cleaned up navigation logic. Cached inventory requests
  • Loading branch information
NecronomiconCoding authored Jul 23, 2016
2 parents 1505ce6 + 90ec00d commit 5f0bb7d
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 62 deletions.
50 changes: 41 additions & 9 deletions PokemonGo.RocketAPI.Logic/Inventory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
using System.Threading.Tasks;
using PokemonGo.RocketAPI.Enums;
using PokemonGo.RocketAPI.GeneratedCode;
using System.Collections.Concurrent;
using System;
using System.Threading;

#endregion

Expand All @@ -13,6 +16,8 @@ namespace PokemonGo.RocketAPI.Logic
public class Inventory
{
private readonly Client _client;
private DateTime _lastRefresh;
private GetInventoryResponse _cachedInventory;

public Inventory(Client client)
{
Expand Down Expand Up @@ -48,7 +53,7 @@ public async Task<IEnumerable<PokemonData>> GetDuplicatePokemonToTransfer(
if (settings.CandyToEvolve == 0)
continue;

var amountToSkip = familyCandy.Candy/settings.CandyToEvolve;
var amountToSkip = familyCandy.Candy / settings.CandyToEvolve;

results.AddRange(pokemonList.Where(x => x.PokemonId == pokemon.Key && x.Favorite == 0)
.OrderByDescending(x => x.Cp)
Expand Down Expand Up @@ -98,12 +103,12 @@ public async Task<PokemonData> GetHighestPokemonOfTypeByCP(PokemonData pokemon)
public async Task<int> GetItemAmountByType(MiscEnums.Item type)
{
var pokeballs = await GetItems();
return pokeballs.FirstOrDefault(i => (MiscEnums.Item) i.Item_ == type)?.Count ?? 0;
return pokeballs.FirstOrDefault(i => (MiscEnums.Item)i.Item_ == type)?.Count ?? 0;
}

public async Task<IEnumerable<Item>> GetItems()
{
var inventory = await _client.GetInventory();
var inventory = await getCachedInventory();
return inventory.InventoryDelta.InventoryItems
.Select(i => i.InventoryItemData?.Item)
.Where(p => p != null);
Expand All @@ -114,36 +119,36 @@ public async Task<IEnumerable<Item>> GetItemsToRecycle(ISettings settings)
var myItems = await GetItems();

return myItems
.Where(x => settings.ItemRecycleFilter.Any(f => f.Key == (ItemId) x.Item_ && x.Count > f.Value))
.Where(x => settings.ItemRecycleFilter.Any(f => f.Key == (ItemId)x.Item_ && x.Count > f.Value))
.Select(
x =>
new Item
{
Item_ = x.Item_,
Count = x.Count - settings.ItemRecycleFilter.Single(f => f.Key == (ItemId) x.Item_).Value,
Count = x.Count - settings.ItemRecycleFilter.Single(f => f.Key == (ItemId)x.Item_).Value,
Unseen = x.Unseen
});
}

public async Task<IEnumerable<PlayerStats>> GetPlayerStats()
{
var inventory = await _client.GetInventory();
var inventory = await getCachedInventory();
return inventory.InventoryDelta.InventoryItems
.Select(i => i.InventoryItemData?.PlayerStats)
.Where(p => p != null);
}

public async Task<IEnumerable<PokemonFamily>> GetPokemonFamilies()
{
var inventory = await _client.GetInventory();
var inventory = await getCachedInventory();
return
inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.PokemonFamily)
.Where(p => p != null && p.FamilyId != PokemonFamilyId.FamilyUnset);
}

public async Task<IEnumerable<PokemonData>> GetPokemons()
{
var inventory = await _client.GetInventory();
var inventory = await getCachedInventory();
return
inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.Pokemon)
.Where(p => p != null && p.PokemonId > 0);
Expand Down Expand Up @@ -186,13 +191,40 @@ public async Task<IEnumerable<PokemonData>> GetPokemonToEvolve(IEnumerable<Pokem

var pokemonCandyNeededAlready =
pokemonToEvolve.Count(
p => pokemonSettings.Single(x => x.PokemonId == p.PokemonId).FamilyId == settings.FamilyId)*
p => pokemonSettings.Single(x => x.PokemonId == p.PokemonId).FamilyId == settings.FamilyId) *
settings.CandyToEvolve;
if (familyCandy.Candy - pokemonCandyNeededAlready > settings.CandyToEvolve)
pokemonToEvolve.Add(pokemon);
}

return pokemonToEvolve;
}


private async Task<GetInventoryResponse> getCachedInventory()
{
var now = DateTime.UtcNow;
SemaphoreSlim ss = new SemaphoreSlim(10);

if (_lastRefresh != null && _lastRefresh.AddSeconds(30).Ticks > now.Ticks)
{
return _cachedInventory;
}
else
{
await ss.WaitAsync();
try
{
_lastRefresh = now;
_cachedInventory = await _client.GetInventory();
return _cachedInventory;
}
finally
{
ss.Release();
}
}

}
}
}
17 changes: 7 additions & 10 deletions PokemonGo.RocketAPI.Logic/Logic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using PokemonGo.RocketAPI.GeneratedCode;
using PokemonGo.RocketAPI.Helpers;
using PokemonGo.RocketAPI.Logic.Utils;
using System.Device.Location;

#endregion

Expand Down Expand Up @@ -52,7 +53,7 @@ private async Task CatchEncounter(EncounterResponse encounter, MapPokemon pokemo
}

var pokeball = await GetBestBall(encounter?.WildPokemon);
var distance = Navigation.DistanceBetween2Coordinates(_client.CurrentLat, _client.CurrentLng,
var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng,
pokemon.Latitude, pokemon.Longitude);
caughtPokemonResponse =
await
Expand Down Expand Up @@ -272,9 +273,7 @@ private async Task ExecuteCatchAllNearbyPokemons()
mapObjects.MapCells.SelectMany(i => i.CatchablePokemons)
.OrderBy(
i =>
LocationUtils.CalculateDistanceInMeters(
new Navigation.Location(_client.CurrentLat, _client.CurrentLng),
new Navigation.Location(i.Latitude, i.Longitude)));
LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng,i.Latitude, i.Longitude));

foreach (var pokemon in pokemons)
{
Expand All @@ -286,7 +285,7 @@ private async Task ExecuteCatchAllNearbyPokemons()
continue;
}

var distance = Navigation.DistanceBetween2Coordinates(_client.CurrentLat, _client.CurrentLng,
var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng,
pokemon.Latitude, pokemon.Longitude);
await Task.Delay(distance > 100 ? 15000 : 500);

Expand Down Expand Up @@ -314,18 +313,16 @@ private async Task ExecuteFarmingPokestopsAndPokemons()
i.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime())
.OrderBy(
i =>
LocationUtils.CalculateDistanceInMeters(
new Navigation.Location(_client.CurrentLat, _client.CurrentLng),
new Navigation.Location(i.Latitude, i.Longitude)));
LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng,i.Latitude, i.Longitude));

foreach (var pokeStop in pokeStops)
{
var distance = Navigation.DistanceBetween2Coordinates(_client.CurrentLat, _client.CurrentLng,
var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng,
pokeStop.Latitude, pokeStop.Longitude);

var update =
await
_navigation.HumanLikeWalking(new Navigation.Location(pokeStop.Latitude, pokeStop.Longitude),
_navigation.HumanLikeWalking(new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude),
_clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);

var fortInfo = await _client.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
Expand Down
31 changes: 4 additions & 27 deletions PokemonGo.RocketAPI.Logic/Navigation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading.Tasks;
using PokemonGo.RocketAPI.GeneratedCode;
using PokemonGo.RocketAPI.Logic.Utils;
using System.Device.Location;

#endregion

Expand All @@ -19,24 +20,12 @@ public Navigation(Client client)
_client = client;
}

public static double DistanceBetween2Coordinates(double lat1, double lng1, double lat2, double lng2)
{
const double rEarth = 6378137;
var dLat = (lat2 - lat1)*Math.PI/180;
var dLon = (lng2 - lng1)*Math.PI/180;
var alpha = Math.Sin(dLat/2)*Math.Sin(dLat/2)
+ Math.Cos(lat1*Math.PI/180)*Math.Cos(lat2*Math.PI/180)
*Math.Sin(dLon/2)*Math.Sin(dLon/2);
var d = 2*rEarth*Math.Atan2(Math.Sqrt(alpha), Math.Sqrt(1 - alpha));
return d;
}

public async Task<PlayerUpdateResponse> HumanLikeWalking(Location targetLocation,
public async Task<PlayerUpdateResponse> HumanLikeWalking(GeoCoordinate targetLocation,
double walkingSpeedInKilometersPerHour, Func<Task> functionExecutedWhileWalking)
{
var speedInMetersPerSecond = walkingSpeedInKilometersPerHour/3.6;

var sourceLocation = new Location(_client.CurrentLat, _client.CurrentLng);
var sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
var distanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
// Logger.Write($"Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget/speedInMetersPerSecond:0.##} seconds!", LogLevel.Info);

Expand All @@ -57,7 +46,7 @@ public async Task<PlayerUpdateResponse> HumanLikeWalking(Location targetLocation
var millisecondsUntilGetUpdatePlayerLocationResponse =
(DateTime.Now - requestSendDateTime).TotalMilliseconds;

sourceLocation = new Location(_client.CurrentLat, _client.CurrentLng);
sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);

if (currentDistanceToTarget < 40)
Expand All @@ -84,17 +73,5 @@ public async Task<PlayerUpdateResponse> HumanLikeWalking(Location targetLocation

return result;
}

public class Location
{
public Location(double latitude, double longitude)
{
Latitude = latitude;
Longitude = longitude;
}

public double Latitude { get; set; }
public double Longitude { get; set; }
}
}
}
1 change: 1 addition & 0 deletions PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Device" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
Expand Down
28 changes: 12 additions & 16 deletions PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#region

using System;
using System.Device.Location;
using static PokemonGo.RocketAPI.Logic.Navigation;

#endregion
Expand All @@ -9,26 +10,21 @@ namespace PokemonGo.RocketAPI.Logic.Utils
{
public static class LocationUtils
{
public static double CalculateDistanceInMeters(Location sourceLocation, Location targetLocation)
public static double CalculateDistanceInMeters(double sourceLat, double sourceLng, double destLat, double destLng)
// from http://stackoverflow.com/questions/6366408/calculating-distance-between-two-latitude-and-longitude-geocoordinates
{
var baseRad = Math.PI*sourceLocation.Latitude/180;
var targetRad = Math.PI*targetLocation.Latitude/180;
var theta = sourceLocation.Longitude - targetLocation.Longitude;
var thetaRad = Math.PI*theta/180;
var sourceLocation = new GeoCoordinate(sourceLat, sourceLng);
var targetLocation = new GeoCoordinate(destLat, destLng);

var dist =
Math.Sin(baseRad)*Math.Sin(targetRad) + Math.Cos(baseRad)*
Math.Cos(targetRad)*Math.Cos(thetaRad);
dist = Math.Acos(dist);

dist = dist*180/Math.PI;
dist = dist*60*1.1515*1.609344*1000;
return sourceLocation.GetDistanceTo(targetLocation);
}

return dist;
public static double CalculateDistanceInMeters(GeoCoordinate sourceLocation, GeoCoordinate destinationLocation)
{
return CalculateDistanceInMeters(sourceLocation.Latitude, sourceLocation.Longitude, destinationLocation.Latitude, destinationLocation.Longitude);
}

public static Location CreateWaypoint(Location sourceLocation, double distanceInMeters, double bearingDegrees)
public static GeoCoordinate CreateWaypoint(GeoCoordinate sourceLocation, double distanceInMeters, double bearingDegrees)
//from http://stackoverflow.com/a/17545955
{
var distanceKm = distanceInMeters/1000.0;
Expand All @@ -52,10 +48,10 @@ public static Location CreateWaypoint(Location sourceLocation, double distanceIn
// adjust toLonRadians to be in the range -180 to +180...
targetLongitudeRadians = (targetLongitudeRadians + 3*Math.PI)%(2*Math.PI) - Math.PI;

return new Location(ToDegrees(targetLatitudeRadians), ToDegrees(targetLongitudeRadians));
return new GeoCoordinate(ToDegrees(targetLatitudeRadians), ToDegrees(targetLongitudeRadians));
}

public static double DegreeBearing(Location sourceLocation, Location targetLocation)
public static double DegreeBearing(GeoCoordinate sourceLocation, GeoCoordinate targetLocation)
// from http://stackoverflow.com/questions/2042599/direction-between-2-latitude-longitude-points-in-c-sharp
{
var dLon = ToRad(targetLocation.Longitude - sourceLocation.Longitude);
Expand Down

0 comments on commit 5f0bb7d

Please sign in to comment.