public async Task <PlayerUpdateResponse> HumanPathWalking(GpxReader.Trkpt trk, double walkingSpeedInKilometersPerHour, Func <Task> functionExecutedWhileWalking) { var targetLocation = new GeoCoordinate(Convert.ToDouble(trk.Lat), Convert.ToDouble(trk.Lon)); var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6; var sourceLocation = new GeoCoordinate(Context.Client.CurrentLatitude, Context.Client.CurrentLongitude); var distanceToTarget = sourceLocation.CalculateDistanceInMeters(targetLocation); Logger.Write($"Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget / speedInMetersPerSecond:0.##} seconds!", LogLevel.Navigation); var seconds = distanceToTarget / speedInMetersPerSecond; //adjust speed to try and keep the trip under a minute, might not be possible if (walkingSpeedInKilometersPerHour < Context.Settings.MaxSpeed && Context.Settings.EnableSpeedAdjustment) { while (seconds > Context.Settings.MaxSecondsBetweenStops && walkingSpeedInKilometersPerHour < Context.Settings.MaxSpeed) { walkingSpeedInKilometersPerHour++; speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6; seconds = distanceToTarget / speedInMetersPerSecond; } } LastKnownSpeed = walkingSpeedInKilometersPerHour; //log distance and time if (seconds > 60) { Logger.Write($"(NAVIGATION) Distance to target location: {distanceToTarget:0.##} meters. Will take {StringUtils.GetSecondsDisplay(seconds)} {StringUtils.GetTravelActionString(walkingSpeedInKilometersPerHour)} at {walkingSpeedInKilometersPerHour}kmh", LogLevel.None, ConsoleColor.Red); } else { Logger.Write($"Distance to target location: {distanceToTarget:0.##} meters. Will take {StringUtils.GetSecondsDisplay(seconds)} {StringUtils.GetTravelActionString(walkingSpeedInKilometersPerHour)} at {walkingSpeedInKilometersPerHour}kmh", LogLevel.Navigation); } var nextWaypointBearing = sourceLocation.DegreeBearing(targetLocation); var nextWaypointDistance = speedInMetersPerSecond; var waypoint = sourceLocation.CreateWaypoint(nextWaypointDistance, nextWaypointBearing, Convert.ToDouble(trk.Ele)); //Initial walking var requestSendDateTime = DateTime.Now; var result = await UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, waypoint.Altitude); do { var millisecondsUntilGetUpdatePlayerLocationResponse = (DateTime.Now - requestSendDateTime).TotalMilliseconds; sourceLocation = new GeoCoordinate(Context.Client.CurrentLatitude, Context.Client.CurrentLongitude); var currentDistanceToTarget = sourceLocation.CalculateDistanceInMeters(targetLocation); nextWaypointDistance = Math.Min(currentDistanceToTarget, millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond); nextWaypointBearing = sourceLocation.DegreeBearing(targetLocation); waypoint = sourceLocation.CreateWaypoint(nextWaypointDistance, nextWaypointBearing); if (Context.Client.Settings.ShowDebugMessages) { Logger.Write($"Distance to target - {currentDistanceToTarget} meters", LogLevel.Debug); } requestSendDateTime = DateTime.Now; result = await UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, waypoint.Altitude); if (functionExecutedWhileWalking != null) { await functionExecutedWhileWalking();// look for pokemon } await Task.Delay(500); } while (sourceLocation.CalculateDistanceInMeters(targetLocation) >= 13); return(result); }
public async Task <PlayerUpdateResponse> HumanLikeWalking(GeoCoordinate targetLocation, double walkingSpeedInKilometersPerHour, Func <Task> functionExecutedWhileWalking, bool allowRandomization = true) { //randomize speed for less detection if (allowRandomization && Context.Settings.EnableSpeedRandomizer) { if (walkingSpeedInKilometersPerHour > 3) { walkingSpeedInKilometersPerHour += RandomHelper.RandomNumber(-2, 3); } else { walkingSpeedInKilometersPerHour += RandomHelper.RandomNumber(0, 2); } } var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6; var sourceLocation = new GeoCoordinate(Context.Client.CurrentLatitude, Context.Client.CurrentLongitude); var distanceToTarget = sourceLocation.CalculateDistanceInMeters(targetLocation); var dynamicLandingDistance = distanceToTarget > 18 ? random.Next(3, 18) : distanceToTarget > 3 ? random.Next(1, 3) : 2; distanceToTarget = distanceToTarget - dynamicLandingDistance; if (distanceToTarget < 1) { distanceToTarget = 1; } var seconds = distanceToTarget / speedInMetersPerSecond; //adjust speed to try and keep the trip under a minute, might not be possible if (walkingSpeedInKilometersPerHour < Context.Settings.MaxSpeed && Context.Settings.EnableSpeedAdjustment) { while (seconds > Context.Settings.MaxSecondsBetweenStops && walkingSpeedInKilometersPerHour < Context.Settings.MaxSpeed) { walkingSpeedInKilometersPerHour++; speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6; seconds = distanceToTarget / speedInMetersPerSecond; } } //record last known speed LastKnownSpeed = walkingSpeedInKilometersPerHour; //log distance and time if (seconds > 300) { Logger.Write($"(NAVIGATION) Distance to target location: {distanceToTarget:0.##} meters. Will take {StringUtils.GetSecondsDisplay(seconds)} {StringUtils.GetTravelActionString(walkingSpeedInKilometersPerHour)} at {walkingSpeedInKilometersPerHour}kmh", LogLevel.None, ConsoleColor.Red); } else { Logger.Write($"Distance to target location: {distanceToTarget:0.##} meters. Will take {StringUtils.GetSecondsDisplay(seconds)} {StringUtils.GetTravelActionString(walkingSpeedInKilometersPerHour)} at {walkingSpeedInKilometersPerHour}kmh", LogLevel.Navigation); } //get next bearing var nextWaypointBearing = sourceLocation.DegreeBearing(targetLocation); //log debug messages if (Context.Client.Settings.ShowDebugMessages) { Logger.Write($"From {sourceLocation} to {targetLocation} bearing {Math.Round(nextWaypointBearing,1)}", LogLevel.Debug); var distanceFromStart = Navigation.CalculateDistanceInMeters( Context.Client.CurrentLatitude, Context.Client.CurrentLongitude, Context.Settings.WaypointLatitude, Context.Settings.WaypointLongitude); Logger.Write($"{Math.Round(distanceFromStart, 1)} meters from current waypoint ({Context.Settings.MaxDistance} meters max)", LogLevel.Debug); } var nextWaypointDistance = speedInMetersPerSecond; var waypoint = sourceLocation.CreateWaypoint(nextWaypointDistance, nextWaypointBearing); //Initial walking var requestSendDateTime = DateTime.Now; var result = await UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, Context.Client.Settings.CurrentAltitude); var minMetersPerSecond = Context.Client.Settings.MinSpeed / 3.6; var enableCurve = distanceToTarget > (Context.Client.Settings.SpeedCurveDistance * 2); do { var millisecondsUntilGetUpdatePlayerLocationResponse = (DateTime.Now - requestSendDateTime).TotalMilliseconds; sourceLocation = new GeoCoordinate(Context.Client.CurrentLatitude, Context.Client.CurrentLongitude); var currentDistanceToTarget = sourceLocation.CalculateDistanceInMeters(targetLocation); //if (Context.Client.Settings.DebugMode) //Logger.Write($"Distance to target location: {currentDistanceToTarget:0.##} meters. Will take {currentDistanceToTarget / speedInMetersPerSecond:0.##} seconds!", LogLevel.Navigation); if (enableCurve && currentDistanceToTarget < Context.Client.Settings.SpeedCurveDistance && speedInMetersPerSecond > (minMetersPerSecond + .2)) { speedInMetersPerSecond -= .55; LastKnownSpeed = speedInMetersPerSecond * 3.6; if (Context.Client.Settings.ShowDebugMessages) { Logger.Write($"{Math.Round(currentDistanceToTarget,1)} meters from the target, slowing down to {LastKnownSpeed}...", LogLevel.Debug); } } nextWaypointDistance = Math.Min(currentDistanceToTarget, millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond); nextWaypointBearing = sourceLocation.DegreeBearing(targetLocation); waypoint = sourceLocation.CreateWaypoint(nextWaypointDistance, nextWaypointBearing); requestSendDateTime = DateTime.Now; result = await UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, Context.Client.Settings.CurrentAltitude); if (functionExecutedWhileWalking != null) { await functionExecutedWhileWalking();// look for pokemon } //check for needs new login if (PokeRoadieLogic.NeedsNewLogin) { return(result); } await Task.Delay(500); } while (sourceLocation.CalculateDistanceInMeters(targetLocation) >= dynamicLandingDistance); return(result); }