private void OnFrame(object sender, EventArgs e) { var watch = new Stopwatch(); // Only pulse state changes every 1.5s if (DateTime.Now.Subtract(_lastPulse).TotalMilliseconds < 1500) { return; } _lastPulse = DateTime.Now; // Session is not ready yet, do not continue if (!Cache.Instance.DirectEve.Session.IsReady) { return; } // If Questor window not visible, show it if (!m_Parent.Visible) { m_Parent.Visible = true; } // We are not in space or station, don't do shit yet! if (!Cache.Instance.InSpace && !Cache.Instance.InStation) { return; } // New frame, invalidate old cache Cache.Instance.InvalidateCache(); // Update settings (settings only load if character name changed) Settings.Instance.LoadSettings(); CharacterName = Cache.Instance.DirectEve.Me.Name; // Check 3D rendering if (Cache.Instance.DirectEve.Session.IsInSpace && Cache.Instance.DirectEve.Rendering3D != !Disable3D) { Cache.Instance.DirectEve.Rendering3D = !Disable3D; } // Invalid settings, quit while we're ahead if (!ValidSettings) { if (DateTime.Now.Subtract(_lastAction).TotalSeconds < 15) { ValidateSettings(); _lastAction = DateTime.Now; } return; } foreach (var window in Cache.Instance.Windows) { // Telecom messages are generally mission info messages if (window.Name == "telecom") { Logging.Log("Questor: Closing telecom message..."); Logging.Log("Questor: Content of telecom window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); window.Close(); } // Modal windows must be closed // But lets only close known modal windows if (window.Name == "modal") { bool close = false; if (!string.IsNullOrEmpty(window.Html)) { // Server going down close |= window.Html.Contains("Please make sure your characters are out of harms way"); // In space "shit" close |= window.Html.Contains("Item cannot be moved back to a loot container."); close |= window.Html.Contains("you do not have the cargo space"); close |= window.Html.Contains("cargo units would be required to complete this operation."); close |= window.Html.Contains("You are too far away from the acceleration gate to activate it!"); close |= window.Html.Contains("maximum distance is 2500 meters"); // Stupid warning, lets see if we can find it close |= window.Html.Contains("Do you wish to proceed with this dangerous action?"); // Yes we know the mission isnt complete, Questor will just redo the mission close |= window.Html.Contains("Please check your mission journal for further information."); // Lag :/ close |= window.Html.Contains("This gate is locked!"); close |= window.Html.Contains("The Zbikoki's Hacker Card"); close |= window.Html.Contains(" units free."); } if (close) { Logging.Log("Questor: Closing modal window..."); Logging.Log("Questor: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); window.Close(); } } } // We always check our defense state if we're in space, regardless of questor state // We also always check panic if (Cache.Instance.InSpace) { watch.Reset(); watch.Start(); if (ExitSta == false) { _defense.ProcessState(); } watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("Defense.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } } // Defense is more important then pause, rest (even panic) isnt! if (Paused) { return; } // Panic always runs, not just in space watch.Reset(); watch.Start(); _panic.InMission = State == QuestorState.ExecuteMission; if (State == QuestorState.Storyline && _storyline.State == StorylineState.ExecuteMission) { _panic.InMission |= _storyline.StorylineHandler is GenericCombatStoryline && (_storyline.StorylineHandler as GenericCombatStoryline).State == GenericCombatStorylineState.ExecuteMission; } _panic.ProcessState(); watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("Panic.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } if (_panic.State == PanicState.Panic || _panic.State == PanicState.Panicking) { // If Panic is in panic state, questor is in panic state :) State = State == QuestorState.Storyline ? QuestorState.StorylinePanic : QuestorState.Panic; if (Settings.Instance.DebugStates) { Logging.Log("State = " + State); } } else if (_panic.State == PanicState.Resume) { // Reset panic state _panic.State = PanicState.Normal; // Ugly storyline resume hack if (State == QuestorState.StorylinePanic) { State = QuestorState.Storyline; if (_storyline.StorylineHandler is GenericCombatStoryline) { (_storyline.StorylineHandler as GenericCombatStoryline).State = GenericCombatStorylineState.GotoMission; } } else { // Head back to the mission _traveler.State = TravelerState.Idle; State = QuestorState.GotoMission; } if (Settings.Instance.DebugStates) { Logging.Log("State = " + State); } } if (Settings.Instance.DebugStates) { Logging.Log("Panic.State = " + _panic.State); } // When in warp there's nothing we can do, so ignore everything if (Cache.Instance.InWarp) { return; } DirectAgentMission mission; switch (State) { case QuestorState.Idle: if (Cache.Instance.StopTimeSpecified) { if (DateTime.Now >= Cache.Instance.StopTime) { Logging.Log("Time to stop. Quitting game."); Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.CmdQuitGame); return; } } if (Cache.Instance.InSpace) { // Questor doesnt handle inspace-starts very well, head back to base to try again Logging.Log("Questor: Started questor while in space, heading back to base in 15 seconds"); _lastAction = DateTime.Now; State = QuestorState.DelayedGotoBase; break; } if (DateTime.Now.Subtract(Program.startTime).Minutes > Program.maxRuntime) { // quit questor Logging.Log("Questor: Maximum runtime exceeded. Quiting..."); Application.Exit(); } mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId); if (!string.IsNullOrEmpty(Mission) && (mission == null || mission.Name != Mission || mission.State != (int)MissionState.Accepted)) { // Do not save statistics if loyalty points == -1 // Seeing as we completed a mission, we will have loyalty points for this agent if (Cache.Instance.Agent.LoyaltyPoints == -1) { return; } // Get the path var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var filename = Path.Combine(path, Cache.Instance.FilterPath(CharacterName) + ".statistics.log"); // Write the header if (!File.Exists(filename)) { File.AppendAllText(filename, "Date;Mission;Time;Isk;Loot;LP;\r\n"); } // Build the line var line = string.Format("{0:dd/MM/yyyy HH:mm:ss}", DateTime.Now) + ";"; line += Mission + ";"; line += ((int)DateTime.Now.Subtract(Started).TotalMinutes) + ";"; line += ((int)(Cache.Instance.DirectEve.Me.Wealth - Wealth)) + ";"; line += ((int)LootValue) + ";"; line += (Cache.Instance.Agent.LoyaltyPoints - LoyaltyPoints) + ";"; line += ((int)LostDrones) + ";"; line += ((int)AmmoConsumption) + ";"; line += ((int)AmmoValue) + ";\r\n"; // The mission is finished File.AppendAllText(filename, line); // Disable next log line Mission = null; } if (AutoStart) { // Dont start missions hour before downtime if (DateTime.UtcNow.Hour == 10) { break; } // Dont start missions in downtime if (DateTime.UtcNow.Hour == 11 && DateTime.UtcNow.Minute < 15) { break; } if (Settings.Instance.RandomDelay > 0 || Settings.Instance.MinimumDelay > 0) { _randomDelay = (Settings.Instance.RandomDelay > 0 ? _random.Next(Settings.Instance.RandomDelay) : 0) + Settings.Instance.MinimumDelay; _lastAction = DateTime.Now; State = QuestorState.DelayedStart; Logging.Log("Questor: Random mission start delay of [" + _randomDelay + "] seconds"); } else { State = QuestorState.Start; } } else if (ExitWhenIdle) { LavishScript.ExecuteCommand("exit"); } break; case QuestorState.DelayedStart: if (DateTime.Now.Subtract(_lastAction).TotalSeconds < _randomDelay) { break; } State = QuestorState.Start; break; case QuestorState.DelayedGotoBase: if (DateTime.Now.Subtract(_lastAction).TotalSeconds < 15) { break; } Logging.Log("Questor: Heading back to base"); State = QuestorState.GotoBase; break; case QuestorState.Start: if (_agentInteraction.State == AgentInteractionState.Idle) { if (Settings.Instance.EnableStorylines && _storyline.HasStoryline()) { Logging.Log("Questor: Storyline detected, doing storyline."); _storyline.Reset(); State = QuestorState.Storyline; break; } Logging.Log("AgentInteraction: Start conversation [Start Mission]"); _agentInteraction.State = AgentInteractionState.StartConversation; _agentInteraction.Purpose = AgentInteractionPurpose.StartMission; // Update statistic values Wealth = Cache.Instance.DirectEve.Me.Wealth; LootValue = 0; LoyaltyPoints = Cache.Instance.Agent.LoyaltyPoints; Started = DateTime.Now; Mission = string.Empty; LostDrones = 0; AmmoConsumption = 0; AmmoValue = 0; } _agentInteraction.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("AgentInteraction.State = " + _agentInteraction.State); } if (_agentInteraction.State == AgentInteractionState.Done) { mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId); if (mission != null) { // Update loyalty points again (the first time might return -1) LoyaltyPoints = Cache.Instance.Agent.LoyaltyPoints; Mission = mission.Name; } _agentInteraction.State = AgentInteractionState.Idle; State = QuestorState.Arm; } break; case QuestorState.Arm: if (_arm.State == ArmState.Idle) { Logging.Log("Arm: Begin"); _arm.State = ArmState.Begin; // Load right ammo based on mission _arm.AmmoToLoad.Clear(); _arm.AmmoToLoad.AddRange(_agentInteraction.AmmoToLoad); } _arm.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("Arm.State = " + _arm.State); } if (_arm.State == ArmState.Done) { _arm.State = ArmState.Idle; State = QuestorState.WarpOutStation; } break; case QuestorState.WarpOutStation: var _bookmark = Cache.Instance.BookmarksByLabel(Settings.Instance.bookmarkWarpOut ?? "").OrderBy(b => b.CreatedOn).FirstOrDefault(); var _solarid = Cache.Instance.DirectEve.Session.SolarSystemId ?? -1; if (_bookmark == null) { Logging.Log("WarpOut: No Bookmark"); State = QuestorState.GotoMission; } else if (_bookmark.LocationId == _solarid) { if (_traveler.Destination == null) { Logging.Log("WarpOut: Warp at " + _bookmark.Title); _traveler.Destination = new BookmarkDestination(_bookmark); ExitSta = true; } _traveler.ProcessState(); if (_traveler.State == TravelerState.AtDestination) { Logging.Log("WarpOut: Safe!"); ExitSta = false; State = QuestorState.GotoMission; _traveler.Destination = null; } } else { Logging.Log("WarpOut: No Bookmark in System"); State = QuestorState.GotoMission; } break; case QuestorState.GotoMission: var missionDestination = _traveler.Destination as MissionBookmarkDestination; if (missionDestination == null || missionDestination.AgentId != Cache.Instance.AgentId) // We assume that this will always work "correctly" (tm) { _traveler.Destination = new MissionBookmarkDestination(Cache.Instance.GetMissionBookmark(Cache.Instance.AgentId, "Encounter")); } if (Cache.Instance.PriorityTargets.Any(pt => pt != null && pt.IsValid)) { Logging.Log("GotoMission: Priority targets found, engaging!"); _combat.ProcessState(); } _traveler.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("Traveler.State = " + _traveler.State); } if (_traveler.State == TravelerState.AtDestination) { State = QuestorState.ExecuteMission; // Seeing as we just warped to the mission, start the mission controller _missionController.State = MissionControllerState.Start; _combat.State = CombatState.CheckTargets; _traveler.Destination = null; } break; case QuestorState.CombatHelper: _combat.ProcessState(); _drones.ProcessState(); _salvage.ProcessState(); break; case QuestorState.ExecuteMission: watch.Reset(); watch.Start(); _combat.ProcessState(); watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("Combat.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } if (Settings.Instance.DebugStates) { Logging.Log("Combat.State = " + _combat.State); } watch.Reset(); watch.Start(); _drones.ProcessState(); watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("Drones.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } if (Settings.Instance.DebugStates) { Logging.Log("Drones.State = " + _drones.State); } watch.Reset(); watch.Start(); _salvage.ProcessState(); watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("Salvage.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } if (Settings.Instance.DebugStates) { Logging.Log("Salvage.State = " + _salvage.State); } watch.Reset(); watch.Start(); _missionController.ProcessState(); watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("MissionController.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } if (Settings.Instance.DebugStates) { Logging.Log("MissionController.State = " + _missionController.State); } // If we are out of ammo, return to base, the mission will fail to complete and the bot will reload the ship // and try the mission again if (_combat.State == CombatState.OutOfAmmo) { Logging.Log("Combat: Out of Ammo!"); State = QuestorState.GotoBase; // Clear looted containers Cache.Instance.LootedContainers.Clear(); } if (_missionController.State == MissionControllerState.Done) { State = QuestorState.GotoBase; // Clear looted containers Cache.Instance.LootedContainers.Clear(); } // If in error state, just go home and stop the bot if (_missionController.State == MissionControllerState.Error) { Logging.Log("MissionController: Error"); State = QuestorState.GotoBase; // Clear looted containers Cache.Instance.LootedContainers.Clear(); } break; case QuestorState.GotoBase: var baseDestination = _traveler.Destination as StationDestination; if (baseDestination == null || baseDestination.StationId != Cache.Instance.Agent.StationId) { _traveler.Destination = new StationDestination(Cache.Instance.Agent.SolarSystemId, Cache.Instance.Agent.StationId, Cache.Instance.DirectEve.GetLocationName(Cache.Instance.Agent.StationId)); } if (Cache.Instance.PriorityTargets.Any(pt => pt != null && pt.IsValid)) { Logging.Log("GotoBase: Priority targets found, engaging!"); _combat.ProcessState(); } _traveler.ProcessState(); if (_traveler.State == TravelerState.AtDestination) { mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId); if (_missionController.State == MissionControllerState.Error) { State = QuestorState.Error; } else if (_combat.State != CombatState.OutOfAmmo && mission != null && mission.State == (int)MissionState.Accepted) { State = QuestorState.CompleteMission; } else { State = QuestorState.UnloadLoot; } _traveler.Destination = null; } if (Settings.Instance.DebugStates) { Logging.Log("Traveler.State = " + _traveler.State); } break; case QuestorState.CompleteMission: if (_agentInteraction.State == AgentInteractionState.Idle) { // Lost drone statistics // (inelegantly located here so as to avoid the necessity to switch to a combat ship after salvaging) if (Settings.Instance.UseDrones) { var droneBay = Cache.Instance.DirectEve.GetShipsDroneBay(); if (droneBay.Window == null) { Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.OpenDroneBayOfActiveShip); break; } if (!droneBay.IsReady) { break; } if (Cache.Instance.InvTypesById.ContainsKey(Settings.Instance.DroneTypeId)) { var drone = Cache.Instance.InvTypesById[Settings.Instance.DroneTypeId]; LostDrones = (int)Math.Floor((droneBay.Capacity - droneBay.UsedCapacity) / drone.Volume); Logging.Log("DroneStats: Logging the number of lost drones: " + LostDrones.ToString()); } else { Logging.Log("DroneStats: Couldn't find the drone TypeID specified in the settings.xml; this shouldn't happen!"); } } // Lost drone statistics stuff ends here // Ammo Consumption statistics // Is cargo open? var cargoship = Cache.Instance.DirectEve.GetShipsCargo(); if (cargoship.Window == null) { // No, command it to open Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.OpenCargoHoldOfActiveShip); break; } if (!cargoship.IsReady) { break; } var correctAmmo1 = Settings.Instance.Ammo.Where(a => a.DamageType == Cache.Instance.DamageType); var AmmoCargo = cargoship.Items.Where(i => correctAmmo1.Any(a => a.TypeId == i.TypeId)); foreach (var item in AmmoCargo) { var Ammo1 = Settings.Instance.Ammo.Where(a => a.TypeId == item.TypeId).FirstOrDefault(); var AmmoType = Cache.Instance.InvTypesById[item.TypeId]; AmmoConsumption = (Ammo1.Quantity - item.Quantity); AmmoValue = (AmmoType.MedianBuy ?? 0) * AmmoConsumption; } Logging.Log("AgentInteraction: Start Conversation [Complete Mission]"); _agentInteraction.State = AgentInteractionState.StartConversation; _agentInteraction.Purpose = AgentInteractionPurpose.CompleteMission; } _agentInteraction.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("AgentInteraction.State = " + _agentInteraction.State); } if (_agentInteraction.State == AgentInteractionState.Done) { _agentInteraction.State = AgentInteractionState.Idle; State = QuestorState.UnloadLoot; } break; case QuestorState.UnloadLoot: if (_unloadLoot.State == UnloadLootState.Idle) { Logging.Log("UnloadLoot: Begin"); _unloadLoot.State = UnloadLootState.Begin; } _unloadLoot.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("UnloadLoot.State = " + _unloadLoot.State); } if (_unloadLoot.State == UnloadLootState.Done) { Logging.Log("UnloadLoot: Done"); _unloadLoot.State = UnloadLootState.Idle; // Update total loot value LootValue += _unloadLoot.LootValue; mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId); if (_combat.State != CombatState.OutOfAmmo && Settings.Instance.AfterMissionSalvaging && Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " ").Count > 0 && (mission == null || mission.State == (int)MissionState.Offered)) { State = QuestorState.BeginAfterMissionSalvaging; } else if (_combat.State == CombatState.OutOfAmmo) { State = QuestorState.Start; } else { State = QuestorState.Idle; } } break; case QuestorState.BeginAfterMissionSalvaging: _GatesPresent = false; if (_arm.State == ArmState.Idle) { _arm.State = ArmState.SwitchToSalvageShip; } _arm.ProcessState(); if (_arm.State == ArmState.Done) { _arm.State = ArmState.Idle; var bookmark = Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " ").OrderBy(b => b.CreatedOn).FirstOrDefault(); if (bookmark == null) { State = QuestorState.Idle; break; } State = QuestorState.GotoSalvageBookmark; _traveler.Destination = new BookmarkDestination(bookmark); } break; case QuestorState.GotoSalvageBookmark: _traveler.ProcessState(); string target = "Acceleration Gate"; var targets = Cache.Instance.EntitiesByName(target); if (_traveler.State == TravelerState.AtDestination || GateInSalvage()) { State = QuestorState.Salvage; _traveler.Destination = null; } if (Settings.Instance.DebugStates) { Logging.Log("Traveler.State = " + _traveler.State); } break; case QuestorState.Salvage: var cargo = Cache.Instance.DirectEve.GetShipsCargo(); // Is our cargo window open? if (cargo.Window == null) { // No, command it to open Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.OpenCargoHoldOfActiveShip); break; } if (Settings.Instance.UnloadLootAtStation && cargo.IsReady && (cargo.Capacity - cargo.UsedCapacity) < 100) { Logging.Log("Salvage: We are full, goto base to unload"); State = QuestorState.GotoBase; break; } if (Cache.Instance.UnlootedContainers.Count() == 0) { Logging.Log("Salvage: Finished salvaging the room"); bool GatesInRoom = GateInSalvage(); var bookmarks = Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " "); do { var bookmark = bookmarks.FirstOrDefault(b => Cache.Instance.DistanceFromMe(b.X ?? 0, b.Y ?? 0, b.Z ?? 0) < 250000); if (!GatesInRoom && _GatesPresent) // if there were gates, but we've gone through them all, delete all bookmarks { bookmark = bookmarks.FirstOrDefault(); } else if (GatesInRoom) { break; } if (bookmark == null) { break; } bookmark.Delete(); bookmarks.Remove(bookmark); } while (true); if (bookmarks.Count == 0 && !GatesInRoom) { Logging.Log("Salvage: We have salvaged all bookmarks, goto base"); State = QuestorState.GotoBase; } else { if (!GatesInRoom) { Logging.Log("Salvage: Goto the next salvage bookmark"); State = QuestorState.GotoSalvageBookmark; _traveler.Destination = new BookmarkDestination(bookmarks.OrderBy(b => b.CreatedOn).First()); } else if (Settings.Instance.UseGatesInSalvage) { Logging.Log("Salvage: Acceleration gate found - moving to next pocket"); State = QuestorState.SalvageUseGate; } else { Logging.Log("Salvage: Acceleration gate found, useGatesInSalvage set to false - Returning to base"); State = QuestorState.GotoBase; _traveler.Destination = null; } } break; } var closestWreck = Cache.Instance.UnlootedContainers.First(); if (closestWreck.Distance > 2500 && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closestWreck.Id)) { if (closestWreck.Distance > 150000) { closestWreck.WarpTo(); } else { closestWreck.Approach(); } } else if (closestWreck.Distance <= 2500 && Cache.Instance.Approaching != null) { Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.CmdStopShip); } try { // Overwrite settings, as the 'normal' settings do not apply _salvage.MaximumWreckTargets = Math.Min(Cache.Instance.DirectEve.ActiveShip.MaxLockedTargets, Cache.Instance.DirectEve.Me.MaxLockedTargets); _salvage.ReserveCargoCapacity = 80; _salvage.LootEverything = true; _salvage.ProcessState(); } finally { ApplySettings(); } break; case QuestorState.SalvageUseGate: target = "Acceleration Gate"; targets = Cache.Instance.EntitiesByName(target); if (targets == null || targets.Count() == 0) { State = QuestorState.GotoSalvageBookmark; return; } _lastX = Cache.Instance.DirectEve.ActiveShip.Entity.X; _lastY = Cache.Instance.DirectEve.ActiveShip.Entity.Y; _lastZ = Cache.Instance.DirectEve.ActiveShip.Entity.Z; var closest = targets.OrderBy(t => t.Distance).First(); if (closest.Distance < 2500) { Logging.Log("Salvage: Acceleration gate found - GroupID=" + closest.GroupId); // Activate it and move to the next Pocket closest.Activate(); // Do not change actions, if NextPocket gets a timeout (>2 mins) then it reverts to the last action Logging.Log("Salvage: Activate [" + closest.Name + "] and change state to 'NextPocket'"); State = QuestorState.SalvageNextPocket; _lastPulse = DateTime.Now; } else if (closest.Distance < 150000) { // Move to the target if (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closest.Id) { Logging.Log("Salvage: Approaching target [" + closest.Name + "][" + closest.Id + "]"); closest.Approach(); } } else { // Probably never happens closest.WarpTo(); } _lastPulse = DateTime.Now.AddSeconds(10); break; case QuestorState.SalvageNextPocket: var distance = Cache.Instance.DistanceFromMe(_lastX, _lastY, _lastZ); if (distance > 100000) { Logging.Log("Salvage: We've moved to the next Pocket [" + distance + "]"); State = QuestorState.Salvage; } else if (DateTime.Now.Subtract(_lastPulse).TotalMinutes > 2) { Logging.Log("Salvage: We've timed out, retry last action"); // We have reached a timeout, revert to ExecutePocketActions (e.g. most likely Activate) State = QuestorState.SalvageUseGate; } break; case QuestorState.Storyline: _storyline.ProcessState(); if (_storyline.State == StorylineState.Done) { Logging.Log("Questor: We have completed the storyline, returning to base"); State = QuestorState.GotoBase; break; } break; case QuestorState.Traveler: var destination = Cache.Instance.DirectEve.Navigation.GetDestinationPath(); if (destination == null || destination.Count == 0) { // should never happen, but still... Logging.Log("Traveler: No destination?"); State = QuestorState.Error; } else if (destination.Count == 1 && destination.First() == 0) { destination[0] = Cache.Instance.DirectEve.Session.SolarSystemId ?? -1; } if (_traveler.Destination == null || _traveler.Destination.SolarSystemId != destination.Last()) { var bookmarks = Cache.Instance.DirectEve.Bookmarks.Where(b => b.LocationId == destination.Last()); if (bookmarks != null && bookmarks.Count() > 0) { _traveler.Destination = new BookmarkDestination(bookmarks.OrderBy(b => b.CreatedOn).First()); } else { Logging.Log("Traveler: Destination: [" + Cache.Instance.DirectEve.Navigation.GetLocation(destination.Last()).Name + "]"); _traveler.Destination = new SolarSystemDestination(destination.Last()); } } else { _traveler.ProcessState(); if (_traveler.State == TravelerState.AtDestination) { if (_missionController.State == MissionControllerState.Error) { Logging.Log("Questor stopped: an error has occured"); State = QuestorState.Error; } else if (Cache.Instance.InSpace) { Logging.Log("Traveler: Arrived at destination (in space, Questor stopped)"); State = QuestorState.Error; } else { Logging.Log("Traveler: Arrived at destination"); State = QuestorState.Idle; } } } break; } }
private void OnFrame(object sender, EventArgs e) { var watch = new Stopwatch(); // Only pulse state changes every 1.5s if (DateTime.Now.Subtract(_lastPulse).TotalMilliseconds < 1500) { return; } _lastPulse = DateTime.Now; // Session is not ready yet, do not continue if (!Cache.Instance.DirectEve.Session.IsReady) { return; } // We are not in space or station, don't do shit yet! if (!Cache.Instance.InSpace && !Cache.Instance.InStation) { return; } // New frame, invalidate old cache Cache.Instance.InvalidateCache(); // Update settings (settings only load if character name changed) Settings.Instance.LoadSettings(); CharacterName = Cache.Instance.DirectEve.Me.Name; // Check 3D rendering if (Cache.Instance.DirectEve.Session.IsInSpace && Cache.Instance.DirectEve.Rendering3D != !Disable3D) { Cache.Instance.DirectEve.Rendering3D = !Disable3D; } // Invalid settings, quit while we're ahead if (!ValidSettings) { if (DateTime.Now.Subtract(_lastAction).TotalSeconds < 15) { ValidateSettings(); _lastAction = DateTime.Now; } return; } foreach (var window in Cache.Instance.Windows) { // Telecom messages are generally mission info messages if (window.Name == "telecom") { Logging.Log("Questor: Closing telecom message..."); Logging.Log("Questor: Content of telecom window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); window.Close(); } // Modal windows must be closed // But lets only close known modal windows if (window.Name == "modal") { bool close = false; if (!string.IsNullOrEmpty(window.Html)) { // Server going down close |= window.Html.Contains("Please make sure your characters are out of harms way"); // In space "shit" close |= window.Html.Contains("Item cannot be moved back to a loot container."); close |= window.Html.Contains("you do not have the cargo space"); close |= window.Html.Contains("cargo units would be required to complete this operation."); close |= window.Html.Contains("You are too far away from the acceleration gate to activate it!"); close |= window.Html.Contains("maximum distance is 2500 meters"); // Stupid warning, lets see if we can find it close |= window.Html.Contains("Do you wish to proceed with this dangerous action?"); // Yes we know the mission isnt complete, Questor will just redo the mission close |= window.Html.Contains("Please check your mission journal for further information."); // Lag :/ close |= window.Html.Contains("The Zbikoki's Hacker Card"); close |= window.Html.Contains(" units free."); } if (close) { Logging.Log("Questor: Closing modal window..."); Logging.Log("Questor: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); window.Close(); } } } // We always check our defense state if we're in space, regardless of questor state // We also always check panic if (Cache.Instance.InSpace) { watch.Reset(); watch.Start(); _defense.ProcessState(); watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("Defense.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } } // Defense is more important then pause, rest (even panic) isnt! if (Paused) { return; } // Panic always runs, not just in space watch.Reset(); watch.Start(); _panic.InMission = State == QuestorState.ExecuteMission; if (State == QuestorState.Storyline && _storyline.State == StorylineState.ExecuteMission) { _panic.InMission |= _storyline.StorylineHandler is GenericCombatStoryline && (_storyline.StorylineHandler as GenericCombatStoryline).State == GenericCombatStorylineState.ExecuteMission; } _panic.ProcessState(); watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("Panic.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } if (_panic.State == PanicState.Panic || _panic.State == PanicState.Panicking) { // If Panic is in panic state, questor is in panic state :) State = State == QuestorState.Storyline ? QuestorState.StorylinePanic : QuestorState.Panic; if (Settings.Instance.DebugStates) { Logging.Log("State = " + State); } } else if (_panic.State == PanicState.Resume) { // Reset panic state _panic.State = PanicState.Normal; // Ugly storyline resume hack if (State == QuestorState.StorylinePanic) { State = QuestorState.Storyline; if (_storyline.StorylineHandler is GenericCombatStoryline) { (_storyline.StorylineHandler as GenericCombatStoryline).State = GenericCombatStorylineState.GotoMission; } } else { // Head back to the mission _traveler.State = TravelerState.Idle; State = QuestorState.GotoMission; } if (Settings.Instance.DebugStates) { Logging.Log("State = " + State); } } if (Settings.Instance.DebugStates) { Logging.Log("Panic.State = " + _panic.State); } // When in warp there's nothing we can do, so ignore everything if (Cache.Instance.InWarp) { return; } DirectAgentMission mission; switch (State) { case QuestorState.Idle: if (Cache.Instance.InSpace) { // Questor doesnt handle inspace-starts very well, head back to base to try again Logging.Log("Questor: Started questor while in space, heading back to base in 15 seconds"); _lastAction = DateTime.Now; State = QuestorState.DelayedGotoBase; break; } mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId); if (!string.IsNullOrEmpty(Mission) && (mission == null || mission.Name != Mission || mission.State != (int)MissionState.Accepted)) { // Do not save statistics if loyalty points == -1 // Seeing as we completed a mission, we will have loyalty points for this agent if (Cache.Instance.Agent.LoyaltyPoints == -1) { return; } // Get the path var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var filename = Path.Combine(path, Cache.Instance.FilterPath(CharacterName) + ".statistics.log"); // Write the header if (!File.Exists(filename)) { File.AppendAllText(filename, "Mission;Time;Isk;Loot;LP;\r\n"); } // Build the line var line = Mission + ";"; line += ((int)DateTime.Now.Subtract(Started).TotalMinutes) + ";"; line += ((int)(Cache.Instance.DirectEve.Me.Wealth - Wealth)) + ";"; line += ((int)LootValue) + ";"; line += (Cache.Instance.Agent.LoyaltyPoints - LoyaltyPoints) + ";\r\n"; // The mission is finished File.AppendAllText(filename, line); // Disable next log line Mission = null; } if (AutoStart) { // Dont start missions hour before downtime if (DateTime.UtcNow.Hour == 10) { break; } // Dont start missions in downtime if (DateTime.UtcNow.Hour == 11 && DateTime.UtcNow.Minute < 15) { break; } if (Settings.Instance.RandomDelay > 0 || Settings.Instance.MinimumDelay > 0) { _randomDelay = (Settings.Instance.RandomDelay > 0 ? _random.Next(Settings.Instance.RandomDelay) : 0) + Settings.Instance.MinimumDelay; _lastAction = DateTime.Now; State = QuestorState.DelayedStart; Logging.Log("Questor: Random mission start delay of [" + _randomDelay + "] seconds"); } else { State = QuestorState.Start; } } else if (ExitWhenIdle) { LavishScript.ExecuteCommand("exit"); } break; case QuestorState.DelayedStart: if (DateTime.Now.Subtract(_lastAction).TotalSeconds < _randomDelay) { break; } State = QuestorState.Start; break; case QuestorState.DelayedGotoBase: if (DateTime.Now.Subtract(_lastAction).TotalSeconds < 15) { break; } Logging.Log("Questor: Heading back to base"); State = QuestorState.GotoBase; break; case QuestorState.Start: if (_agentInteraction.State == AgentInteractionState.Idle) { if (Settings.Instance.EnableStorylines && _storyline.HasStoryline()) { Logging.Log("Questor: Storyline detected, doing storyline."); _storyline.Reset(); State = QuestorState.Storyline; break; } Logging.Log("AgentInteraction: Start conversation [Start Mission]"); _agentInteraction.State = AgentInteractionState.StartConversation; _agentInteraction.Purpose = AgentInteractionPurpose.StartMission; // Update statistic values Wealth = Cache.Instance.DirectEve.Me.Wealth; LootValue = 0; LoyaltyPoints = Cache.Instance.Agent.LoyaltyPoints; Started = DateTime.Now; Mission = string.Empty; } _agentInteraction.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("AgentInteraction.State = " + _agentInteraction.State); } if (_agentInteraction.State == AgentInteractionState.Done) { mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId); if (mission != null) { // Update loyalty points again (the first time might return -1) LoyaltyPoints = Cache.Instance.Agent.LoyaltyPoints; Mission = mission.Name; } _agentInteraction.State = AgentInteractionState.Idle; State = QuestorState.Arm; } break; case QuestorState.Arm: if (_arm.State == ArmState.Idle) { Logging.Log("Arm: Begin"); _arm.State = ArmState.Begin; // Load right ammo based on mission _arm.AmmoToLoad.Clear(); _arm.AmmoToLoad.AddRange(_agentInteraction.AmmoToLoad); } _arm.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("Arm.State = " + _arm.State); } if (_arm.State == ArmState.Done) { _arm.State = ArmState.Idle; State = QuestorState.GotoMission; } break; case QuestorState.GotoMission: var missionDestination = _traveler.Destination as MissionBookmarkDestination; if (missionDestination == null || missionDestination.AgentId != Cache.Instance.AgentId) // We assume that this will always work "correctly" (tm) { _traveler.Destination = new MissionBookmarkDestination(Cache.Instance.GetMissionBookmark(Cache.Instance.AgentId, "Encounter")); } if (Cache.Instance.PriorityTargets.Any(pt => pt != null && pt.IsValid)) { Logging.Log("GotoMission: Priority targets found, engaging!"); _combat.ProcessState(); } _traveler.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("Traveler.State = " + _traveler.State); } if (_traveler.State == TravelerState.AtDestination) { State = QuestorState.ExecuteMission; // Seeing as we just warped to the mission, start the mission controller _missionController.State = MissionControllerState.Start; _combat.State = CombatState.CheckTargets; _traveler.Destination = null; } break; case QuestorState.CombatHelper: _combat.ProcessState(); _drones.ProcessState(); _salvage.ProcessState(); break; case QuestorState.ExecuteMission: watch.Reset(); watch.Start(); _combat.ProcessState(); watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("Combat.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } if (Settings.Instance.DebugStates) { Logging.Log("Combat.State = " + _combat.State); } watch.Reset(); watch.Start(); _drones.ProcessState(); watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("Drones.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } if (Settings.Instance.DebugStates) { Logging.Log("Drones.State = " + _drones.State); } watch.Reset(); watch.Start(); _salvage.ProcessState(); watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("Salvage.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } if (Settings.Instance.DebugStates) { Logging.Log("Salvage.State = " + _salvage.State); } watch.Reset(); watch.Start(); _missionController.ProcessState(); watch.Stop(); if (Settings.Instance.DebugPerformance) { Logging.Log("MissionController.ProcessState took " + watch.ElapsedMilliseconds + "ms"); } if (Settings.Instance.DebugStates) { Logging.Log("MissionController.State = " + _missionController.State); } // If we are out of ammo, return to base, the mission will fail to complete and the bot will reload the ship // and try the mission again if (_combat.State == CombatState.OutOfAmmo) { Logging.Log("Combat: Out of Ammo!"); State = QuestorState.GotoBase; // Clear looted containers Cache.Instance.LootedContainers.Clear(); } if (_missionController.State == MissionControllerState.Done) { State = QuestorState.GotoBase; // Clear looted containers Cache.Instance.LootedContainers.Clear(); } // If in error state, just go home and stop the bot if (_missionController.State == MissionControllerState.Error) { Logging.Log("MissionController: Error"); State = QuestorState.GotoBase; // Clear looted containers Cache.Instance.LootedContainers.Clear(); } break; case QuestorState.GotoBase: var baseDestination = _traveler.Destination as StationDestination; if (baseDestination == null || baseDestination.StationId != Cache.Instance.Agent.StationId) { _traveler.Destination = new StationDestination(Cache.Instance.Agent.SolarSystemId, Cache.Instance.Agent.StationId, Cache.Instance.DirectEve.GetLocationName(Cache.Instance.Agent.StationId)); } if (Cache.Instance.PriorityTargets.Any(pt => pt != null && pt.IsValid)) { Logging.Log("GotoBase: Priority targets found, engaging!"); _combat.ProcessState(); } _traveler.ProcessState(); if (_traveler.State == TravelerState.AtDestination) { mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId); if (_missionController.State == MissionControllerState.Error) { State = QuestorState.Error; } else if (_combat.State != CombatState.OutOfAmmo && mission != null && mission.State == (int)MissionState.Accepted) { State = QuestorState.CompleteMission; } else { State = QuestorState.UnloadLoot; } _traveler.Destination = null; } if (Settings.Instance.DebugStates) { Logging.Log("Traveler.State = " + _traveler.State); } break; case QuestorState.CompleteMission: if (_agentInteraction.State == AgentInteractionState.Idle) { Logging.Log("AgentInteraction: Start Conversation [Complete Mission]"); _agentInteraction.State = AgentInteractionState.StartConversation; _agentInteraction.Purpose = AgentInteractionPurpose.CompleteMission; } _agentInteraction.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("AgentInteraction.State = " + _agentInteraction.State); } if (_agentInteraction.State == AgentInteractionState.Done) { _agentInteraction.State = AgentInteractionState.Idle; State = QuestorState.UnloadLoot; } break; case QuestorState.UnloadLoot: if (_unloadLoot.State == UnloadLootState.Idle) { Logging.Log("UnloadLoot: Begin"); _unloadLoot.State = UnloadLootState.Begin; } _unloadLoot.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("UnloadLoot.State = " + _unloadLoot.State); } if (_unloadLoot.State == UnloadLootState.Done) { Logging.Log("UnloadLoot: Done"); _unloadLoot.State = UnloadLootState.Idle; // Update total loot value LootValue += _unloadLoot.LootValue; mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId); if (_combat.State != CombatState.OutOfAmmo && Settings.Instance.AfterMissionSalvaging && Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " ").Count > 0 && (mission == null || mission.State == (int)MissionState.Offered)) { State = QuestorState.BeginAfterMissionSalvaging; } else if (_combat.State == CombatState.OutOfAmmo) { State = QuestorState.Start; } else { State = QuestorState.Idle; } } break; case QuestorState.BeginAfterMissionSalvaging: if (_arm.State == ArmState.Idle) { _arm.State = ArmState.SwitchToSalvageShip; } _arm.ProcessState(); if (_arm.State == ArmState.Done) { _arm.State = ArmState.Idle; var bookmark = Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " ").OrderBy(b => b.CreatedOn).FirstOrDefault(); if (bookmark == null) { State = QuestorState.Idle; break; } State = QuestorState.GotoSalvageBookmark; _traveler.Destination = new BookmarkDestination(bookmark); } break; case QuestorState.GotoSalvageBookmark: _traveler.ProcessState(); if (_traveler.State == TravelerState.AtDestination) { State = QuestorState.Salvage; _traveler.Destination = null; } if (Settings.Instance.DebugStates) { Logging.Log("Traveler.State = " + _traveler.State); } break; case QuestorState.Salvage: var cargo = Cache.Instance.DirectEve.GetShipsCargo(); // Is our cargo window open? if (cargo.Window == null) { // No, command it to open Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.OpenCargoHoldOfActiveShip); break; } if (Settings.Instance.UnloadLootAtStation && cargo.IsReady && (cargo.Capacity - cargo.UsedCapacity) < 100) { Logging.Log("Salvage: We are full, goto base to unload"); State = QuestorState.GotoBase; break; } if (Cache.Instance.UnlootedContainers.Count() == 0) { Logging.Log("Salvage: Finished salvaging the room"); var bookmarks = Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " "); do { // Remove all bookmarks from address book var bookmark = bookmarks.FirstOrDefault(b => Cache.Instance.DistanceFromMe(b.X ?? 0, b.Y ?? 0, b.Z ?? 0) < 250000); if (bookmark == null) { break; } bookmark.Delete(); bookmarks.Remove(bookmark); } while (true); if (bookmarks.Count == 0) { Logging.Log("Salvage: We have salvaged all bookmarks, goto base"); State = QuestorState.GotoBase; } else { Logging.Log("Salvage: Goto the next salvage bookmark"); _traveler.Destination = new BookmarkDestination(bookmarks.OrderBy(b => b.CreatedOn).First()); State = QuestorState.GotoSalvageBookmark; } break; } var closestWreck = Cache.Instance.UnlootedContainers.First(); if (closestWreck.Distance > 2500 && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closestWreck.Id)) { if (closestWreck.Distance > 150000) { closestWreck.WarpTo(); } else { closestWreck.Approach(); } } else if (closestWreck.Distance <= 2500 && Cache.Instance.Approaching != null) { Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.CmdStopShip); } try { // Overwrite settings, as the 'normal' settings do not apply _salvage.MaximumWreckTargets = Math.Min(Cache.Instance.DirectEve.ActiveShip.MaxLockedTargets, Cache.Instance.DirectEve.Me.MaxLockedTargets); _salvage.ReserveCargoCapacity = 80; _salvage.LootEverything = true; _salvage.ProcessState(); } finally { ApplySettings(); } break; case QuestorState.Storyline: _storyline.ProcessState(); if (_storyline.State == StorylineState.Done) { Logging.Log("Questor: We have completed the storyline, returning to base"); State = QuestorState.GotoBase; break; } break; } }
public void ProcessState() { // Invalid settings, quit while we're ahead if (!ValidSettings) { if (DateTime.UtcNow.Subtract(LastAction).TotalSeconds < Time.Instance.ValidateSettings_seconds) //default is a 15 second interval { ValidateDedicatedSalvageSettings(); LastAction = DateTime.UtcNow; } return; } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //this local is safe check is useless as their is no LocalWatch processstate running every tick... //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //If local unsafe go to base and do not start mission again if (Settings.Instance.FinishWhenNotSafe && (_States.CurrentDedicatedBookmarkSalvagerBehaviorState != DedicatedBookmarkSalvagerBehaviorState.GotoNearestStation /*|| State!=QuestorState.GotoBase*/)) { //need to remove spam if (Cache.Instance.InSpace && !Cache.Instance.LocalSafe(Settings.Instance.LocalBadStandingPilotsToTolerate, Settings.Instance.LocalBadStandingLevelToConsiderBad)) { EntityCache station = null; if (Cache.Instance.Stations != null && Cache.Instance.Stations.Any()) { station = Cache.Instance.Stations.OrderBy(x => x.Distance).FirstOrDefault(); } if (station != null) { Logging.Log("Local not safe", "Station found. Going to nearest station", Logging.White); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.GotoNearestStation; } else { Logging.Log("Local not safe", "Station not found. Going back to base", Logging.White); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.GotoBase; } Cache.Instance.StopBot = true; } } if (Cache.Instance.SessionState == "Quitting") { BeginClosingQuestor(); } if (Cache.Instance.GotoBaseNow) { _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.GotoBase; } if ((DateTime.UtcNow.Subtract(Cache.Instance.QuestorStarted_DateTime).TotalSeconds > 10) && (DateTime.UtcNow.Subtract(Cache.Instance.QuestorStarted_DateTime).TotalSeconds < 60)) { if (Cache.Instance.QuestorJustStarted) { Cache.Instance.QuestorJustStarted = false; Cache.Instance.SessionState = "Starting Up"; // write session log Statistics.WriteSessionLogStarting(); } } // // Panic always runs, not just in space // DebugPerformanceClearandStartTimer(); _panic.ProcessState(); DebugPerformanceStopandDisplayTimer("Panic.ProcessState"); if (_States.CurrentPanicState == PanicState.Panic || _States.CurrentPanicState == PanicState.Panicking) { DebugDedicatedBookmarkSalvagerBehaviorStates(); if (PanicStateReset) { _States.CurrentPanicState = PanicState.Normal; PanicStateReset = false; } } else if (_States.CurrentPanicState == PanicState.Resume) { // Reset panic state _States.CurrentPanicState = PanicState.Normal; } DebugPanicstates(); switch (_States.CurrentDedicatedBookmarkSalvagerBehaviorState) { case DedicatedBookmarkSalvagerBehaviorState.Idle: if (Cache.Instance.StopBot) { return; } _States.CurrentAgentInteractionState = AgentInteractionState.Idle; _States.CurrentArmState = ArmState.Idle; _States.CurrentDroneState = DroneState.Idle; _States.CurrentSalvageState = SalvageState.Idle; _States.CurrentStorylineState = StorylineState.Idle; _States.CurrentTravelerState = TravelerState.Idle; _States.CurrentUnloadLootState = UnloadLootState.Idle; _States.CurrentTravelerState = TravelerState.AtDestination; if (Cache.Instance.InSpace) { // Questor does not handle in space starts very well, head back to base to try again Logging.Log("DedicatedBookmarkSalvagerBehavior", "Started questor while in space, heading back to base in 15 seconds", Logging.White); LastAction = DateTime.UtcNow; Cache.Instance.NextSalvageTrip = DateTime.UtcNow; _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.CheckBookmarkAge; break; } // only attempt to write the mission statistics logs if one of the mission stats logs is enabled in settings //if (Settings.Instance.SalvageStats1Log) //{ // if (!Statistics.Instance.SalvageLoggingCompleted) // { // Statistics.WriteSalvagerStatistics(); // break; // } //} if (Settings.Instance.AutoStart) { //we know we are connected here Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; // Don't start a new action an hour before downtime if (DateTime.UtcNow.Hour == 10) { if (Settings.Instance.DebugAutoStart) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "Autostart: if (DateTime.UtcNow.Hour == 10)", Logging.White); } break; } // Don't start a new action near downtime if (DateTime.UtcNow.Hour == 11 && DateTime.UtcNow.Minute < 15) { if (Settings.Instance.DebugAutoStart) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "if (DateTime.UtcNow.Hour == 11 && DateTime.UtcNow.Minute < 15)", Logging.White); } break; } //Logging.Log("DedicatedBookmarkSalvagerBehavior::: _nextBookmarksrefresh.subtract(DateTime.UtcNow).totalminutes [" + // Math.Round(DateTime.UtcNow.Subtract(_nextBookmarkRefreshCheck).TotalMinutes,0) + "]"); //Logging.Log("DedicatedBookmarkSalvagerBehavior::: Next Salvage Trip Scheduled in [" + // _Cache.Instance.NextSalvageTrip.ToString(CultureInfo.InvariantCulture) + "min]"); if (DateTime.UtcNow > _nextBookmarkRefreshCheck) { _nextBookmarkRefreshCheck = DateTime.UtcNow.AddMinutes(1); if (Cache.Instance.InStation && (DateTime.UtcNow > _nextBookmarksrefresh)) { _nextBookmarksrefresh = DateTime.UtcNow.AddMinutes(Cache.Instance.RandomNumber(18, 24)); Logging.Log("DedicatedBookmarkSalvagerBehavior", "Next Bookmark refresh in [" + Math.Round(_nextBookmarksrefresh.Subtract(DateTime.UtcNow).TotalMinutes, 0) + "min]", Logging.White); Cache.Instance.DirectEve.RefreshBookmarks(); } else { Logging.Log("DedicatedBookmarkSalvagerBehavior", "Next Bookmark refresh in [" + Math.Round(_nextBookmarksrefresh.Subtract(DateTime.UtcNow).TotalMinutes, 0) + "min]", Logging.White); Logging.Log("DedicatedBookmarkSalvagerBehavior", "Next Salvage Trip Scheduled in [" + Math.Round(Cache.Instance.NextSalvageTrip.Subtract(DateTime.UtcNow).TotalMinutes, 0) + "min]", Logging.White); } } if (DateTime.UtcNow > Cache.Instance.NextSalvageTrip) { Logging.Log("DedicatedBookmarkSalvagerBehavior.BeginAftermissionSalvaging", "Starting Another Salvage Trip", Logging.White); LastAction = DateTime.UtcNow; _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.Start; return; } } else { Cache.Instance.LastScheduleCheck = DateTime.UtcNow; Questor.TimeCheck(); //Should we close questor due to stoptime or runtime? } break; case DedicatedBookmarkSalvagerBehaviorState.DelayedGotoBase: if (DateTime.UtcNow.Subtract(LastAction).TotalSeconds < Time.Instance.DelayedGotoBase_seconds) { break; } Logging.Log("DedicatedBookmarkSalvagerBehavior", "Heading back to base", Logging.White); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.GotoBase; break; case DedicatedBookmarkSalvagerBehaviorState.Start: Cache.Instance.OpenWrecks = true; ValidateDedicatedSalvageSettings(); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.UnloadLoot; break; case DedicatedBookmarkSalvagerBehaviorState.LocalWatch: if (Settings.Instance.UseLocalWatch) { Cache.Instance.LastLocalWatchAction = DateTime.UtcNow; if (Cache.Instance.LocalSafe(Settings.Instance.LocalBadStandingPilotsToTolerate, Settings.Instance.LocalBadStandingLevelToConsiderBad)) { Logging.Log("DedicatedBookmarkSalvagerBehavior.LocalWatch", "local is clear", Logging.White); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.BeginAfterMissionSalvaging; } else { Logging.Log("DedicatedBookmarkSalvagerBehavior.LocalWatch", "Bad standings pilots in local: We will stay 5 minutes in the station and then we will check if it is clear again", Logging.White); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.WaitingforBadGuytoGoAway; Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; } } else { _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.BeginAfterMissionSalvaging; } break; case DedicatedBookmarkSalvagerBehaviorState.WaitingforBadGuytoGoAway: Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; if (DateTime.UtcNow.Subtract(Cache.Instance.LastLocalWatchAction).TotalMinutes < Time.Instance.WaitforBadGuytoGoAway_minutes) { //TODO: add debug logging here break; } _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.LocalWatch; break; case DedicatedBookmarkSalvagerBehaviorState.GotoBase: Cache.Instance.CurrentlyShouldBeSalvaging = false; if (Settings.Instance.DebugGotobase) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "GotoBase: AvoidBumpingThings()", Logging.White); } NavigateOnGrid.AvoidBumpingThings(Cache.Instance.BigObjects.FirstOrDefault(), "DedicatedBookmarkSalvagerBehaviorState.GotoBase"); if (Settings.Instance.DebugGotobase) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "GotoBase: Traveler.TravelHome()", Logging.White); } Traveler.TravelHome("DedicatedBookmarkSalvagerBehavior"); if (_States.CurrentTravelerState == TravelerState.AtDestination) // || DateTime.UtcNow.Subtract(Cache.Instance.EnteredCloseQuestor_DateTime).TotalMinutes > 10) { if (Settings.Instance.DebugGotobase) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "GotoBase: We are at destination", Logging.White); } Cache.Instance.GotoBaseNow = false; //we are there - turn off the 'forced' gotobase Cache.Instance.Mission = Cache.Instance.GetAgentMission(AgentID, false); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.UnloadLoot; Traveler.Destination = null; } break; case DedicatedBookmarkSalvagerBehaviorState.UnloadLoot: if (_States.CurrentUnloadLootState == UnloadLootState.Idle) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "UnloadLoot: Begin", Logging.White); _States.CurrentUnloadLootState = UnloadLootState.Begin; } _unloadLoot.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "UnloadLoot.State = " + _States.CurrentUnloadLootState, Logging.White); } if (_States.CurrentUnloadLootState == UnloadLootState.Done) { Cache.Instance.LootAlreadyUnloaded = true; _States.CurrentUnloadLootState = UnloadLootState.Idle; _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.CheckBookmarkAge; } break; case DedicatedBookmarkSalvagerBehaviorState.CheckBookmarkAge: if (DateTime.UtcNow >= Cache.Instance.NextSalvageTrip || Cache.Instance.InSpace) { if (Cache.Instance.GetSalvagingBookmark == null) { BookmarksThatAreNotReadyYet = Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " "); if (BookmarksThatAreNotReadyYet != null && BookmarksThatAreNotReadyYet.Any()) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "CheckBookmarkAge: There are [" + BookmarksThatAreNotReadyYet.Count() + "] Salvage Bookmarks that have not yet aged [" + Settings.Instance.AgeofBookmarksForSalvageBehavior + "] min.", Logging.White); } Logging.Log("DedicatedBookmarkSalvagerBehavior", "CheckBookmarkAge: Character mode is BookmarkSalvager and no bookmarks are ready to salvage.", Logging.White); //We just need a NextSalvagerSession timestamp to key off of here to add the delay if (Cache.Instance.InSpace) { // Questor does not handle in space starts very well, head back to base to try again LastAction = DateTime.UtcNow; Cache.Instance.NextSalvageTrip = DateTime.UtcNow.AddMinutes(Time.Instance.DelayBetweenSalvagingSessions_minutes); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.GotoBase; break; } _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.Idle; _States.CurrentQuestorState = QuestorState.Idle; Cache.Instance.NextSalvageTrip = DateTime.UtcNow.AddMinutes(Time.Instance.DelayBetweenSalvagingSessions_minutes); break; } Logging.Log("DedicatedBookmarkSalvagerBehavior", "CheckBookmarkAge: There are [ " + Cache.Instance.AfterMissionSalvageBookmarks.Count() + " ] more salvage bookmarks older then:" + Cache.Instance.AgedDate.ToString(CultureInfo.InvariantCulture) + ", left to process", Logging.White); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.BeginAfterMissionSalvaging; Statistics.Instance.StartedSalvaging = DateTime.UtcNow; } else { Logging.Log("DedicatedBookmarkSalvagerBehavior", "CheckBookmarkAge: next salvage timer not expired. Waiting...", Logging.White); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.Idle; _States.CurrentQuestorState = QuestorState.Idle; return; } break; case DedicatedBookmarkSalvagerBehaviorState.BeginAfterMissionSalvaging: if (DateTime.UtcNow > Statistics.Instance.StartedSalvaging.AddMinutes(2)) { Logging.Log("DedicatedBookmarkSalvagebehavior", "Found [" + Cache.Instance.AfterMissionSalvageBookmarks.Count() + "] salvage bookmarks ready to process.", Logging.White); Statistics.Instance.StartedSalvaging = DateTime.UtcNow; //this will be reset for each "run" between the station and the field if using <unloadLootAtStation>true</unloadLootAtStation> Cache.Instance.NextSalvageTrip = DateTime.UtcNow.AddMinutes(Time.Instance.DelayBetweenSalvagingSessions_minutes); } //we know we are connected here Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; Cache.Instance.OpenWrecks = true; if (Cache.Instance.InStation) { if (_States.CurrentArmState == ArmState.Idle) { _States.CurrentArmState = ArmState.SwitchToSalvageShip; } Arm.ProcessState(); } if (_States.CurrentArmState == ArmState.Done || Cache.Instance.InSpace) { _States.CurrentArmState = ArmState.Idle; if (_afterMissionSalvageBookmarks == null || Cache.Instance.InStation) { _afterMissionSalvageBookmarks = Cache.Instance.AfterMissionSalvageBookmarks.OrderBy(b => b.CreatedOn).ToList(); } _afterMissionSalvageBookmarks = _afterMissionSalvageBookmarks.OrderBy(b => b.CreatedOn).ToList(); if (DateTime.UtcNow < Cache.Instance.LastAccelerationGateDetected.AddSeconds(10)) //long enough that the timer should expire if we have to warp even small distances to the next bm { _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.GotoBase; Cache.Instance.NextSalvageTrip = DateTime.UtcNow.AddMinutes(Time.Instance.DelayBetweenSalvagingSessions_minutes); return; //Logging.Log("DedicatedBookmarkSalvagerBehavior.Salvager", "There is a gate on grid with us: deferring processing any bookmarks within CloseRangeScan because those are likely behind this gate and might have NPCs still there", Logging.White); //_afterMissionSalvageBookmarks = new List<DirectBookmark>(_afterMissionSalvageBookmarks.Where(b => Cache.Instance.DistanceFromMe(b.X ?? 0, b.Y ?? 0, b.Z ?? 0) > (int)Distance.DirectionalScannerCloseRange)).OrderBy(b => b.CreatedOn).ToList(); //int i = 1; //Logging.Log("DedicatedBookmarkSalvagerBehavior.Salvager", "Listing bookmarks in: _afterMissionSalvageBookmarks, they should be all more than CloseRangeScan [" + Distance.DirectionalScannerCloseRange + "] away.", Logging.Red); //foreach (var bm in _afterMissionSalvageBookmarks) //{ // Logging.Log("", "[" + i + "] BM Name: [" + bm.Title + "]" + "] Distance: [" + Cache.Instance.DistanceFromMe(bm.X ?? 0, bm.Y ?? 0, bm.Z ?? 0) + "]", Logging.Red); // i++; //} //if (_afterMissionSalvageBookmarks.Any()) //{ // Logging.Log("DedicatedBookmarkSalvagerBehavior.Salvager", "_afterMissionSalvageBookmarks contains [" + _afterMissionSalvageBookmarks.Count() + "] bookmarks", Logging.White); //} //else //{ // Logging.Log("DedicatedBookmarkSalvagerBehavior.Salvager", "_afterMissionSalvageBookmarks contains [ Zero ] bookmarks", Logging.White); // Logging.Log("DedicatedBookmarkSalvagerBehavior.Salvager", "AfterMissionSalvageBookmarks (including BMs we cant process yet) contains [" + Cache.Instance.AfterMissionSalvageBookmarks + "]", Logging.White); //} } DirectBookmark bookmark = _afterMissionSalvageBookmarks.OrderBy(b => b.CreatedOn).FirstOrDefault(); if (bookmark == null) { _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.GotoBase; Cache.Instance.NextSalvageTrip = DateTime.UtcNow.AddMinutes(Time.Instance.DelayBetweenSalvagingSessions_minutes); return; } Logging.Log("DedicatedBookmarkSalvagerBehavior.Salvager", "Salvaging at first oldest bookmarks created on: " + bookmark.CreatedOn.ToString(), Logging.White); List <DirectBookmark> bookmarksInLocal = new List <DirectBookmark>(_afterMissionSalvageBookmarks.Where(b => b.LocationId == Cache.Instance.DirectEve.Session.SolarSystemId). OrderBy(b => b.CreatedOn)); DirectBookmark localBookmark = bookmarksInLocal.FirstOrDefault(); if (localBookmark != null) { Traveler.Destination = new BookmarkDestination(localBookmark); } else { Traveler.Destination = new BookmarkDestination(bookmark); } _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.GotoSalvageBookmark; //we know we are connected here Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.LastInWarp = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; return; } break; case DedicatedBookmarkSalvagerBehaviorState.GotoSalvageBookmark: Traveler.ProcessState(); if (Cache.Instance.GateInGrid()) { //Logging.Log("DedicatedBookmarkSalvagerBehavior", "GotoSalvageBookmark: We found gate in salvage bookmark. Going back to Base", Logging.White); Logging.Log("DedicatedBookmarkSalvagerBehavior", "GotoSalvageBookmark: We found gate in salvage bookmark. Skipping this bookmark.", Logging.White); Cache.Instance.LastAccelerationGateDetected = DateTime.UtcNow; //we know we are connected here Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.BeginAfterMissionSalvaging; Traveler.Destination = null; Cache.Instance.NextSalvageTrip = DateTime.UtcNow.AddMinutes(Time.Instance.DelayBetweenSalvagingSessions_minutes); return; } if (_States.CurrentTravelerState == TravelerState.AtDestination) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "GotoSalvageBookmark: Gate not found, we can start salvaging", Logging.White); //we know we are connected here Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; Cache.Instance.LastInWarp = DateTime.UtcNow; _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.Salvage; Traveler.Destination = null; return; } if (Settings.Instance.DebugStates) { Logging.Log("Traveler.State is ", _States.CurrentTravelerState.ToString(), Logging.White); } break; case DedicatedBookmarkSalvagerBehaviorState.Salvage: if (Settings.Instance.DebugSalvage) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "salvage::: attempting to open cargo hold", Logging.White); } if (Cache.Instance.CurrentShipsCargo == null) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "salvage:: if (Cache.Instance.CurrentShipsCargo == null)", Logging.Teal); return; } if (Settings.Instance.DebugSalvage) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "salvage::: done opening cargo hold", Logging.White); } Cache.Instance.SalvageAll = true; Cache.Instance.OpenWrecks = true; Cache.Instance.CurrentlyShouldBeSalvaging = true; const int distanceToCheck = (int)Distances.OnGridWithMe; // is there any NPCs within distanceToCheck? EntityCache deadlyNPC = Cache.Instance.EntitiesOnGrid.Where(t => t.Distance < distanceToCheck && !t.IsEntityIShouldLeaveAlone && !t.IsContainer && t.IsNpc && t.CategoryId == (int)CategoryID.Entity && !t.IsLargeCollidable).OrderBy(t => t.Distance).FirstOrDefault(); if (deadlyNPC != null) { Logging.Log("DedicatedBookmarkSalvagerBehavior.Salvage", "Npc name:[" + deadlyNPC.Name + "] with groupId:[" + deadlyNPC.GroupId + "].", Logging.White); // found NPCs that will likely kill out fragile salvage boat! DirectBookmark bookmark = Cache.Instance.AfterMissionSalvageBookmarks.OrderBy(b => b.CreatedOn).FirstOrDefault(); if (bookmark != null) { Cache.Instance.DeleteBookmarksOnGrid("DedicatedBookmarkSalvageBehavior"); return; } Statistics.Instance.FinishedSalvaging = DateTime.UtcNow; Cache.Instance.NextSalvageTrip = DateTime.UtcNow; _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.GotoBase; return; } if (Cache.Instance.CurrentShipsCargo.IsValid && (Cache.Instance.CurrentShipsCargo.Capacity - Cache.Instance.CurrentShipsCargo.UsedCapacity) < Settings.Instance.ReserveCargoCapacity + 10) { Logging.Log("DedicatedBookmarkSalvageBehavior.Salvage", "We are full, go to base to unload", Logging.White); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.GotoBase; break; } else if (Cache.Instance.CurrentShipsCargo.IsValid) { if (Settings.Instance.DebugSalvage) { Logging.Log("DedicatedSalvager", "CurrentCapacity [" + Cache.Instance.CurrentShipsCargo.Capacity + "] UsedCapacity [" + Cache.Instance.CurrentShipsCargo.UsedCapacity + "][" + Settings.Instance.ReserveCargoCapacity + "]", Logging.Debug); } } if (!Cache.Instance.UnlootedContainers.Any()) { if (!Cache.Instance.DeleteBookmarksOnGrid("DedicatedBookmarkSalvageBehavior")) { return; } // this can eventually be moved to somewhere else like unloadloot BUT... // that will mean keeping track of bookmarks we delete and such in this local list. _afterMissionSalvageBookmarks = Cache.Instance.AfterMissionSalvageBookmarks.OrderBy(b => b.CreatedOn).ToList(); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.CheckBookmarkAge; return; } if (DateTime.UtcNow > Cache.Instance.LastInWarp.AddMinutes(20)) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "It has been over 20 min since we were last in warp. Assuming something went wrong: setting GoToBase", Logging.Orange); _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.GotoBase; return; } if (Settings.Instance.DebugSalvage) { Logging.Log("DedicatedBookmarkSalvagerBehavior", "salvage: we have more wrecks to salvage", Logging.White); } //we __cannot ever__ approach in salvage.cs so this section _is_ needed. Salvage.MoveIntoRangeOfWrecks(); try { // Overwrite settings, as the 'normal' settings do not apply Salvage.MaximumWreckTargets = Cache.Instance.MaxLockedTargets; Salvage.ReserveCargoCapacity = 80; Salvage.LootEverything = true; Salvage.ProcessState(); //Logging.Log("number of max cache ship: " + Cache.Instance.ActiveShip.MaxLockedTargets); //Logging.Log("number of max cache me: " + Cache.Instance.DirectEve.Me.MaxLockedTargets); //Logging.Log("number of max math.min: " + _salvage.MaximumWreckTargets); } finally { ApplySalvageSettings(); } break; case DedicatedBookmarkSalvagerBehaviorState.Default: _States.CurrentDedicatedBookmarkSalvagerBehaviorState = DedicatedBookmarkSalvagerBehaviorState.Idle; break; } }
public void ProcessState() { //Logging.Log("DebugHangarsBehavior","ProcessState - every tick",Logging.Teal); if (Cache.Instance.SessionState == "Quitting") { BeginClosingQuestor(); } if (Cache.Instance.GotoBaseNow) { _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.GotoBase; } if ((DateTime.UtcNow.Subtract(Cache.Instance.QuestorStarted_DateTime).TotalSeconds > 10) && (DateTime.UtcNow.Subtract(Cache.Instance.QuestorStarted_DateTime).TotalSeconds < 60)) { if (Cache.Instance.QuestorJustStarted) { Cache.Instance.QuestorJustStarted = false; Cache.Instance.SessionState = "Starting Up"; // write session log Statistics.WriteSessionLogStarting(); } } // // Panic always runs, not just in space // DebugPerformanceClearandStartTimer(); _panic.ProcessState(); DebugPerformanceStopandDisplayTimer("Panic.ProcessState"); if (_States.CurrentPanicState == PanicState.Panic || _States.CurrentPanicState == PanicState.Panicking) { // If Panic is in panic state, questor is in panic States.CurrentDebugHangarBehaviorState :) _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Panic; DebugHangarsBehaviorStates(); if (PanicStateReset) { _States.CurrentPanicState = PanicState.Normal; PanicStateReset = false; } } else if (_States.CurrentPanicState == PanicState.Resume) { // Reset panic state _States.CurrentPanicState = PanicState.Normal; // Sit Idle and wait for orders. _States.CurrentTravelerState = TravelerState.Idle; _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Idle; DebugHangarsBehaviorStates(); } DebugPanicstates(); //Logging.Log("test"); switch (_States.CurrentDebugHangarBehaviorState) { case DebugHangarsBehaviorState.Idle: if (Cache.Instance.StopBot) { // // this is used by the 'local is safe' routines - standings checks - at the moment is stops questor for the rest of the session. // if (Settings.Instance.DebugAutoStart || Settings.Instance.DebugIdle) { Logging.Log("DebugHangarsBehavior", "DebugIdle: StopBot [" + Cache.Instance.StopBot + "]", Logging.White); } return; } if (Cache.Instance.InSpace) { if (Settings.Instance.DebugAutoStart || Settings.Instance.DebugIdle) { Logging.Log("DebugHangarsBehavior", "DebugIdle: InSpace [" + Cache.Instance.InSpace + "]", Logging.White); } // Questor does not handle in space starts very well, head back to base to try again Logging.Log("DebugHangarsBehavior", "Started questor while in space, heading back to base in 15 seconds", Logging.White); LastAction = DateTime.UtcNow; _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.DelayedGotoBase; break; } if (DateTime.UtcNow < Cache.Instance.LastInSpace.AddSeconds(10)) { if (Settings.Instance.DebugAutoStart || Settings.Instance.DebugIdle) { Logging.Log("DebugHangarsBehavior", "DebugIdle: Cache.Instance.LastInSpace [" + Cache.Instance.LastInSpace.Subtract(DateTime.UtcNow).TotalSeconds + "] sec ago, waiting until we have been docked for 10+ seconds", Logging.White); } return; } _States.CurrentArmState = ArmState.Idle; _States.CurrentDroneState = DroneState.Idle; _States.CurrentSalvageState = SalvageState.Idle; _States.CurrentTravelerState = TravelerState.Idle; _States.CurrentUnloadLootState = UnloadLootState.Idle; _States.CurrentTravelerState = TravelerState.Idle; LastAction = DateTime.UtcNow; break; case DebugHangarsBehaviorState.DelayedGotoBase: if (DateTime.UtcNow.Subtract(LastAction).TotalSeconds < Time.Instance.DelayedGotoBase_seconds) { break; } Logging.Log("DebugHangarsBehavior", "Heading back to base", Logging.White); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.GotoBase; break; case DebugHangarsBehaviorState.Arm: // // only used when someone manually selects the arm state. // if (_States.CurrentArmState == ArmState.Idle) { Logging.Log("Arm", "Begin", Logging.White); _States.CurrentArmState = ArmState.Begin; // Load right ammo based on mission Arm.AmmoToLoad.Clear(); Arm.LoadSpecificAmmo(new[] { Cache.Instance.MissionDamageType }); } Arm.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("Arm.State", "is" + _States.CurrentArmState, Logging.White); } if (_States.CurrentArmState == ArmState.NotEnoughAmmo) { // we know we are connected if we were able to arm the ship - update the lastknownGoodConnectedTime // we may be out of drones/ammo but disconnecting/reconnecting will not fix that so update the timestamp Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; Logging.Log("Arm", "Armstate.NotEnoughAmmo", Logging.Orange); _States.CurrentArmState = ArmState.Idle; _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; } if (_States.CurrentArmState == ArmState.NotEnoughDrones) { // we know we are connected if we were able to arm the ship - update the lastknownGoodConnectedTime // we may be out of drones/ammo but disconnecting/reconnecting will not fix that so update the timestamp Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; Logging.Log("Arm", "Armstate.NotEnoughDrones", Logging.Orange); _States.CurrentArmState = ArmState.Idle; _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; } if (_States.CurrentArmState == ArmState.Done) { //we know we are connected if we were able to arm the ship - update the lastknownGoodConnectedTime Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; _States.CurrentArmState = ArmState.Idle; _States.CurrentDroneState = DroneState.WaitingForTargets; _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Idle; } break; case DebugHangarsBehaviorState.Salvage: if (!Cache.Instance.InSpace) { return; } Cache.Instance.SalvageAll = true; Cache.Instance.OpenWrecks = true; if (Cache.Instance.CurrentShipsCargo == null) { return; } if (Settings.Instance.UnloadLootAtStation && Cache.Instance.CurrentShipsCargo.Window.IsReady && (Cache.Instance.CurrentShipsCargo.Capacity - Cache.Instance.CurrentShipsCargo.UsedCapacity) < 100) { Logging.Log("CombatMissionsBehavior.Salvage", "We are full, go to base to unload", Logging.White); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.GotoBase; break; } if (!Cache.Instance.UnlootedContainers.Any()) { break; } //we __cannot ever__ approach in salvage.cs so this section _is_ needed. Salvage.MoveIntoRangeOfWrecks(); try { // Overwrite settings, as the 'normal' settings do not apply Salvage.MaximumWreckTargets = Cache.Instance.MaxLockedTargets; Salvage.ReserveCargoCapacity = 80; Salvage.LootEverything = true; Salvage.ProcessState(); //Logging.Log("number of max cache ship: " + Cache.Instance.ActiveShip.MaxLockedTargets); //Logging.Log("number of max cache me: " + Cache.Instance.DirectEve.Me.MaxLockedTargets); //Logging.Log("number of max math.min: " + _salvage.MaximumWreckTargets); } finally { ApplyDebugSettings(); } break; case DebugHangarsBehaviorState.GotoBase: if (Settings.Instance.DebugGotobase) { Logging.Log("DebugHangarsBehavior", "GotoBase: AvoidBumpingThings()", Logging.White); } AvoidBumpingThings(); if (Settings.Instance.DebugGotobase) { Logging.Log("DebugHangarsBehavior", "GotoBase: TravelToAgentsStation()", Logging.White); } TravelToAgentsStation(); if (_States.CurrentTravelerState == TravelerState.AtDestination) // || DateTime.UtcNow.Subtract(Cache.Instance.EnteredCloseQuestor_DateTime).TotalMinutes > 10) { if (Settings.Instance.DebugGotobase) { Logging.Log("DebugHangarsBehavior", "GotoBase: We are at destination", Logging.White); } Cache.Instance.GotoBaseNow = false; //we are there - turn off the 'forced' GoToBase Cache.Instance.Mission = Cache.Instance.GetAgentMission(AgentID, false); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.UnloadLoot; Traveler.Destination = null; } break; case DebugHangarsBehaviorState.UnloadLoot: if (_States.CurrentUnloadLootState == UnloadLootState.Idle) { Logging.Log("DebugHangarsBehavior", "UnloadLoot: Begin", Logging.White); _States.CurrentUnloadLootState = UnloadLootState.Begin; } _unloadLoot.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("DebugHangarsBehavior", "UnloadLoot.State is " + _States.CurrentUnloadLootState, Logging.White); } if (_States.CurrentUnloadLootState == UnloadLootState.Done) { Cache.Instance.LootAlreadyUnloaded = true; _States.CurrentUnloadLootState = UnloadLootState.Idle; Cache.Instance.Mission = Cache.Instance.GetAgentMission(AgentID, false); if (_States.CurrentCombatState == CombatState.OutOfAmmo) // on mission { Logging.Log("DebugHangarsBehavior.UnloadLoot", "We are out of ammo", Logging.Orange); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Idle; return; } _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Idle; Logging.Log("DebugHangarsBehavior.Unloadloot", "CharacterMode: [" + Settings.Instance.CharacterMode + "], AfterMissionSalvaging: [" + Settings.Instance.AfterMissionSalvaging + "], DebugHangarsBehaviorState: [" + _States.CurrentDebugHangarBehaviorState + "]", Logging.White); Statistics.Instance.FinishedMission = DateTime.UtcNow; return; } break; case DebugHangarsBehaviorState.Traveler: Cache.Instance.OpenWrecks = false; List <int> destination = Cache.Instance.DirectEve.Navigation.GetDestinationPath(); if (destination == null || destination.Count == 0) { // happens if autopilot is not set and this QuestorState is chosen manually // this also happens when we get to destination (!?) Logging.Log("DebugHangarsBehavior.Traveler", "No destination?", Logging.White); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; return; } else if (destination.Count == 1 && destination.FirstOrDefault() == 0) { destination[0] = Cache.Instance.DirectEve.Session.SolarSystemId ?? -1; } if (Traveler.Destination == null || Traveler.Destination.SolarSystemId != destination.Last()) { IEnumerable <DirectBookmark> bookmarks = Cache.Instance.AllBookmarks.Where(b => b.LocationId == destination.Last()).ToList(); if (bookmarks != null && bookmarks.Any()) { Traveler.Destination = new BookmarkDestination(bookmarks.OrderBy(b => b.CreatedOn).FirstOrDefault()); } else { Logging.Log("DebugHangarsBehavior.Traveler", "Destination: [" + Cache.Instance.DirectEve.Navigation.GetLocation(destination.Last()).Name + "]", Logging.White); Traveler.Destination = new SolarSystemDestination(destination.Last()); } } else { Traveler.ProcessState(); //we also assume you are connected during a manual set of questor into travel mode (safe assumption considering someone is at the kb) Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; if (_States.CurrentTravelerState == TravelerState.AtDestination) { if (_States.CurrentCombatMissionCtrlState == CombatMissionCtrlState.Error) { Logging.Log("DebugHangarsBehavior.Traveler", "an error has occurred", Logging.White); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; return; } if (Cache.Instance.InSpace) { Logging.Log("DebugHangarsBehavior.Traveler", "Arrived at destination (in space, Questor stopped)", Logging.White); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; return; } Logging.Log("DebugHangarsBehavior.Traveler", "Arrived at destination", Logging.White); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Idle; return; } } break; case DebugHangarsBehaviorState.GotoNearestStation: if (!Cache.Instance.InSpace || Cache.Instance.InWarp) { return; } EntityCache station = null; if (Cache.Instance.Stations != null && Cache.Instance.Stations.Any()) { station = Cache.Instance.Stations.OrderBy(x => x.Distance).FirstOrDefault(); } if (station != null) { if (station.Distance > (int)Distances.WarptoDistance) { if (station.WarpTo()) { Logging.Log("DebugHangarsBehavior.GotoNearestStation", "[" + station.Name + "] which is [" + Math.Round(station.Distance / 1000, 0) + "k away]", Logging.White); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Idle; break; } break; } if (station.Distance < 1900) { if (station.Dock()) { Logging.Log("DebugBehavior.GotoNearestStation", "[" + station.Name + "] which is [" + Math.Round(station.Distance / 1000, 0) + "k away]", Logging.White); } } else { if (Cache.Instance.NextApproachAction < DateTime.UtcNow && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != station.Id)) { Cache.Instance.NextApproachAction = DateTime.UtcNow.AddSeconds(Time.Instance.ApproachDelay_seconds); Logging.Log("DebugHangarsBehavior.GotoNearestStation", "Approaching [" + station.Name + "] which is [" + Math.Round(station.Distance / 1000, 0) + "k away]", Logging.White); station.Approach(); } } } else { _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; //should we goto idle here? } break; case DebugHangarsBehaviorState.ReadyItemsHangar: Logging.Log("DebugHangars", "DebugHangarsState.ReadyItemsHangar:", Logging.White); if (Cache.Instance.ItemHangar == null) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.StackItemsHangar: Logging.Log("DebugHangars", "DebugHangarsState.StackItemsHangar:", Logging.White); if (!Cache.Instance.StackItemsHangarAsAmmoHangar("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.CloseItemsHangar: Logging.Log("DebugHangars", "DebugHangarsState.CloseItemsHangar:", Logging.White); if (!Cache.Instance.CloseItemsHangar("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.OpenShipsHangar: Logging.Log("DebugHangars", "DebugHangarsState.OpenShipsHangar:", Logging.White); if (!Cache.Instance.OpenShipsHangar("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.StackShipsHangar: Logging.Log("DebugHangars", "DebugHangarsState.StackShipsHangar:", Logging.White); if (!Cache.Instance.StackShipsHangar("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.CloseShipsHangar: Logging.Log("DebugHangars", "DebugHangarsState.CloseShipsHangar:", Logging.White); if (!Cache.Instance.CloseShipsHangar("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.OpenLootContainer: Logging.Log("DebugHangars", "DebugHangarsState.OpenLootContainer:", Logging.White); Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.StackLootContainer: Logging.Log("DebugHangars", "DebugHangarsState.StackLootContainer:", Logging.White); if (!Cache.Instance.StackLootContainer("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.CloseLootContainer: Logging.Log("DebugHangars", "DebugHangarsState.CloseLootContainer:", Logging.White); if (!Cache.Instance.CloseLootContainer("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; //Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.OpenCorpAmmoHangar: Logging.Log("DebugHangars", "DebugHangarsState.OpenCorpAmmoHangar:", Logging.White); Cache.Instance.DebugInventoryWindows("DebugHangars"); Logging.Log("OpenCorpAmmoHangar", "AmmoHangar Contains [" + Cache.Instance.AmmoHangar.Items.Count() + "] Items", Logging.Debug); try { int icount = 0; foreach (DirectItem itemfound in Cache.Instance.AmmoHangar.Items) { icount++; Logging.Log("Arm.MoveItems", "Found: Name [" + itemfound.TypeName + "] Quantity [" + itemfound.Quantity + "] in the AmmoHangar", Logging.Red); if (icount > 20) { Logging.Log("Arm.MoveItems", "max items to log reached (over 20). there are probably more items but we only log 20 of em.", Logging.Red); break; } continue; } } catch (Exception exception) { Logging.Log("OpenCorpLootHangar", "Exception was: [" + exception + "]", Logging.Debug); } _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.StackCorpAmmoHangar: Logging.Log("DebugHangars", "DebugHangarsState.StackCorpAmmoHangar:", Logging.White); if (!Cache.Instance.StackCorpAmmoHangar("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.CloseCorpAmmoHangar: Logging.Log("DebugHangars", "DebugHangarsState.CloseCorpAmmoHangar:", Logging.White); if (!Cache.Instance.CloseCorpHangar("DebugHangars", "AMMO")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.OpenCorpLootHangar: Logging.Log("DebugHangars", "DebugHangarsState.OpenCorpLootHangar:", Logging.White); Cache.Instance.DebugInventoryWindows("DebugHangars"); Logging.Log("OpenCorpLootHangar", "LootHangar Contains [" + Cache.Instance.LootHangar.Items.Count() + "] Items", Logging.Debug); try { int icount2 = 0; foreach (DirectItem itemfound in Cache.Instance.LootHangar.Items) { icount2++; Logging.Log("Arm.MoveItems", "Found: Name [" + itemfound.TypeName + "] Quantity [" + itemfound.Quantity + "] in the LootHangar", Logging.Red); if (icount2 > 20) { Logging.Log("Arm.MoveItems", "max items to log reached (over 20). there are probably more items but we only log 20 of em.", Logging.Red); break; } continue; } } catch (Exception exception) { Logging.Log("OpenCorpLootHangar", "Exception was: [" + exception + "]", Logging.Debug); } _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.StackCorpLootHangar: Logging.Log("DebugHangars", "DebugHangarsState.StackCorpLootHangar:", Logging.White); if (!Cache.Instance.StackCorpLootHangar("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.CloseCorpLootHangar: Logging.Log("DebugHangars", "DebugHangarsState.CloseCorpLootHangar:", Logging.White); if (!Cache.Instance.CloseCorpHangar("DebugHangars", "LOOT")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.OpenAmmoHangar: Logging.Log("DebugHangars", "DebugHangarsState.OpenAmmoHangar:", Logging.White); Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.StackAmmoHangar: Logging.Log("DebugHangars", "DebugHangarsState.StackAmmoHangar:", Logging.White); if (!Cache.Instance.StackAmmoHangar("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.CloseAmmoHangar: Logging.Log("DebugHangars", "DebugHangarsState.CloseAmmoHangar:", Logging.White); if (!Cache.Instance.CloseAmmoHangar("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.OpenLootHangar: Logging.Log("DebugHangars", "DebugHangarsState.OpenLootHangar:", Logging.White); Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.StackLootHangar: Logging.Log("DebugHangars", "DebugHangarsState.StackLootHangar:", Logging.White); if (!Cache.Instance.StackLootHangar("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.CloseLootHangar: Logging.Log("DebugHangars", "DebugHangarsState.CloseLootHangar:", Logging.White); if (!Cache.Instance.CloseLootHangar("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.CloseAllInventoryWindows: Logging.Log("DebugHangars", "DebugHangarsState.CloseAllInventoryWindows:", Logging.White); if (!Cleanup.CloseInventoryWindows()) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.OpenCargoHold: Logging.Log("DebugHangars", "DebugHangarsState.StackLootHangar:", Logging.White); if (Cache.Instance.CurrentShipsCargo == null) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.StackCargoHold: Logging.Log("DebugHangars", "DebugHangarsState.CloseLootHangar:", Logging.White); if (!Cache.Instance.StackCargoHold("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.CloseCargoHold: Logging.Log("DebugHangars", "DebugHangarsState.CloseAllInventoryWindows:", Logging.White); if (!Cache.Instance.CloseCargoHold("DebugHangars")) { return; } Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.GetAmmoHangarID: Logging.Log("DebugHangars", "DebugHangarsState.GetAmmoHangarID:", Logging.White); if (!Cache.Instance.GetCorpAmmoHangarID()) { return; } Logging.Log("DebugHangars", "AmmoHangarId [" + Cache.Instance.AmmoHangarID + "]", Logging.White); Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.GetLootHangarID: Logging.Log("DebugHangars", "DebugHangarsState.GetLootHangarID:", Logging.White); if (!Cache.Instance.GetCorpLootHangarID()) { return; } Logging.Log("DebugHangars", "LootHangarId [" + Cache.Instance.LootHangarID + "]", Logging.White); Cache.Instance.DebugInventoryWindows("DebugHangars"); _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.OpenInventory: Logging.Log("DebugHangars", "DebugHangarsState.OpenInventory:", Logging.White); if (!Cache.Instance.OpenInventoryWindow("DebugHangarsState.OpenInventoryWindow")) { return; } _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.ListInvTree: Logging.Log("DebugHangars", "DebugHangarsState.ListInvTree:", Logging.White); if (!Cache.Instance.ListInvTree("DebugHangarsState.ListInvTree")) { return; } _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.OpenOreHold: Logging.Log("DebugHangars", "DebugHangarsState.OpenOreHold:", Logging.White); if (!Cache.Instance.OpenOreHold("DebugHangarsState.OpenOreHold")) { return; } _States.CurrentDebugHangarBehaviorState = DebugHangarsBehaviorState.Error; Cache.Instance.Paused = true; break; case DebugHangarsBehaviorState.Default: break; } }
public void ProcessState() { if (DateTime.UtcNow.Subtract(_lastPulse).TotalMilliseconds < Time.Instance.QuestorPulse_milliseconds) //default: 1500ms { return; } _lastPulse = DateTime.UtcNow; if (Cache.Instance.SessionState == "Quitting") { BeginClosingQuestor(); } if (Cache.Instance.GotoBaseNow) { _States.CurrentMiningState = MiningState.GotoBase; } if ((DateTime.UtcNow.Subtract(Cache.Instance.QuestorStarted_DateTime).TotalSeconds > 10) && (DateTime.UtcNow.Subtract(Cache.Instance.QuestorStarted_DateTime).TotalSeconds < 60)) { if (Cache.Instance.QuestorJustStarted) { Cache.Instance.QuestorJustStarted = false; Cache.Instance.SessionState = "Starting Up"; // write session log Statistics.WriteSessionLogStarting(); } } _panic.ProcessState(); if (_States.CurrentPanicState == PanicState.Panic || _States.CurrentPanicState == PanicState.Panicking) { // If Panic is in panic state, questor is in panic States.CurrentCombatMissionBehaviorState :) _States.CurrentMiningState = MiningState.Panic; if (PanicStateReset) { _States.CurrentPanicState = PanicState.Normal; PanicStateReset = false; } } else if (_States.CurrentPanicState == PanicState.Resume) { // Reset panic state _States.CurrentPanicState = PanicState.Normal; _States.CurrentTravelerState = TravelerState.Idle; _States.CurrentMiningState = MiningState.GotoBelt; } if (Settings.Instance.DebugMiningBehavior) { Logging.Log("MiningBehavior", "Pre-switch", Logging.White); } switch (_States.CurrentMiningState) { case MiningState.Default: case MiningState.Idle: _States.CurrentMiningState = MiningState.Cleanup; break; case MiningState.Cleanup: if (Cache.Instance.LootAlreadyUnloaded == false) { _States.CurrentMiningState = MiningState.GotoBase; break; } Cleanup.CheckEVEStatus(); _States.CurrentMiningState = MiningState.Arm; break; case MiningState.GotoBase: DirectBookmark miningHome = Cache.Instance.BookmarksByLabel("Mining Home").FirstOrDefault(); //Cache.Instance.DirectEve.Navigation.GetDestinationPath Traveler.TravelToMiningHomeBookmark(miningHome, "Mining go to base"); if (_States.CurrentTravelerState == TravelerState.AtDestination) // || DateTime.UtcNow.Subtract(Cache.Instance.EnteredCloseQuestor_DateTime).TotalMinutes > 10) { if (Settings.Instance.DebugGotobase) { Logging.Log("MiningBehavior", "GotoBase: We are at destination", Logging.White); } Cache.Instance.GotoBaseNow = false; //we are there - turn off the 'forced' gotobase _States.CurrentMiningState = MiningState.UnloadLoot; Traveler.Destination = null; } break; case MiningState.UnloadLoot: // // this state should never be reached in space. if we are in space and in this state we should switch to gotobase // if (Cache.Instance.InSpace) { Logging.Log(_States.CurrentCombatMissionBehaviorState.ToString(), "We are in space, how did we get set to this state while in space? Changing state to: GotoBase", Logging.White); _States.CurrentMiningState = MiningState.GotoBase; } if (_States.CurrentUnloadLootState == UnloadLootState.Idle) { Logging.Log("MiningBehavior", "UnloadLoot: Begin", Logging.White); _States.CurrentUnloadLootState = UnloadLootState.Begin; } _unloadLoot.ProcessState(); if (_States.CurrentUnloadLootState == UnloadLootState.Done) { Cache.Instance.LootAlreadyUnloaded = true; _States.CurrentUnloadLootState = UnloadLootState.Idle; if (_States.CurrentCombatState == CombatState.OutOfAmmo) { Logging.Log("MiningBehavior.UnloadLoot", "We are out of ammo", Logging.Orange); _States.CurrentMiningState = MiningState.Idle; return; } _States.CurrentMiningState = MiningState.Idle; _States.CurrentQuestorState = QuestorState.Idle; Logging.Log("MiningBehavior.Unloadloot", "CharacterMode: [" + Settings.Instance.CharacterMode + "], AfterMissionSalvaging: [" + Settings.Instance.AfterMissionSalvaging + "], MiningState: [" + _States.CurrentMiningState + "]", Logging.White); return; } break; case MiningState.Start: Cache.Instance.OpenWrecks = false; _States.CurrentMiningState = MiningState.Arm; DirectBookmark asteroidShortcut = Cache.Instance.BookmarksByLabel("Asteroid Location").FirstOrDefault(); if (asteroidShortcut != null) { asteroidShortcut.Delete(); } break; case MiningState.Arm: // // this state should never be reached in space. if we are in space and in this state we should switch to gotobase // if (Cache.Instance.InSpace) { Logging.Log(_States.CurrentMiningState.ToString(), "We are in space, how did we get set to this state while in space? Changing state to: GotoBase", Logging.White); _States.CurrentMiningState = MiningState.GotoBase; } if (_States.CurrentArmState == ArmState.Idle) { Logging.Log("Arm", "Begin", Logging.White); _States.CurrentArmState = ArmState.Begin; // Load ammo... this "fixes" the problem I experienced with not reloading after second arm phase. The quantity was getting set to 0. Arm.AmmoToLoad.Clear(); Arm.AmmoToLoad.Add(Settings.Instance.Ammo.FirstOrDefault()); //FIXME: bad hack - this should be fixed differently / elsewhere Ammo FirstAmmoToLoad = Arm.AmmoToLoad.FirstOrDefault(); if (FirstAmmoToLoad != null && FirstAmmoToLoad.Quantity == 0) { FirstAmmoToLoad.Quantity = 333; } } Arm.ProcessState(); if (_States.CurrentArmState == ArmState.NotEnoughAmmo) { // we know we are connected if we were able to arm the ship - update the lastknownGoodConnectedTime // we may be out of drones/ammo but disconnecting/reconnecting will not fix that so update the timestamp Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; Logging.Log("Arm", "Armstate.NotEnoughAmmo", Logging.Orange); _States.CurrentArmState = ArmState.Idle; _States.CurrentMiningState = MiningState.Error; } if (_States.CurrentArmState == ArmState.NotEnoughDrones) { // we know we are connected if we were able to arm the ship - update the lastknownGoodConnectedTime // we may be out of drones/ammo but disconnecting/reconnecting will not fix that so update the timestamp Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; Logging.Log("Arm", "Armstate.NotEnoughDrones", Logging.Orange); _States.CurrentArmState = ArmState.Idle; _States.CurrentMiningState = MiningState.Error; } if (_States.CurrentArmState == ArmState.Done) { if (DateTime.UtcNow > Cache.Instance.LastInSpace.AddSeconds(45)) //do not try to leave the station until you have been docked for at least 45seconds! (this gives some overhead to load the station env + session change timer) { //we know we are connected if we were able to arm the ship - update the lastknownGoodConnectedTime Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; _States.CurrentArmState = ArmState.Idle; _States.CurrentDroneState = DroneState.WaitingForTargets; //exit the station Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.CmdExitStation); //set up a wait of 10 seconds so the undock can complete _lastPulse = DateTime.UtcNow.AddSeconds(10); _States.CurrentMiningState = MiningState.GotoBelt; } } break; case MiningState.GotoBelt: if (DateTime.UtcNow.Subtract(_lastPulse).TotalMilliseconds < Time.Instance.QuestorPulse_milliseconds * 2) { return; } if (Cache.Instance.InWarp || (!Cache.Instance.InSpace && !Cache.Instance.InStation)) { return; } // // this should goto a mining system bookmark (one of possibly many) // then goto the 1st belt. This would allow for mining in systems without stations // Logging.Log("MiningBehavior", "Setting Destination to 1st Asteroid belt.", Logging.White); DirectBookmark asteroidShortcutGTB = Cache.Instance.BookmarksByLabel("Asteroid Location").FirstOrDefault(); if (asteroidShortcutGTB != null) { if (Cache.Instance.EntityById(_currentBelt.Id).Distance < 65000) { _States.CurrentMiningState = MiningState.Mine; Traveler.Destination = null; } else { asteroidShortcutGTB.WarpTo(); _lastPulse = DateTime.UtcNow; } break; } IEnumerable <EntityCache> belts = Cache.Instance.Entities.Where(i => i.GroupId == (int)Group.AsteroidBelt && !i.Name.ToLower().Contains("ice") && !EmptyBelts.Contains(i.Id)); EntityCache belt = belts.OrderBy(x => x.Distance).FirstOrDefault(); _currentBelt = belt; //Traveler.Destination = new MissionBookmarkDestination(belt); if (belt != null) { if (belt.Distance < 35000) { _States.CurrentMiningState = MiningState.Mine; Traveler.Destination = null; } else { if (belt.WarpTo()) { _lastPulse = DateTime.UtcNow; } } break; } _States.CurrentMiningState = MiningState.GotoBase; Logging.Log("MiningBehavior", "Could not find a suitable Asteroid belt.", Logging.White); Settings.Instance.AutoStart = false; break; case MiningState.Mine: IEnumerable <EntityCache> _asteroidsOnGrid = Cache.Instance.EntitiesOnGrid.Where(i => i.Distance < (int)Distances.OnGridWithMe && i.CategoryId == (int)CategoryID.Asteroid).OrderBy(i => i.Distance); IEnumerable <EntityCache> _asteroidsInRange = _asteroidsOnGrid.Where(i => i.Distance < 65000).ToList(); EntityCache asteroid = null; if (asteroid == null && _asteroidsInRange.Any(i => i.GroupId == (int)Group.Kernite)) { asteroid = _asteroidsInRange.Where(i => i.GroupId == (int)Group.Kernite).OrderBy(i => i.Distance).FirstOrDefault(); } if (asteroid == null && _asteroidsInRange.Any(i => i.GroupId == (int)Group.Plagioclase)) { asteroid = _asteroidsInRange.Where(i => i.GroupId == (int)Group.Plagioclase).OrderBy(i => i.Distance).FirstOrDefault(); } if (asteroid == null && _asteroidsInRange.Any(i => i.GroupId == (int)Group.Pyroxeres)) { asteroid = _asteroidsInRange.Where(i => i.GroupId == (int)Group.Pyroxeres).OrderBy(i => i.Distance).FirstOrDefault(); } if (asteroid == null && _asteroidsInRange.Any(i => i.GroupId == (int)Group.Scordite)) { asteroid = _asteroidsInRange.Where(i => i.GroupId == (int)Group.Scordite).OrderBy(i => i.Distance).FirstOrDefault(); } if (asteroid == null && _asteroidsInRange.Any(i => i.GroupId == (int)Group.Veldspar)) { asteroid = _asteroidsInRange.Where(i => i.GroupId == (int)Group.Veldspar).OrderBy(i => i.Distance).FirstOrDefault(); } if (asteroid == null) { EmptyBelts.Add(_currentBelt.Id); DirectBookmark asteroidShortcutBM2 = Cache.Instance.BookmarksByLabel("Asteroid Location").FirstOrDefault(); if (asteroidShortcutBM2 != null) { asteroidShortcutBM2.Delete(); } Logging.Log("MiningBehavior", "Could not find a suitable Asteroid to mine in this belt.", Logging.White); _States.CurrentMiningState = MiningState.GotoBelt; break; } Logging.Log("Mining: [", "Target Rock is [" + asteroid.Name + "][" + Math.Round(asteroid.Distance / 1000, 0) + "k] ID [" + asteroid.MaskedId + "] GroupID [" + asteroid.GroupId + "]", Logging.White); _targetAsteroidID = asteroid.Id; _targetAsteroid.Approach(); _States.CurrentMiningState = MiningState.MineAsteroid; break; case MiningState.MineAsteroid: if (Cache.Instance.EntityById(_targetAsteroidID) == null) { Logging.Log("Mining: [", "Target Rock [" + Cache.Instance.MaskedID(_targetAsteroidID) + "] has been depleted. Searching for another target.", Logging.White); _States.CurrentMiningState = MiningState.Mine; return; } _targetAsteroid = Cache.Instance.EntityById(_targetAsteroidID); Combat.ProcessState(); Drones.ProcessState(); // If we are out of ammo, return to base, Arm should then grab the right ammo / crystals / drones if (_States.CurrentCombatState == CombatState.OutOfAmmo) { Logging.Log("Combat", "Out of Ammo!", Logging.Orange); _States.CurrentMiningState = MiningState.GotoBase; } //check if we're full // // we really ought to be checking for and using the OreHold if needed, not directly using the cargohold ffs! // if (Cache.Instance.CurrentShipsCargo == null) { return; } if (Cache.Instance.CurrentShipsCargo.IsValid && (Cache.Instance.CurrentShipsCargo.UsedCapacity >= Cache.Instance.CurrentShipsCargo.Capacity * .9) && Cache.Instance.CurrentShipsCargo.Capacity > 0) { if (_States.CurrentDroneState == DroneState.WaitingForTargets) { Logging.Log("Miner:MineAsteroid", "We are full, go to base to unload. Capacity is: " + Cache.Instance.CurrentShipsCargo.Capacity + ", Used: " + Cache.Instance.CurrentShipsCargo.UsedCapacity, Logging.White); _States.CurrentMiningState = MiningState.GotoBase; break; } if (_States.CurrentDroneState == DroneState.WaitingForTargets) { Logging.Log("Miner:MineAsteroid", "We are full, but drones are busy. Drone state: " + _States.CurrentDroneState.ToString(), Logging.White); } } // // do we need to make sure the rock is in targeting range? rats that damp, frigates with crap skills?, wormhole effects... // if (_targetAsteroid.Distance < 10000) { if (_targetAsteroid.Distance < 9400) { if (_asteroidBookmarkForID != _targetAsteroid.Id) { DirectBookmark asteroidShortcutBM = Cache.Instance.BookmarksByLabel("Asteroid Location").FirstOrDefault(); if (asteroidShortcutBM != null) { asteroidShortcutBM.UpdateBookmark("Asteroid Location", "Mining Shortcut"); } else { Cache.Instance.DirectEve.BookmarkCurrentLocation("Asteroid Location", "Mining Shortcut", null); } _asteroidBookmarkForID = _targetAsteroid.Id; } } if (Cache.Instance.Targeting.Contains(_targetAsteroid)) { if (Settings.Instance.DebugMiningBehavior) { Logging.Log("Miner:MineAsteroid", "Targeting asteroid.", Logging.White); } return; //wait } if (Cache.Instance.Targets.Contains(_targetAsteroid)) { if (Settings.Instance.DebugMiningBehavior) { Logging.Log("Miner:MineAsteroid", "Asteroid Targeted.", Logging.White); } //if(!_targetAsteroid.IsActiveTarget) _targetAsteroid.MakeActiveTarget(); List <ModuleCache> miningTools = Cache.Instance.Modules.Where(m => MiningToolGroupIDs.Contains(m.GroupId)).ToList(); _minerNumber = 0; foreach (ModuleCache miningTool in miningTools) { if (Cache.Instance.LastActivatedTimeStamp != null && Cache.Instance.LastActivatedTimeStamp.ContainsKey(miningTool.ItemId)) { if (Cache.Instance.LastActivatedTimeStamp[miningTool.ItemId].AddSeconds(3) > DateTime.UtcNow) { continue; } } _minerNumber++; // Are we on the right target? if (miningTool.IsActive) { if (miningTool.TargetId != _targetAsteroid.Id) { if (miningTool.Click()) { return; } return; } continue; } // Are we deactivating? if (miningTool.IsDeactivating) { continue; } if (miningTool.Activate(_targetAsteroid)) { //only activate one module per cycle Logging.Log("Mining", "Activating mining tool [" + _minerNumber + "] on [" + _targetAsteroid.Name + "][" + Cache.Instance.MaskedID(_targetAsteroid.Id) + "][" + Math.Round(_targetAsteroid.Distance / 1000, 0) + "k away]", Logging.Teal); return; } continue; } return; } //mine //asteroid is not targeted if (Settings.Instance.DebugMiningBehavior) { Logging.Log("Miner:MineAsteroid", "Asteroid not yet targeted.", Logging.White); } if (DateTime.UtcNow < Cache.Instance.NextTargetAction) //if we just did something wait a fraction of a second { return; } if (Cache.Instance.MaxLockedTargets == 0) { if (!_isJammed) { Logging.Log("Mining", "We are jammed and can't target anything", Logging.Orange); } _isJammed = true; return; } if (_isJammed) { // Clear targeting list as it does not apply Cache.Instance.TargetingIDs.Clear(); Logging.Log("Mining", "We are no longer jammed, ReTargeting", Logging.Teal); } _isJammed = false; _targetAsteroid.LockTarget("Mining.targetAsteroid"); Cache.Instance.NextTargetAction = DateTime.UtcNow.AddMilliseconds(Time.Instance.TargetDelay_milliseconds); return; } //check 10K distance // // not inside 10k // if (Settings.Instance.DebugMiningBehavior) { Logging.Log("Miner:MineAsteroid", "Debug: Distance to Target [" + Math.Round(_targetAsteroid.Distance / 1000, 2) + "] > 10K.] Id [" + _targetAsteroid.Id + "] TargetingMe [" + Combat.TargetingMe.Count() + "]", Logging.White); } //this isn't working because Cache.Instance.Approaching.TargetValue always seems to return null. This will negatively impact combat since it won't orbit. Might want to check CombatState instead. if (Cache.Instance.IsApproaching(_targetAsteroidID) && !Cache.Instance.TargetedBy.Any()) { // // this will only approach every 15 sec // _targetAsteroid.Approach(); } break; } //ends MiningState switch } //ends ProcessState method
public void ProcessState() { // Invalid settings, quit while we're ahead if (!ValidSettings) { if (DateTime.UtcNow.Subtract(LastAction).TotalSeconds < Time.Instance.ValidateSettings_seconds) //default is a 15 second interval { ValidateCombatMissionSettings(); LastAction = DateTime.UtcNow; } return; } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //this local is safe check is useless as their is no LocalWatch processstate running every tick... //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //If local unsafe go to base and do not start mission again if (Settings.Instance.FinishWhenNotSafe && (_States.CurrentDebugBehaviorState != DebugBehaviorState.GotoNearestStation /*|| State!=QuestorState.GotoBase*/)) { //need to remove spam if (Cache.Instance.InSpace && !Cache.Instance.LocalSafe(Settings.Instance.LocalBadStandingPilotsToTolerate, Settings.Instance.LocalBadStandingLevelToConsiderBad)) { EntityCache station = null; if (Cache.Instance.Stations != null && Cache.Instance.Stations.Any()) { station = Cache.Instance.Stations.OrderBy(x => x.Distance).FirstOrDefault(); } if (station != null) { Logging.Log("Local not safe", "Station found. Going to nearest station", Logging.White); _States.CurrentDebugBehaviorState = DebugBehaviorState.GotoNearestStation; } else { Logging.Log("Local not safe", "Station not found. Going back to base", Logging.White); _States.CurrentDebugBehaviorState = DebugBehaviorState.GotoBase; } Cache.Instance.StopBot = true; } } if (Cache.Instance.SessionState == "Quitting") { BeginClosingQuestor(); } if (Cache.Instance.GotoBaseNow) { _States.CurrentDebugBehaviorState = DebugBehaviorState.GotoBase; } if ((DateTime.UtcNow.Subtract(Cache.Instance.QuestorStarted_DateTime).TotalSeconds > 10) && (DateTime.UtcNow.Subtract(Cache.Instance.QuestorStarted_DateTime).TotalSeconds < 60)) { if (Cache.Instance.QuestorJustStarted) { Cache.Instance.QuestorJustStarted = false; Cache.Instance.SessionState = "Starting Up"; // write session log Statistics.WriteSessionLogStarting(); } } // // Panic always runs, not just in space // DebugPerformanceClearandStartTimer(); _panic.ProcessState(); DebugPerformanceStopandDisplayTimer("Panic.ProcessState"); if (_States.CurrentPanicState == PanicState.Panic || _States.CurrentPanicState == PanicState.Panicking) { // If Panic is in panic state, questor is in panic States.CurrentDebugBehaviorState :) _States.CurrentDebugBehaviorState = DebugBehaviorState.Panic; DebugDebugBehaviorStates(); if (PanicStateReset) { _States.CurrentPanicState = PanicState.Normal; PanicStateReset = false; } } else if (_States.CurrentPanicState == PanicState.Resume) { // Reset panic state _States.CurrentPanicState = PanicState.Normal; // Sit Idle and wait for orders. _States.CurrentTravelerState = TravelerState.Idle; _States.CurrentDebugBehaviorState = DebugBehaviorState.Idle; DebugDebugBehaviorStates(); } DebugPanicstates(); //Logging.Log("test"); switch (_States.CurrentDebugBehaviorState) { case DebugBehaviorState.Idle: if (Cache.Instance.StopBot) { // // this is used by the 'local is safe' routines - standings checks - at the moment is stops questor for the rest of the session. // if (Settings.Instance.DebugAutoStart || Settings.Instance.DebugIdle) { Logging.Log("DebugBehavior", "DebugIdle: StopBot [" + Cache.Instance.StopBot + "]", Logging.White); } return; } if (Cache.Instance.InSpace) { if (Settings.Instance.DebugAutoStart || Settings.Instance.DebugIdle) { Logging.Log("DebugBehavior", "DebugIdle: InSpace [" + Cache.Instance.InSpace + "]", Logging.White); } // Questor does not handle in space starts very well, head back to base to try again Logging.Log("DebugBehavior", "Started questor while in space, heading back to base in 15 seconds", Logging.White); LastAction = DateTime.UtcNow; _States.CurrentDebugBehaviorState = DebugBehaviorState.DelayedGotoBase; break; } if (DateTime.UtcNow < Cache.Instance.LastInSpace.AddSeconds(10)) { if (Settings.Instance.DebugAutoStart || Settings.Instance.DebugIdle) { Logging.Log("DebugBehavior", "DebugIdle: Cache.Instance.LastInSpace [" + Cache.Instance.LastInSpace.Subtract(DateTime.UtcNow).TotalSeconds + "] sec ago, waiting until we have been docked for 10+ seconds", Logging.White); } return; } _States.CurrentArmState = ArmState.Idle; _States.CurrentDroneState = DroneState.Idle; _States.CurrentSalvageState = SalvageState.Idle; _States.CurrentTravelerState = TravelerState.Idle; _States.CurrentUnloadLootState = UnloadLootState.Idle; _States.CurrentTravelerState = TravelerState.Idle; Logging.Log("DebugBehavior", "Started questor in Debug mode", Logging.White); LastAction = DateTime.UtcNow; break; case DebugBehaviorState.DelayedGotoBase: if (DateTime.UtcNow.Subtract(LastAction).TotalSeconds < Time.Instance.DelayedGotoBase_seconds) { break; } Logging.Log("DebugBehavior", "Heading back to base", Logging.White); _States.CurrentDebugBehaviorState = DebugBehaviorState.GotoBase; break; case DebugBehaviorState.Arm: // // only used when someone manually selects the arm state. // if (_States.CurrentArmState == ArmState.Idle) { Logging.Log("Arm", "Begin", Logging.White); _States.CurrentArmState = ArmState.Begin; // Load right ammo based on mission Arm.AmmoToLoad.Clear(); Arm.LoadSpecificAmmo(new[] { Cache.Instance.MissionDamageType }); } Arm.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("Arm.State", "is" + _States.CurrentArmState, Logging.White); } if (_States.CurrentArmState == ArmState.NotEnoughAmmo) { // we know we are connected if we were able to arm the ship - update the lastknownGoodConnectedTime // we may be out of drones/ammo but disconnecting/reconnecting will not fix that so update the timestamp Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; Logging.Log("Arm", "Armstate.NotEnoughAmmo", Logging.Orange); _States.CurrentArmState = ArmState.Idle; _States.CurrentDebugBehaviorState = DebugBehaviorState.Error; } if (_States.CurrentArmState == ArmState.NotEnoughDrones) { // we know we are connected if we were able to arm the ship - update the lastknownGoodConnectedTime // we may be out of drones/ammo but disconnecting/reconnecting will not fix that so update the timestamp Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; Logging.Log("Arm", "Armstate.NotEnoughDrones", Logging.Orange); _States.CurrentArmState = ArmState.Idle; _States.CurrentDebugBehaviorState = DebugBehaviorState.Error; } if (_States.CurrentArmState == ArmState.Done) { //we know we are connected if we were able to arm the ship - update the lastknownGoodConnectedTime Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; _States.CurrentArmState = ArmState.Idle; _States.CurrentDroneState = DroneState.WaitingForTargets; _States.CurrentDebugBehaviorState = DebugBehaviorState.Idle; } break; case DebugBehaviorState.Salvage: if (!Cache.Instance.InSpace) { return; } Cache.Instance.SalvageAll = true; Cache.Instance.OpenWrecks = true; if (Cache.Instance.CurrentShipsCargo == null) { return; } if (Settings.Instance.UnloadLootAtStation && Cache.Instance.CurrentShipsCargo.Window.IsReady && (Cache.Instance.CurrentShipsCargo.Capacity - Cache.Instance.CurrentShipsCargo.UsedCapacity) < 100) { Logging.Log("CombatMissionsBehavior.Salvage", "We are full, go to base to unload", Logging.White); _States.CurrentCombatMissionBehaviorState = CombatMissionsBehaviorState.GotoBase; break; } if (!Cache.Instance.UnlootedContainers.Any()) { break; } //we __cannot ever__ approach in salvage.cs so this section _is_ needed. Salvage.MoveIntoRangeOfWrecks(); try { // Overwrite settings, as the 'normal' settings do not apply Salvage.MaximumWreckTargets = Cache.Instance.MaxLockedTargets; Salvage.ReserveCargoCapacity = 80; Salvage.LootEverything = true; Salvage.ProcessState(); //Logging.Log("number of max cache ship: " + Cache.Instance.ActiveShip.MaxLockedTargets); //Logging.Log("number of max cache me: " + Cache.Instance.DirectEve.Me.MaxLockedTargets); //Logging.Log("number of max math.min: " + _salvage.MaximumWreckTargets); } finally { ApplyDebugSettings(); } break; case DebugBehaviorState.GotoBase: if (Settings.Instance.DebugGotobase) { Logging.Log("DebugBehavior", "GotoBase: AvoidBumpingThings()", Logging.White); } AvoidBumpingThings(); if (Settings.Instance.DebugGotobase) { Logging.Log("DebugBehavior", "GotoBase: TravelToAgentsStation()", Logging.White); } Traveler.TravelHome("DebugBehavior.TravelHome"); if (_States.CurrentTravelerState == TravelerState.AtDestination) // || DateTime.UtcNow.Subtract(Cache.Instance.EnteredCloseQuestor_DateTime).TotalMinutes > 10) { if (Settings.Instance.DebugGotobase) { Logging.Log("DebugBehavior", "GotoBase: We are at destination", Logging.White); } Cache.Instance.GotoBaseNow = false; //we are there - turn off the 'forced' GoToBase Cache.Instance.Mission = Cache.Instance.GetAgentMission(AgentID, false); _States.CurrentDebugBehaviorState = DebugBehaviorState.UnloadLoot; Traveler.Destination = null; } break; case DebugBehaviorState.UnloadLoot: if (_States.CurrentUnloadLootState == UnloadLootState.Idle) { Logging.Log("DebugBehavior", "UnloadLoot: Begin", Logging.White); _States.CurrentUnloadLootState = UnloadLootState.Begin; } _unloadLoot.ProcessState(); if (Settings.Instance.DebugStates) { Logging.Log("DebugBehavior", "UnloadLoot.State is " + _States.CurrentUnloadLootState, Logging.White); } if (_States.CurrentUnloadLootState == UnloadLootState.Done) { Cache.Instance.LootAlreadyUnloaded = true; _States.CurrentUnloadLootState = UnloadLootState.Idle; Cache.Instance.Mission = Cache.Instance.GetAgentMission(AgentID, false); if (_States.CurrentCombatState == CombatState.OutOfAmmo) // on mission { Logging.Log("DebugBehavior.UnloadLoot", "We are out of ammo", Logging.Orange); _States.CurrentDebugBehaviorState = DebugBehaviorState.Idle; return; } _States.CurrentDebugBehaviorState = DebugBehaviorState.Idle; Logging.Log("DebugBehavior.Unloadloot", "CharacterMode: [" + Settings.Instance.CharacterMode + "], AfterMissionSalvaging: [" + Settings.Instance.AfterMissionSalvaging + "], DebugBehaviorState: [" + _States.CurrentDebugBehaviorState + "]", Logging.White); Statistics.Instance.FinishedMission = DateTime.UtcNow; return; } break; case DebugBehaviorState.Traveler: Cache.Instance.OpenWrecks = false; List <int> destination = Cache.Instance.DirectEve.Navigation.GetDestinationPath(); if (destination == null || destination.Count == 0) { // happens if autopilot is not set and this QuestorState is chosen manually // this also happens when we get to destination (!?) Logging.Log("DebugBehavior.Traveler", "No destination?", Logging.White); _States.CurrentDebugBehaviorState = DebugBehaviorState.Error; return; } if (destination.Count == 1 && destination.FirstOrDefault() == 0) { destination[0] = Cache.Instance.DirectEve.Session.SolarSystemId ?? -1; } if (Traveler.Destination == null || Traveler.Destination.SolarSystemId != destination.Last()) { IEnumerable <DirectBookmark> bookmarks = Cache.Instance.AllBookmarks.Where(b => b.LocationId == destination.Last()).ToList(); if (bookmarks != null && bookmarks.Any()) { Traveler.Destination = new BookmarkDestination(bookmarks.OrderBy(b => b.CreatedOn).FirstOrDefault()); } else { Logging.Log("DebugBehavior.Traveler", "Destination: [" + Cache.Instance.DirectEve.Navigation.GetLocation(destination.Last()).Name + "]", Logging.White); Traveler.Destination = new SolarSystemDestination(destination.Last()); } } else { Traveler.ProcessState(); //we also assume you are connected during a manual set of questor into travel mode (safe assumption considering someone is at the kb) Cache.Instance.LastKnownGoodConnectedTime = DateTime.UtcNow; Cache.Instance.MyWalletBalance = Cache.Instance.DirectEve.Me.Wealth; if (_States.CurrentTravelerState == TravelerState.AtDestination) { if (_States.CurrentCombatMissionCtrlState == CombatMissionCtrlState.Error) { Logging.Log("DebugBehavior.Traveler", "an error has occurred", Logging.White); _States.CurrentDebugBehaviorState = DebugBehaviorState.Error; return; } else if (Cache.Instance.InSpace) { Logging.Log("DebugBehavior.Traveler", "Arrived at destination (in space, Questor stopped)", Logging.White); _States.CurrentDebugBehaviorState = DebugBehaviorState.Error; return; } else { Logging.Log("DebugBehavior.Traveler", "Arrived at destination", Logging.White); _States.CurrentDebugBehaviorState = DebugBehaviorState.Idle; return; } } } break; case DebugBehaviorState.GotoNearestStation: if (!Cache.Instance.InSpace || Cache.Instance.InWarp) { return; } EntityCache station = null; if (Cache.Instance.Stations != null && Cache.Instance.Stations.Any()) { station = Cache.Instance.Stations.OrderBy(x => x.Distance).FirstOrDefault(); } if (station != null) { if (station.Distance > (int)Distances.WarptoDistance) { if (station.WarpTo()) { Logging.Log("DebugBehavior.GotoNearestStation", "[" + station.Name + "] which is [" + Math.Round(station.Distance / 1000, 0) + "k away]", Logging.White); _States.CurrentDebugBehaviorState = DebugBehaviorState.Idle; break; } break; } else { if (station.Distance < 1900) { if (station.Dock()) { Logging.Log("DebugBehavior.GotoNearestStation", "[" + station.Name + "] which is [" + Math.Round(station.Distance / 1000, 0) + "k away]", Logging.White); } } else { if (Cache.Instance.NextApproachAction < DateTime.UtcNow && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != station.Id)) { Cache.Instance.NextApproachAction = DateTime.UtcNow.AddSeconds(Time.Instance.ApproachDelay_seconds); Logging.Log("DebugBehavior.GotoNearestStation", "Approaching [" + station.Name + "] which is [" + Math.Round(station.Distance / 1000, 0) + "k away]", Logging.White); station.Approach(); } } } } else { _States.CurrentDebugBehaviorState = DebugBehaviorState.Error; //should we goto idle here? } break; case DebugBehaviorState.LogCombatTargets: //combat targets //List<EntityCache> combatentitiesInList = Cache.Instance.Entities.Where(t => t.IsNpc && !t.IsBadIdea && t.CategoryId == (int)CategoryID.Entity && !t.IsContainer && t.Distance < Cache.Instance.MaxRange && !Cache.Instance.IgnoreTargets.Contains(t.Name.Trim())).ToList(); List <EntityCache> combatentitiesInList = Cache.Instance.EntitiesOnGrid.Where(t => t.IsNpc && !t.IsBadIdea && t.CategoryId == (int)CategoryID.Entity && !t.IsContainer).ToList(); Statistics.EntityStatistics(combatentitiesInList); Cache.Instance.Paused = true; break; case DebugBehaviorState.LogDroneTargets: //drone targets List <EntityCache> droneentitiesInList = Cache.Instance.EntitiesOnGrid.Where(e => e.IsNpc && !e.IsBadIdea && e.CategoryId == (int)CategoryID.Entity && !e.IsContainer && !e.IsSentry && !e.IsLargeCollidable).ToList(); Statistics.EntityStatistics(droneentitiesInList); Cache.Instance.Paused = true; break; case DebugBehaviorState.LogStationEntities: //stations List <EntityCache> stationsInList = Cache.Instance.Entities.Where(e => !e.IsSentry && e.GroupId == (int)Group.Station).ToList(); Statistics.EntityStatistics(stationsInList); Cache.Instance.Paused = true; break; case DebugBehaviorState.LogStargateEntities: //stargates List <EntityCache> stargatesInList = Cache.Instance.Entities.Where(e => !e.IsSentry && e.GroupId == (int)Group.Stargate).ToList(); Statistics.EntityStatistics(stargatesInList); Cache.Instance.Paused = true; break; case DebugBehaviorState.LogAsteroidBelts: //Asteroid Belts List <EntityCache> asteroidbeltsInList = Cache.Instance.Entities.Where(e => !e.IsSentry && e.GroupId == (int)Group.AsteroidBelt).ToList(); Statistics.EntityStatistics(asteroidbeltsInList); Cache.Instance.Paused = true; break; case DebugBehaviorState.LogCansAndWrecks: //Asteroid Belts List <EntityCache> cansandWrecksInList = Cache.Instance.EntitiesOnGrid.Where(e => !e.IsSentry && e.GroupId == (int)Group.CargoContainer && e.GroupId == (int)Group.Wreck).ToList(); Statistics.EntityStatistics(cansandWrecksInList); Cache.Instance.Paused = true; break; case DebugBehaviorState.Default: _States.CurrentDebugBehaviorState = DebugBehaviorState.Idle; break; } }