diff --git a/PokemonGo.RocketAPI.Console/App.config b/PokemonGo.RocketAPI.Console/App.config
index 7b4eede..4f58a92 100644
--- a/PokemonGo.RocketAPI.Console/App.config
+++ b/PokemonGo.RocketAPI.Console/App.config
@@ -59,11 +59,17 @@
<value>password</value>
</setting>
<setting name="PrioritizeIVOverCP" serializeAs="String">
- <value>False</value>
+ <value>True</value>
</setting>
<setting name="MaxTravelDistanceInMeters" serializeAs="String">
<value>1000</value>
</setting>
+ <setting name="UseGPXPathing" serializeAs="String">
+ <value>False</value>
+ </setting>
+ <setting name="GPXFile" serializeAs="String">
+ <value>GPXFile.GPX</value>
+ </setting>
</PokemonGo.RocketAPI.Console.UserSettings>
</userSettings>
</configuration>
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Console/Settings.cs b/PokemonGo.RocketAPI.Console/Settings.cs
index 2b823eb..16711c0 100644
--- a/PokemonGo.RocketAPI.Console/Settings.cs
+++ b/PokemonGo.RocketAPI.Console/Settings.cs
@@ -32,6 +32,9 @@ namespace PokemonGo.RocketAPI.Console
public bool PrioritizeIVOverCP => UserSettings.Default.PrioritizeIVOverCP;
public int MaxTravelDistanceInMeters => UserSettings.Default.MaxTravelDistanceInMeters;
+ public bool UseGPXPathing => UserSettings.Default.UseGPXPathing;
+ public string GPXFile => UserSettings.Default.GPXFile;
+
private ICollection<PokemonId> _pokemonsToEvolve;
private ICollection<PokemonId> _pokemonsNotToTransfer;
private ICollection<PokemonId> _pokemonsNotToCatch;
diff --git a/PokemonGo.RocketAPI.Console/UserSettings.Designer.cs b/PokemonGo.RocketAPI.Console/UserSettings.Designer.cs
index 9b0046f..1c5a32e 100644
--- a/PokemonGo.RocketAPI.Console/UserSettings.Designer.cs
+++ b/PokemonGo.RocketAPI.Console/UserSettings.Designer.cs
@@ -181,7 +181,7 @@ namespace PokemonGo.RocketAPI.Console {
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool PrioritizeIVOverCP {
get {
return ((bool)(this["PrioritizeIVOverCP"]));
@@ -202,5 +202,29 @@ namespace PokemonGo.RocketAPI.Console {
this["MaxTravelDistanceInMeters"] = value;
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool UseGPXPathing {
+ get {
+ return ((bool)(this["UseGPXPathing"]));
+ }
+ set {
+ this["UseGPXPathing"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("GPXFile.GPX")]
+ public string GPXFile {
+ get {
+ return ((string)(this["GPXFile"]));
+ }
+ set {
+ this["GPXFile"] = value;
+ }
+ }
}
}
diff --git a/PokemonGo.RocketAPI.Console/UserSettings.settings b/PokemonGo.RocketAPI.Console/UserSettings.settings
index 7c7f600..5c0b59b 100644
--- a/PokemonGo.RocketAPI.Console/UserSettings.settings
+++ b/PokemonGo.RocketAPI.Console/UserSettings.settings
@@ -42,10 +42,16 @@
<Value Profile="(Default)">password</Value>
</Setting>
<Setting Name="PrioritizeIVOverCP" Type="System.Boolean" Scope="User">
- <Value Profile="(Default)">False</Value>
+ <Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="MaxTravelDistanceInMeters" Type="System.Int32" Scope="User">
<Value Profile="(Default)">1000</Value>
</Setting>
+ <Setting Name="UseGPXPathing" Type="System.Boolean" Scope="User">
+ <Value Profile="(Default)">False</Value>
+ </Setting>
+ <Setting Name="GPXFile" Type="System.String" Scope="User">
+ <Value Profile="(Default)">GPXFile.GPX</Value>
+ </Setting>
</Settings>
</SettingsFile>
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Logic/Logic.cs b/PokemonGo.RocketAPI.Logic/Logic.cs
index 79580a2..baf544c 100644
--- a/PokemonGo.RocketAPI.Logic/Logic.cs
+++ b/PokemonGo.RocketAPI.Logic/Logic.cs
@@ -129,7 +129,7 @@ namespace PokemonGo.RocketAPI.Logic
if (_clientSettings.TransferDuplicatePokemon) await TransferDuplicatePokemon();
await PokemonToCSV();
await RecycleItems();
- await ExecuteFarmingPokestopsAndPokemons();
+ await ExecuteFarmingPokestopsAndPokemons(_clientSettings.UseGPXPathing);
/*
* Example calls below
@@ -145,6 +145,100 @@ namespace PokemonGo.RocketAPI.Logic
}
}
+ private async Task ExecuteFarmingPokestopsAndPokemons(bool path = false)
+ {
+ if (!path)
+ await ExecuteFarmingPokestopsAndPokemons();
+ else
+ {
+ //bool onTrack = true;
+ List<GPXReader.trk> Tracks = GetGPXTracks(_clientSettings.GPXFile);
+ int curTrkPt = 0;
+ int maxTrkPt = 0;
+ int curTrk = 0;
+ int maxTrk = Tracks.Count - 1;
+ int curTrkSeg = 0;
+ int maxTrkSeg = 0;
+ while (curTrk <= maxTrk)
+ {
+ var Track = Tracks.ElementAt(curTrk);
+ var trackSegments = Track.Segments;
+ maxTrkSeg = trackSegments.Count - 1;
+ while (curTrkSeg <= maxTrkSeg)
+ {
+ List<GPXReader.trkpt> TrackPoints = Track.Segments.ElementAt(0).TrackPoints;
+ maxTrkPt = TrackPoints.Count - 1;
+ var mapObjects = await _client.GetMapObjects();
+ while (curTrkPt <= maxTrkPt)
+ {
+ GPXReader.trkpt nextPoint = TrackPoints.ElementAt(curTrkPt);
+ if (LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, Convert.ToDouble(nextPoint.Lat), Convert.ToDouble(nextPoint.Lon)) > 5000)
+ {
+ Logger.Write($"Your desired destination of {nextPoint.Lat}, {nextPoint.Lon} is too far from your current position of {_client.CurrentLat}, {_client.CurrentLng}", LogLevel.Error);
+ break;
+ }
+
+ Logger.Write($"Your desired destination is {nextPoint.Lat}, your location is {nextPoint.Lon} {_client.CurrentLat}, {_client.CurrentLng}", LogLevel.Warning);
+
+ // Wasn't sure how to make this pretty. Edit as needed.
+ var pokeStops =
+ mapObjects.MapCells.SelectMany(i => i.Forts)
+ .Where(
+ i =>
+ i.Type == FortType.Checkpoint &&
+ i.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime() &&
+ ( // Make sure PokeStop is within 40 meters, otherwise we cannot hit them.
+ LocationUtils.CalculateDistanceInMeters(
+ _client.CurrentLat, _client.CurrentLng,
+ i.Latitude, i.Longitude) < 40)
+ );
+
+ var pokestopList = pokeStops.ToList();
+
+ while (pokestopList.Any())
+ {
+ pokestopList = pokestopList.OrderBy(i => LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude)).ToList();
+ var pokeStop = pokestopList[0];
+ pokestopList.RemoveAt(0);
+
+ var fortInfo = await _client.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
+
+ var fortSearch = await _client.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
+ if (fortSearch.ExperienceAwarded > 0)
+ {
+ _stats.AddExperience(fortSearch.ExperienceAwarded);
+ _stats.UpdateConsoleTitle(_inventory);
+ //todo: fix egg crash
+ Logger.Write($"XP: {fortSearch.ExperienceAwarded}, Gems: {fortSearch.GemsAwarded}, Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}", LogLevel.Pokestop);
+ }
+
+ await Task.Delay(1000);
+ await RecycleItems();
+ if (_clientSettings.TransferDuplicatePokemon) await TransferDuplicatePokemon();
+
+
+ }
+
+ var update = await _navigation.HumanPathWalking(TrackPoints.ElementAt(curTrkPt), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);
+
+ if (curTrkPt >= maxTrkPt)
+ curTrkPt = 0;
+ else
+ curTrkPt++;
+
+ }//end trkpts
+ if (curTrkSeg >= maxTrkSeg)
+ curTrkSeg = 0;
+ else
+ curTrkSeg++;
+ }//end trksegs
+ if (curTrk >= maxTrkSeg)
+ curTrk = 0;
+ else
+ curTrk++;
+ }//end tracks
+ }
+ }
private async Task ExecuteFarmingPokestopsAndPokemons()
{
var distanceFromStart = LocationUtils.CalculateDistanceInMeters(
@@ -514,7 +608,36 @@ namespace PokemonGo.RocketAPI.Logic
}
}
+ private async Task LoadAndDisplayGPXFile()
+ {
+ string xmlString = File.ReadAllText(_clientSettings.GPXFile);
+ GPXReader Readgpx = new GPXReader(xmlString);
+ foreach (GPXReader.trk trk in Readgpx.Tracks)
+ {
+ foreach (GPXReader.trkseg trkseg in trk.Segments)
+ {
+ foreach (GPXReader.trkpt trpkt in trkseg.TrackPoints)
+ {
+ Console.WriteLine(trpkt.ToString());
+ }
+ }
+ }
+ await Task.Delay(0);
+ }
+ private GPXReader.trk GetGPXTrack(string gpxFile)
+ {
+ string xmlString = File.ReadAllText(_clientSettings.GPXFile);
+ GPXReader Readgpx = new GPXReader(xmlString);
+ return Readgpx.Tracks.ElementAt(0);
+ }
+
+ private List<GPXReader.trk> GetGPXTracks(string gpxFile)
+ {
+ string xmlString = File.ReadAllText(_clientSettings.GPXFile);
+ GPXReader Readgpx = new GPXReader(xmlString);
+ return Readgpx.Tracks;
+ }
}
}
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Logic/Navigation.cs b/PokemonGo.RocketAPI.Logic/Navigation.cs
index 96e8a5d..1486473 100644
--- a/PokemonGo.RocketAPI.Logic/Navigation.cs
+++ b/PokemonGo.RocketAPI.Logic/Navigation.cs
@@ -76,6 +76,64 @@ namespace PokemonGo.RocketAPI.Logic
return result;
}
+ public async Task<PlayerUpdateResponse> HumanPathWalking(GPXReader.trkpt trk, double walkingSpeedInKilometersPerHour, Func<Task> functionExecutedWhileWalking)
+ {
+ //PlayerUpdateResponse result = null;
+
+ var targetLocation = new GeoCoordinate(Convert.ToDouble(trk.Lat), Convert.ToDouble(trk.Lon));
+
+ var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6;
+
+ 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);
+
+ var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
+ var nextWaypointDistance = speedInMetersPerSecond;
+ var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing, Convert.ToDouble(trk.Ele));
+
+ //Initial walking
+
+ var requestSendDateTime = DateTime.Now;
+ var result =
+ await
+ _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, waypoint.Altitude);
+
+ do
+ {
+ var millisecondsUntilGetUpdatePlayerLocationResponse =
+ (DateTime.Now - requestSendDateTime).TotalMilliseconds;
+
+ sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
+ var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
+
+ //if (currentDistanceToTarget < 40)
+ //{
+ // if (speedInMetersPerSecond > SpeedDownTo)
+ // {
+ // //Logger.Write("We are within 40 meters of the target. Speeding down to 10 km/h to not pass the target.", LogLevel.Info);
+ // speedInMetersPerSecond = SpeedDownTo;
+ // }
+ //}
+
+ nextWaypointDistance = Math.Min(currentDistanceToTarget,
+ millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
+ nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
+ waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
+
+ requestSendDateTime = DateTime.Now;
+ result =
+ await
+ _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude,
+ waypoint.Altitude);
+ if (functionExecutedWhileWalking != null)
+ await functionExecutedWhileWalking();// look for pokemon
+ await Task.Delay(Math.Min((int)(distanceToTarget / speedInMetersPerSecond * 1000), 3000));
+ } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30);
+
+ return result;
+ }
+
public static FortData[] pathByNearestNeighbour(FortData[] pokeStops)
{
for (var i = 1; i < pokeStops.Length - 1; i++)
diff --git a/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj b/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
index bb4377b..5c6e5a4 100644
--- a/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
+++ b/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
@@ -55,6 +55,7 @@
<Compile Include="Logic.cs" />
<Compile Include="Navigation.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Utils\GPXReader.cs" />
<Compile Include="Utils\LocationUtils.cs" />
<Compile Include="Utils\Statistics.cs" />
<Compile Include="Utils\StringUtils.cs" />
diff --git a/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs b/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
index 2a44693..e250a36 100644
--- a/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
+++ b/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
@@ -50,6 +50,33 @@ namespace PokemonGo.RocketAPI.Logic.Utils
return new GeoCoordinate(ToDegrees(targetLatitudeRadians), ToDegrees(targetLongitudeRadians));
}
+ public static GeoCoordinate CreateWaypoint(GeoCoordinate sourceLocation, double distanceInMeters, double bearingDegrees, double altitude)
+ //from http://stackoverflow.com/a/17545955
+ {
+ var distanceKm = distanceInMeters / 1000.0;
+ var distanceRadians = distanceKm / 6371; //6371 = Earth's radius in km
+
+ var bearingRadians = ToRad(bearingDegrees);
+ var sourceLatitudeRadians = ToRad(sourceLocation.Latitude);
+ var sourceLongitudeRadians = ToRad(sourceLocation.Longitude);
+
+ var targetLatitudeRadians = Math.Asin(Math.Sin(sourceLatitudeRadians) * Math.Cos(distanceRadians)
+ +
+ Math.Cos(sourceLatitudeRadians) * Math.Sin(distanceRadians) *
+ Math.Cos(bearingRadians));
+
+ var targetLongitudeRadians = sourceLongitudeRadians + Math.Atan2(Math.Sin(bearingRadians)
+ * Math.Sin(distanceRadians) *
+ Math.Cos(sourceLatitudeRadians),
+ Math.Cos(distanceRadians)
+ - Math.Sin(sourceLatitudeRadians) * Math.Sin(targetLatitudeRadians));
+
+ // adjust toLonRadians to be in the range -180 to +180...
+ targetLongitudeRadians = (targetLongitudeRadians + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
+
+ return new GeoCoordinate(ToDegrees(targetLatitudeRadians), ToDegrees(targetLongitudeRadians), altitude);
+ }
+
public static double DegreeBearing(GeoCoordinate sourceLocation, GeoCoordinate targetLocation)
// from http://stackoverflow.com/questions/2042599/direction-between-2-latitude-longitude-points-in-c-sharp
{
diff --git a/PokemonGo.RocketAPI/ISettings.cs b/PokemonGo.RocketAPI/ISettings.cs
index 043ee76..c935e24 100644
--- a/PokemonGo.RocketAPI/ISettings.cs
+++ b/PokemonGo.RocketAPI/ISettings.cs
@@ -27,6 +27,9 @@ namespace PokemonGo.RocketAPI
bool PrioritizeIVOverCP { get; }
int MaxTravelDistanceInMeters { get; }
+ bool UseGPXPathing { get; }
+ string GPXFile { get; }
+
ICollection<KeyValuePair<ItemId, int>> ItemRecycleFilter { get; }
ICollection<PokemonId> PokemonsToEvolve { get; }
diff --git a/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj b/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
index a758415..61ddc2d 100644
--- a/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
+++ b/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
@@ -17,7 +17,7 @@
<UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
<AssemblyVersionSettings>YearStamp.MonthStamp.DayStamp.Increment</AssemblyVersionSettings>
<PrimaryVersionType>AssemblyVersionAttribute</PrimaryVersionType>
- <AssemblyVersion>2016.7.24.283</AssemblyVersion>
+ <AssemblyVersion>2016.7.24.286</AssemblyVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
diff --git a/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs b/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
index 68d9d4d..951128e 100644
--- a/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
+++ b/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2016.7.24.283")]
+[assembly: AssemblyVersion("2016.7.24.286")]
[assembly: AssemblyFileVersion("1.0.0.0")]
You may download the files in Public Git.