Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleaned up navigation logic. Cached inventory requests #153

Merged
merged 1 commit into from
Jul 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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