private FleetSaveTarget CandidateFromGalaxy(BotDb db, Coordinate here, int fleetSpeed)
        {
            SystemCoordinate hereSystem = here;
            FleetSaveTarget  best       = null;

            for (int speed = 1; speed <= 10 && best == null; speed++)
            {
                for (short range = 1; range <= 100 && best == null; range++)
                {
                    short systemCoordLeft  = (short)(hereSystem.System - range);
                    short systemCoordRight = (short)(hereSystem.System + range);
                    if (systemCoordLeft <= 0)
                    {
                        systemCoordLeft = 0;
                    }
                    else if (systemCoordRight >= 499)
                    {
                        systemCoordRight = systemCoordLeft;
                    }

                    SystemCoordinate systemLeft  = new SystemCoordinate(hereSystem.Galaxy, systemCoordLeft);
                    SystemCoordinate systemRight = new SystemCoordinate(hereSystem.Galaxy, systemCoordRight);

                    var duration = here.DurationTo(systemRight.LowerCoordinate, fleetSpeed, speed, OGameClient.Instance.Settings.Speed);

                    if (GetDifference(duration, _oneWayTrip) > AcceptableWindow)
                    {
                        continue;
                    }

                    var targets = db.Planets
                                  .Where(p => (p.LocationId >= systemLeft.LowerCoordinate && p.LocationId <= systemLeft.UpperCoordinate) ||
                                         (p.LocationId >= systemRight.LowerCoordinate && p.LocationId <= systemRight.UpperCoordinate))
                                  .Select(p => p.LocationId)
                                  .AsEnumerable()
                                  .Select(target => new FleetSaveTarget {
                        Target = target, Duration = duration, Speed = speed
                    });

                    best = FilterDebrisAvailable(targets).FirstOrDefault();
                }
            }

            return(best);
        }
        protected override CommandQueueElement RunInternal()
        {
            _oneWayTrip = TimeSpan.FromSeconds((ReturnTime - DateTimeOffset.Now).TotalSeconds / 2);

            using (BotDb db = new BotDb())
                using (Client.EnterPlanetExclusive(this))
                {
                    var resp = Client.IssueRequest(Client.RequestBuilder.GetPage(PageType.Fleet, PlanetId));
                    var info = resp.GetParsedSingle <OgamePageInfo>();

                    FleetComposition fleet = FleetComposition.FromDetected(resp.GetParsed <DetectedShip>());
                    if (!fleet.Ships.ContainsKey(ShipType.Recycler))
                    {
                        Logger.Instance.Log(LogLevel.Error, "Planet does not have a recycler, cannot fleetsave");
                        return(null);
                    }
                    fleet.Resources = resp.GetParsedSingle <PlanetResources>().Resources;

                    PlayerResearch research   = db.Players.Where(p => p.PlayerId == info.PlayerId).Select(p => p.Research).First();
                    int            fleetSpeed = fleet.Speed(research);

                    Coordinate      here      = info.PlanetCoord;
                    FleetSaveTarget candidate = CandidateFromSystem(db, here, fleetSpeed) ?? CandidateFromGalaxy(db, here, fleetSpeed);

                    if (candidate != null)
                    {
                        Logger.Instance.Log(LogLevel.Success, $"Best candidate for fleetsave is {candidate.Target} at speed {candidate.Speed}; one way trip {candidate.Duration}");

                        new SendFleetCommand()
                        {
                            PlanetId    = PlanetId,
                            Destination = Coordinate.Create(candidate.Target, CoordinateType.DebrisField),
                            Speed       = candidate.Speed,
                            Mission     = MissionType.Recycle,
                            Fleet       = fleet
                        }.Run();
                    }
                    else
                    {
                        Logger.Instance.Log(LogLevel.Error, $"Could not find a good candidate for fleetsave");
                    }
                }
            return(null);
        }
        private bool CheckDebris(FleetSaveTarget candidate)
        {
            var resp = Client.IssueRequest(Client.RequestBuilder.GetFleetCheckDebris(candidate.Target));

            return(resp.GetParsedSingle <FleetCheck>().Status == FleetCheckStatus.OK);
        }