private void RecallDronesTest() { _state = TestState.Idle; if (!_directEve.Session.IsInSpace) { Log("Can't perform RecallDronesTest, not in space"); return; } if (_directEve.ActiveDrones.Count == 0) { Log("Can't recall drones, no drones in space"); return; } _directEve.ExecuteCommand(DirectCmd.CmdDronesReturnToBay); }
private void OnFrame(object sender, EventArgs e) { if (State == ValueDumpState.Idle) { return; } var hangar = DirectEve.GetItemHangar(); var sellWindow = DirectEve.Windows.OfType <DirectMarketActionWindow>().FirstOrDefault(w => w.IsSellAction); switch (State) { case ValueDumpState.GetItems: if (hangar.Window == null) { // No, command it to open if (DateTime.Now.Subtract(_lastExecute).TotalSeconds > 5) { Log("Opening hangar"); DirectEve.ExecuteCommand(DirectCmd.OpenHangarFloor); _lastExecute = DateTime.Now; } return; } if (!hangar.IsReady) { return; } Log("Loading hangar items"); // Clear out the old Items.Clear(); var hangarItems = hangar.Items; if (hangarItems != null) { Items.AddRange(hangarItems.Where(i => i.ItemId > 0 && i.MarketGroupId.HasValue && i.Quantity > 0).Select(i => new ItemCache(i))); } State = ValueDumpState.UpdatePrices; break; case ValueDumpState.UpdatePrices: foreach (var item in Items) { InvType invType; if (!InvTypesById.TryGetValue(item.TypeId, out invType)) { Log("Unknown TypeId " + _currentItem.TypeId + " for " + _currentItem.Name); continue; } item.InvType = invType; } State = ValueDumpState.Idle; if (cbxSell.Checked) { // Copy the items to sell list ItemsToSell.Clear(); if (cbxUndersell.Checked) { ItemsToSell.AddRange(Items.Where(i => i.InvType != null)); } else { ItemsToSell.AddRange(Items.Where(i => i.InvType != null && i.InvType.MedianBuy.HasValue)); } State = ValueDumpState.NextItem; } break; case ValueDumpState.NextItem: if (ItemsToSell.Count == 0) { State = ValueDumpState.Idle; break; } Log(ItemsToSell.Count + " items left to sell"); _currentItem = ItemsToSell[0]; ItemsToSell.RemoveAt(0); // Dont sell containers if (_currentItem.GroupId == 448) { Log("Skipping " + _currentItem.Name); break; } State = ValueDumpState.StartQuickSell; break; case ValueDumpState.StartQuickSell: if (DateTime.Now.Subtract(_lastExecute).TotalSeconds < 1) { break; } _lastExecute = DateTime.Now; var directItem = hangar.Items.FirstOrDefault(i => i.ItemId == _currentItem.Id); if (directItem == null) { Log("Item " + _currentItem.Name + " no longer exists in the hanger"); break; } // Update Quantity _currentItem.QuantitySold = _currentItem.Quantity - (directItem.Quantity ?? _currentItem.Quantity); Log("Starting QuickSell for " + _currentItem.Name); if (!directItem.QuickSell()) { _lastExecute = DateTime.Now.AddSeconds(-5); Log("QuickSell failed for " + _currentItem.Name + ", retrying in 5 seconds"); break; } State = ValueDumpState.WaitForSellWindow; break; case ValueDumpState.WaitForSellWindow: if (sellWindow == null || !sellWindow.IsReady || sellWindow.Item.ItemId != _currentItem.Id) { break; } // Mark as new execution _lastExecute = DateTime.Now; Log("Inspecting sell order for " + _currentItem.Name); State = ValueDumpState.InspectOrder; break; case ValueDumpState.InspectOrder: // Let the order window stay open for 2 seconds if (DateTime.Now.Subtract(_lastExecute).TotalSeconds < 2) { break; } if (!sellWindow.OrderId.HasValue || !sellWindow.Price.HasValue || !sellWindow.RemainingVolume.HasValue) { Log("No order available for " + _currentItem.Name); sellWindow.Cancel(); State = ValueDumpState.WaitingToFinishQuickSell; break; } var price = sellWindow.Price.Value; if (!cbxUndersell.Checked) { if (!_currentItem.InvType.MedianBuy.HasValue) { Log("No historical price available for " + _currentItem.Name); sellWindow.Cancel(); State = ValueDumpState.WaitingToFinishQuickSell; break; } var perc = price / _currentItem.InvType.MedianBuy.Value; var total = _currentItem.InvType.MedianBuy.Value * _currentItem.Quantity; // If percentage < 85% and total price > 1m isk then skip this item (we don't undersell) if (perc < 0.85 && total > 1000000) { Log("Not underselling item " + _currentItem.Name + " [" + _currentItem.InvType.MedianBuy.Value.ToString("#,##0.00") + "][" + price.ToString("#,##0.00") + "][" + perc.ToString("0%") + "]"); sellWindow.Cancel(); State = ValueDumpState.WaitingToFinishQuickSell; break; } } var quantity = (int)Math.Min(_currentItem.Quantity - _currentItem.QuantitySold, sellWindow.RemainingVolume.Value); // Update quantity sold _currentItem.QuantitySold += quantity; // Update station price if (!_currentItem.StationBuy.HasValue) { _currentItem.StationBuy = price; } _currentItem.StationBuy = (_currentItem.StationBuy + price) / 2; Log("Selling " + quantity + " of " + _currentItem.Name + " for " + (price * quantity).ToString("#,##0.00")); sellWindow.Accept(); // Requeue to check again if (_currentItem.QuantitySold < _currentItem.Quantity) { ItemsToSell.Add(_currentItem); } _lastExecute = DateTime.Now; State = ValueDumpState.WaitingToFinishQuickSell; break; case ValueDumpState.WaitingToFinishQuickSell: if (sellWindow == null || !sellWindow.IsReady || sellWindow.Item.ItemId != _currentItem.Id) { var modal = DirectEve.Windows.FirstOrDefault(w => w.IsModal); if (modal != null) { modal.Close(); } State = ValueDumpState.NextItem; break; } break; } }
private void OnFrame(object sender, EventArgs e) { if (State == ValueDumpState.Idle) { return; } var marketWindow = DirectEve.Windows.OfType <DirectMarketWindow>().FirstOrDefault(); var hangar = DirectEve.GetItemHangar(); var sellWindow = DirectEve.Windows.OfType <DirectMarketActionWindow>().FirstOrDefault(w => w.IsSellAction); var reprorcessingWindow = DirectEve.Windows.OfType <DirectReprocessingWindow>().FirstOrDefault(); switch (State) { case ValueDumpState.CheckMineralPrices: if (RefineCheckBox.Checked) { _currentMineral = InvTypesById.Values.FirstOrDefault(i => i.ReprocessValue.HasValue && i.LastUpdate < DateTime.Now.AddDays(-7)); } else { _currentMineral = InvTypesById.Values.FirstOrDefault(i => i.Id != 27029 && i.GroupId == 18 && i.LastUpdate < DateTime.Now.AddHours(-4)); } //_currentMineral = InvTypesById.Values.FirstOrDefault(i => i.Id != 27029 && i.GroupId == 18 && i.LastUpdate < DateTime.Now.AddMinutes(-1)); //_currentMineral = InvTypesById.Values.FirstOrDefault(i => i.Id == 20236 && i.LastUpdate < DateTime.Now.AddMinutes(-1)); if (_currentMineral == null) { if (DateTime.Now.Subtract(_lastExecute).TotalSeconds > _delay) { State = ValueDumpState.SaveMineralPrices; if (marketWindow != null) { marketWindow.Close(); } } } else { //State = ValueDumpState.GetMineralPrice; if (marketWindow == null) { if (DateTime.Now.Subtract(_lastExecute).TotalSeconds > _delay) { DirectEve.ExecuteCommand(DirectCmd.OpenMarket); _lastExecute = DateTime.Now; } return; } if (!marketWindow.IsReady) { return; } if (marketWindow.DetailTypeId != _currentMineral.Id) { if (DateTime.Now.Subtract(_lastExecute).TotalSeconds < _delay) { return; } Log("Loading orders for " + _currentMineral.Name); marketWindow.LoadTypeId(_currentMineral.Id); _lastExecute = DateTime.Now; return; } if (!marketWindow.BuyOrders.Any(o => o.StationId == DirectEve.Session.StationId)) { _currentMineral.LastUpdate = DateTime.Now; Log("No buy orders found for " + _currentMineral.Name); State = ValueDumpState.CheckMineralPrices; } // Take top 5 orders, average the buy price and consider that median-buy (it's not really median buy but its what we want) //_currentMineral.MedianBuy = marketWindow.BuyOrders.Where(o => o.StationId == DirectEve.Session.StationId).OrderByDescending(o => o.Price).Take(5).Average(o => o.Price); // Take top 1% orders and count median-buy price (no botter covers more than 1% Jita orders anyway) var orders = marketWindow.BuyOrders.Where(o => o.StationId == DirectEve.Session.StationId && o.MinimumVolume == 1).OrderByDescending(o => o.Price).ToList(); var totalAmount = orders.Sum(o => (double)o.VolumeRemaining); double amount = 0, value = 0, count = 0; for (var i = 0; i < orders.Count(); i++) { amount += orders[i].VolumeRemaining; value += orders[i].VolumeRemaining * orders[i].Price; count++; //Log(_currentMineral.Name + " " + count + ": " + orders[i].VolumeRemaining.ToString("#,##0") + " items @ " + orders[i].Price); if (amount / totalAmount > 0.01) { break; } } _currentMineral.MedianBuy = value / amount; Log("Average buy price for " + _currentMineral.Name + " is " + _currentMineral.MedianBuy.Value.ToString("#,##0.00") + " (" + count + " / " + orders.Count() + " orders, " + amount.ToString("#,##0") + " / " + totalAmount.ToString("#,##0") + " items)"); if (!marketWindow.SellOrders.Any(o => o.StationId == DirectEve.Session.StationId)) { _currentMineral.LastUpdate = DateTime.Now; Log("No sell orders found for " + _currentMineral.Name); State = ValueDumpState.CheckMineralPrices; } // Take top 1% orders and count median-sell price orders = marketWindow.SellOrders.Where(o => o.StationId == DirectEve.Session.StationId).OrderBy(o => o.Price).ToList(); totalAmount = orders.Sum(o => (double)o.VolumeRemaining); amount = 0; value = 0; count = 0; for (var i = 0; i < orders.Count(); i++) { amount += orders[i].VolumeRemaining; value += orders[i].VolumeRemaining * orders[i].Price; count++; //Log(_currentMineral.Name + " " + count + ": " + orders[i].VolumeRemaining.ToString("#,##0") + " items @ " + orders[i].Price); if (amount / totalAmount > 0.01) { break; } } _currentMineral.MedianSell = value / amount - 0.01; Log("Average sell price for " + _currentMineral.Name + " is " + _currentMineral.MedianSell.Value.ToString("#,##0.00") + " (" + count + " / " + orders.Count() + " orders, " + amount.ToString("#,##0") + " / " + totalAmount.ToString("#,##0") + " items)"); if (_currentMineral.MedianSell.HasValue && !double.IsNaN(_currentMineral.MedianSell.Value)) { _currentMineral.MedianAll = _currentMineral.MedianSell; } else if (_currentMineral.MedianBuy.HasValue && !double.IsNaN(_currentMineral.MedianBuy.Value)) { _currentMineral.MedianAll = _currentMineral.MedianBuy; } _currentMineral.LastUpdate = DateTime.Now; //State = ValueDumpState.CheckMineralPrices; } break; case ValueDumpState.GetMineralPrice: break; case ValueDumpState.SaveMineralPrices: Log("Updating reprocess prices"); // a quick price check table var MineralPrices = new Dictionary <string, double>(); foreach (var i in InvTypesById.Values) { if (InvType.Minerals.Contains(i.Name)) #if manual { MineralPrices.Add(i.Name, i.MedianSell ?? 0); } } #else { MineralPrices.Add(i.Name, i.MedianBuy ?? 0); } #endif double temp; foreach (var i in InvTypesById.Values) { temp = 0; foreach (var m in InvType.Minerals) { if (i.Reprocess[m].HasValue && i.Reprocess[m] > 0) { temp += i.Reprocess[m].Value * MineralPrices[m]; } } if (temp > 0) { i.ReprocessValue = temp; } else { i.ReprocessValue = null; } } Log("Saving InvTypes.xml"); var xdoc = new XDocument(new XElement("invtypes")); foreach (var type in InvTypesById.Values.OrderBy(i => i.Id)) { xdoc.Root.Add(type.Save()); } xdoc.Save(InvTypesPath); State = ValueDumpState.Idle; break; case ValueDumpState.GetItems: if (hangar.Window == null) { // No, command it to open if (DateTime.Now.Subtract(_lastExecute).TotalSeconds > _delay) { Log("Opening hangar"); DirectEve.ExecuteCommand(DirectCmd.OpenHangarFloor); _lastExecute = DateTime.Now; } return; } if (!hangar.IsReady) { return; } Log("Loading hangar items"); // Clear out the old Items.Clear(); var hangarItems = hangar.Items; if (hangarItems != null) { Items.AddRange(hangarItems.Where(i => i.ItemId > 0 && i.Quantity > 0).Select(i => new ItemCache(i, RefineCheckBox.Checked))); } State = ValueDumpState.UpdatePrices; break; case ValueDumpState.UpdatePrices: bool updated = false; foreach (var item in Items) { InvType invType; if (!InvTypesById.TryGetValue(item.TypeId, out invType)) { Log("Unknown TypeId " + item.TypeId + " for " + item.Name + ", adding to the list"); invType = new InvType(item); InvTypesById.Add(item.TypeId, invType); updated = true; continue; } item.InvType = invType; bool updItem = false; foreach (var material in item.RefineOutput) { if (!InvTypesById.TryGetValue(material.TypeId, out invType)) { Log("Unknown TypeId " + material.TypeId + " for " + material.Name); continue; } material.InvType = invType; var matsPerItem = (double)material.Quantity / item.PortionSize; var exists = InvTypesById[(int)item.TypeId].Reprocess[material.Name].HasValue; if ((!exists && matsPerItem > 0) || (exists && InvTypesById[(int)item.TypeId].Reprocess[material.Name] != matsPerItem)) { if (exists) { Log("[" + item.Name + "][" + material.Name + "] old value: [" + InvTypesById[(int)item.TypeId].Reprocess[material.Name] + ", new value: [" + matsPerItem + "]"); } InvTypesById[(int)item.TypeId].Reprocess[material.Name] = matsPerItem; updItem = true; } } if (updItem) { Log("Updated [" + item.Name + "] refine materials"); } updated |= updItem; } if (updated) { State = ValueDumpState.SaveMineralPrices; } else { State = ValueDumpState.Idle; } if (cbxSell.Checked) { // Copy the items to sell list ItemsToSell.Clear(); ItemsToRefine.Clear(); if (cbxUndersell.Checked) #if manual { ItemsToSell.AddRange(Items.Where(i => i.InvType != null && i.MarketGroupId > 0)); } #else { ItemsToSell.AddRange(Items.Where(i => i.InvType != null && i.MarketGroupId > 0)); } #endif else #if manual { ItemsToSell.AddRange(Items.Where(i => i.InvType != null && i.MarketGroupId > 0 && i.InvType.MedianBuy.HasValue)); } #else { ItemsToSell.AddRange(Items.Where(i => i.InvType != null && i.MarketGroupId > 0 && i.InvType.MedianBuy.HasValue)); } #endif State = ValueDumpState.NextItem; } break;
private void OnFrame(object sender, EventArgs e) { if (State == ValueDumpState.Idle) { return; } var marketWindow = DirectEve.Windows.OfType <DirectMarketWindow>().FirstOrDefault(); var hangar = DirectEve.GetItemHangar(); var sellWindow = DirectEve.Windows.OfType <DirectMarketActionWindow>().FirstOrDefault(w => w.IsSellAction); var reprorcessingWindow = DirectEve.Windows.OfType <DirectReprocessingWindow>().FirstOrDefault(); switch (State) { case ValueDumpState.CheckMineralPrices: _currentMineral = InvTypesById.Values.FirstOrDefault(i => i.Id != 27029 && i.GroupId == 18 && i.LastUpdate < DateTime.Now.AddHours(-4)); if (_currentMineral == null) { if (DateTime.Now.Subtract(_lastExecute).TotalSeconds > 5) { State = ValueDumpState.SaveMineralPrices; if (marketWindow != null) { marketWindow.Close(); } } } else { State = ValueDumpState.GetMineralPrice; } break; case ValueDumpState.GetMineralPrice: if (marketWindow == null) { if (DateTime.Now.Subtract(_lastExecute).TotalSeconds > 5) { DirectEve.ExecuteCommand(DirectCmd.OpenMarket); _lastExecute = DateTime.Now; } return; } if (marketWindow.DetailTypeId != _currentMineral.Id) { if (DateTime.Now.Subtract(_lastExecute).TotalSeconds < 5) { return; } Log("Loading orders for " + _currentMineral.Name); marketWindow.LoadTypeId(_currentMineral.Id); _lastExecute = DateTime.Now; return; } if (!marketWindow.BuyOrders.Any(o => o.StationId == DirectEve.Session.StationId)) { _currentMineral.LastUpdate = DateTime.Now; Log("No orders found for " + _currentMineral.Name); State = ValueDumpState.CheckMineralPrices; } // Take top 5 orders, average the buy price and consider that median-buy (it's not really median buy but its what we want) _currentMineral.MedianBuy = marketWindow.BuyOrders.Where(o => o.StationId == DirectEve.Session.StationId).OrderByDescending(o => o.Price).Take(5).Average(o => o.Price); _currentMineral.LastUpdate = DateTime.Now; State = ValueDumpState.CheckMineralPrices; Log("Average price for " + _currentMineral.Name + " is " + _currentMineral.MedianBuy.Value.ToString("#,##0.00")); break; case ValueDumpState.SaveMineralPrices: Log("Saving InvItems.xml"); var xdoc = new XDocument(new XElement("invtypes")); foreach (var type in InvTypesById.Values.OrderBy(i => i.Id)) { xdoc.Root.Add(type.Save()); } xdoc.Save(InvTypesPath); State = ValueDumpState.Idle; break; case ValueDumpState.GetItems: if (hangar.Window == null) { // No, command it to open if (DateTime.Now.Subtract(_lastExecute).TotalSeconds > 5) { Log("Opening hangar"); DirectEve.ExecuteCommand(DirectCmd.OpenHangarFloor); _lastExecute = DateTime.Now; } return; } if (!hangar.IsReady) { return; } Log("Loading hangar items"); // Clear out the old Items.Clear(); var hangarItems = hangar.Items; if (hangarItems != null) { Items.AddRange(hangarItems.Where(i => i.ItemId > 0 && i.MarketGroupId > 0 && i.Quantity > 0).Select(i => new ItemCache(i, RefineCheckBox.Checked))); } State = ValueDumpState.UpdatePrices; break; case ValueDumpState.UpdatePrices: foreach (var item in Items) { InvType invType; if (!InvTypesById.TryGetValue(item.TypeId, out invType)) { Log("Unknown TypeId " + item.TypeId + " for " + item.Name); continue; } item.InvType = invType; foreach (var material in item.RefineOutput) { if (!InvTypesById.TryGetValue(material.TypeId, out invType)) { Log("Unknown TypeId " + material.TypeId + " for " + material.Name); continue; } material.InvType = invType; } } State = ValueDumpState.Idle; if (cbxSell.Checked) { // Copy the items to sell list ItemsToSell.Clear(); ItemsToRefine.Clear(); if (cbxUndersell.Checked) { ItemsToSell.AddRange(Items.Where(i => i.InvType != null)); } else { ItemsToSell.AddRange(Items.Where(i => i.InvType != null && i.InvType.MedianBuy.HasValue)); } State = ValueDumpState.NextItem; } break; case ValueDumpState.NextItem: if (ItemsToSell.Count == 0) { if (ItemsToRefine.Count != 0) { State = ValueDumpState.RefineItems; } else { State = ValueDumpState.Idle; } break; } Log(ItemsToSell.Count + " items left to sell"); _currentItem = ItemsToSell[0]; ItemsToSell.RemoveAt(0); // Dont sell containers if (_currentItem.GroupId == 448) { Log("Skipping " + _currentItem.Name); break; } State = ValueDumpState.StartQuickSell; break; case ValueDumpState.StartQuickSell: if (DateTime.Now.Subtract(_lastExecute).TotalSeconds < 1) { break; } _lastExecute = DateTime.Now; var directItem = hangar.Items.FirstOrDefault(i => i.ItemId == _currentItem.Id); if (directItem == null) { Log("Item " + _currentItem.Name + " no longer exists in the hanger"); break; } // Update Quantity _currentItem.QuantitySold = _currentItem.Quantity - directItem.Quantity; Log("Starting QuickSell for " + _currentItem.Name); if (!directItem.QuickSell()) { _lastExecute = DateTime.Now.AddSeconds(-5); Log("QuickSell failed for " + _currentItem.Name + ", retrying in 5 seconds"); break; } State = ValueDumpState.WaitForSellWindow; break; case ValueDumpState.WaitForSellWindow: if (sellWindow == null || !sellWindow.IsReady || sellWindow.Item.ItemId != _currentItem.Id) { break; } // Mark as new execution _lastExecute = DateTime.Now; Log("Inspecting sell order for " + _currentItem.Name); State = ValueDumpState.InspectOrder; break; case ValueDumpState.InspectOrder: // Let the order window stay open for 2 seconds if (DateTime.Now.Subtract(_lastExecute).TotalSeconds < 2) { break; } if (!sellWindow.OrderId.HasValue || !sellWindow.Price.HasValue || !sellWindow.RemainingVolume.HasValue) { Log("No order available for " + _currentItem.Name); sellWindow.Cancel(); State = ValueDumpState.WaitingToFinishQuickSell; break; } var price = sellWindow.Price.Value; var quantity = (int)Math.Min(_currentItem.Quantity - _currentItem.QuantitySold, sellWindow.RemainingVolume.Value); var totalPrice = quantity * price; string otherPrices = " "; if (_currentItem.InvType.MedianBuy.HasValue) { otherPrices += "[Median buy price: " + (_currentItem.InvType.MedianBuy.Value * quantity).ToString("#,##0.00") + "]"; } else { otherPrices += "[No median buy price]"; } if (RefineCheckBox.Checked) { var portions = quantity / _currentItem.PortionSize; var refinePrice = _currentItem.RefineOutput.Any() ? _currentItem.RefineOutput.Sum(m => m.Quantity * m.InvType.MedianBuy ?? 0) * portions : 0; refinePrice *= (double)RefineEfficiencyInput.Value / 100; otherPrices += "[Refine price: " + refinePrice.ToString("#,##0.00") + "]"; if (refinePrice > totalPrice) { Log("Refining gives a better price for item " + _currentItem.Name + " [Refine price: " + refinePrice.ToString("#,##0.00") + "][Sell price: " + totalPrice.ToString("#,##0.00") + "]"); // Add it to the refine list ItemsToRefine.Add(_currentItem); sellWindow.Cancel(); State = ValueDumpState.WaitingToFinishQuickSell; break; } } if (!cbxUndersell.Checked) { if (!_currentItem.InvType.MedianBuy.HasValue) { Log("No historical price available for " + _currentItem.Name); sellWindow.Cancel(); State = ValueDumpState.WaitingToFinishQuickSell; break; } var perc = price / _currentItem.InvType.MedianBuy.Value; var total = _currentItem.InvType.MedianBuy.Value * _currentItem.Quantity; // If percentage < 85% and total price > 1m isk then skip this item (we don't undersell) if (perc < 0.85 && total > 1000000) { Log("Not underselling item " + _currentItem.Name + " [Median buy price: " + _currentItem.InvType.MedianBuy.Value.ToString("#,##0.00") + "][Sell price: " + price.ToString("#,##0.00") + "][" + perc.ToString("0%") + "]"); sellWindow.Cancel(); State = ValueDumpState.WaitingToFinishQuickSell; break; } } // Update quantity sold _currentItem.QuantitySold += quantity; // Update station price if (!_currentItem.StationBuy.HasValue) { _currentItem.StationBuy = price; } _currentItem.StationBuy = (_currentItem.StationBuy + price) / 2; Log("Selling " + quantity + " of " + _currentItem.Name + " [Sell price: " + (price * quantity).ToString("#,##0.00") + "]" + otherPrices); sellWindow.Accept(); // Requeue to check again if (_currentItem.QuantitySold < _currentItem.Quantity) { ItemsToSell.Add(_currentItem); } _lastExecute = DateTime.Now; State = ValueDumpState.WaitingToFinishQuickSell; break; case ValueDumpState.WaitingToFinishQuickSell: if (sellWindow == null || !sellWindow.IsReady || sellWindow.Item.ItemId != _currentItem.Id) { var modal = DirectEve.Windows.FirstOrDefault(w => w.IsModal); if (modal != null) { modal.Close(); } State = ValueDumpState.NextItem; break; } break; case ValueDumpState.RefineItems: if (reprorcessingWindow == null) { if (DateTime.Now.Subtract(_lastExecute).TotalSeconds > 5) { var refineItems = hangar.Items.Where(i => ItemsToRefine.Any(r => r.Id == i.ItemId)); DirectEve.ReprocessStationItems(refineItems); _lastExecute = DateTime.Now; } return; } if (reprorcessingWindow.NeedsQuote) { if (DateTime.Now.Subtract(_lastExecute).TotalSeconds > 5) { reprorcessingWindow.GetQuotes(); _lastExecute = DateTime.Now; } return; } // Wait till we have a quote if (reprorcessingWindow.Quotes.Count == 0) { _lastExecute = DateTime.Now; return; } // Wait another 5 seconds to view the quote and then reprocess the stuff if (DateTime.Now.Subtract(_lastExecute).TotalSeconds > 5) { // TODO: We should wait for the items to appear in our hangar and then sell them... reprorcessingWindow.Reprocess(); State = ValueDumpState.Idle; } break; } }
/// <summary> /// Check if we have kernite in station /// </summary> /// <returns></returns> public StorylineState PreAcceptMission(Storyline storyline) { DirectEve directEve = Cache.Instance.DirectEve; if (_nextAction > DateTime.UtcNow) { return(StorylineState.PreAcceptMission); } // the ore and ore quantity can be stored in the characters settings xml this is to facility mission levels other than 4. //The defaults are for level 4 so it will not break for those people that do not include these in their settings file // Level 1 <MaterialsForWarOreID>1230</MaterialsForWarOreID> // <MaterialsForWarOreQty>999</MaterialsForWarOreQty> // Level 4 <MaterialsForWarOreID>20</MaterialsForWarOreID> // <MaterialsForWarOreQty>8000</MaterialsForWarOreQty> int oreid = Settings.Instance.MaterialsForWarOreID; //1230; int orequantity = Settings.Instance.MaterialsForWarOreQty; //999 // Open the item hangar if (Cache.Instance.ItemHangar == null) { return(StorylineState.PreAcceptMission); } //if (Cache.Instance.ItemHangar.Window == null) //{ // Logging.Log("MaterialsForWar", "PreAcceptMission: ItemHangar is null", Logging.Orange); // if (!Cache.Instance.ReadyItemsHangar("MaterialsForWarPreparation")) return StorylineState.PreAcceptMission; // return StorylineState.PreAcceptMission; //} // Is there a market window? DirectMarketWindow marketWindow = directEve.Windows.OfType <DirectMarketWindow>().FirstOrDefault(); // Do we have the ore we need in the Item Hangar?. if (Cache.Instance.ItemHangar.Items.Where(i => i.TypeId == oreid).Sum(i => i.Quantity) >= orequantity) { DirectItem thisOreInhangar = Cache.Instance.ItemHangar.Items.FirstOrDefault(i => i.TypeId == oreid); if (thisOreInhangar != null) { Logging.Log("MaterialsForWarPreparation", "We have [" + Cache.Instance.ItemHangar.Items.Where(i => i.TypeId == oreid).Sum(i => i.Quantity).ToString(CultureInfo.InvariantCulture) + "] " + thisOreInhangar.TypeName + " in the item hangar accepting mission", Logging.White); } // Close the market window if there is one if (marketWindow != null) { marketWindow.Close(); } return(StorylineState.AcceptMission); } if (Cache.Instance.CurrentShipsCargo == null) { return(StorylineState.PreAcceptMission); } if (Cache.Instance.CurrentShipsCargo.Items.Where(i => i.TypeId == oreid).Sum(i => i.Quantity) >= orequantity) { DirectItem thisOreInhangar = Cache.Instance.CurrentShipsCargo.Items.FirstOrDefault(i => i.TypeId == oreid); if (thisOreInhangar != null) { Logging.Log("MaterialsForWarPreparation", "We have [" + Cache.Instance.CurrentShipsCargo.Items.Where(i => i.TypeId == oreid).Sum(i => i.Quantity).ToString(CultureInfo.InvariantCulture) + "] " + thisOreInhangar.TypeName + " in the CargoHold accepting mission", Logging.White); } // Close the market window if there is one if (marketWindow != null) { marketWindow.Close(); } return(StorylineState.AcceptMission); } if (Cache.Instance.DirectEve.HasSupportInstances()) { // We do not have enough ore, open the market window if (marketWindow == null) { _nextAction = DateTime.UtcNow.AddSeconds(10); Logging.Log("MaterialsForWarPreparation", "Opening market window", Logging.White); directEve.ExecuteCommand(DirectCmd.OpenMarket); return(StorylineState.PreAcceptMission); } // Wait for the window to become ready (this includes loading the ore info) if (!marketWindow.IsReady) { return(StorylineState.PreAcceptMission); } // Are we currently viewing ore orders? if (marketWindow.DetailTypeId != oreid) { // No, load the ore orders marketWindow.LoadTypeId(oreid); Logging.Log("MaterialsForWarPreparation", "Loading market window", Logging.White); _nextAction = DateTime.UtcNow.AddSeconds(5); return(StorylineState.PreAcceptMission); } // Get the median sell price InvType type = Cache.Instance.InvTypesById[20]; double? maxPrice = type.MedianSell * 4; // Do we have orders that sell enough ore for the mission? IEnumerable <DirectOrder> orders = marketWindow.SellOrders.Where(o => o.StationId == directEve.Session.StationId && o.Price < maxPrice).ToList(); if (!orders.Any() || orders.Sum(o => o.VolumeRemaining) < orequantity) { Logging.Log("MaterialsForWarPreparation", "Not enough (reasonably priced) ore available! Blacklisting agent for this Questor session!", Logging.Orange); // Close the market window marketWindow.Close(); // No, black list the agent in this Questor session (note we will never decline storylines!) return(StorylineState.BlacklistAgent); } // How much ore do we still need? int neededQuantity = orequantity - Cache.Instance.ItemHangar.Items.Where(i => i.TypeId == oreid).Sum(i => i.Quantity); if (neededQuantity > 0) { // Get the first order DirectOrder order = orders.OrderBy(o => o.Price).FirstOrDefault(); if (order != null) { // Calculate how much ore we still need int remaining = Math.Min(neededQuantity, order.VolumeRemaining); order.Buy(remaining, DirectOrderRange.Station); Logging.Log("MaterialsForWarPreparation", "Buying [" + remaining + "] ore", Logging.White); // Wait for the order to go through _nextAction = DateTime.UtcNow.AddSeconds(10); } } return(StorylineState.PreAcceptMission); } Logging.Log("MaterialsForWarPreparation", "No DirectEVE Instances Available: free version detected. Buy/Sell support not available. Blacklisting agent for this Questor session!", Logging.Orange); // Close the market window if (marketWindow != null) { marketWindow.Close(); } // No, black list the agent in this Questor session (note we will never decline storylines!) return(StorylineState.BlacklistAgent); }
private static void OnFrame(object sender, EventArgs eventArgs) { if (_done) { return; } // Wait for the next action if (_nextAction >= DateTime.Now) { return; } var hangar = _directEve.GetItemHangar(); if (!hangar.IsReady) { _nextAction = DateTime.Now.AddMilliseconds(WaitMillis); _directEve.ExecuteCommand(DirectCmd.OpenHangarFloor); Log("BuyLPI: Opening item hangar"); return; } var lpstore = _directEve.Windows.OfType <DirectLoyaltyPointStoreWindow>().FirstOrDefault(); if (lpstore == null) { _nextAction = DateTime.Now.AddMilliseconds(WaitMillis); _directEve.ExecuteCommand(DirectCmd.OpenLpstore); Log("BuyLPI: Opening loyalty point store"); return; } // Wait for the amount of LP to change if (_lastLoyaltyPoints == lpstore.LoyaltyPoints) { return; } // Do not expect it to be 0 (probably means its reloading) if (lpstore.LoyaltyPoints == 0) { if (_loyaltyPointTimeout < DateTime.Now) { Log("BuyLPI: It seems we have no loyalty points left"); _done = true; return; } return; } _lastLoyaltyPoints = lpstore.LoyaltyPoints; // Find the offer var offer = lpstore.Offers.FirstOrDefault(o => o.TypeId.ToString() == _type || string.Compare(o.TypeName, _type, true) == 0); if (offer == null) { Log("BuyLPI: Can't find offer with type name/id: {0}!", _type); _done = true; return; } // Check LP if (_lastLoyaltyPoints < offer.LoyaltyPointCost) { Log("BuyLPI: Not enough loyalty points left"); _done = true; return; } // Check ISK if (_directEve.Me.Wealth < offer.IskCost) { Log("BuyLPI: Not enough ISK left"); _done = true; return; } // Check items foreach (var requiredItem in offer.RequiredItems) { var item = hangar.Items.FirstOrDefault(i => i.TypeId == requiredItem.TypeId); if (item == null || item.Quantity < requiredItem.Quantity) { Log("Missing {0}x {1}", requiredItem.Quantity, requiredItem.TypeName); _done = true; return; } } // All passed, accept offer Log("BuyLPI: Accepting {0}", offer.TypeName, "[ ", _quantity.Value, " ] of [ ", _totalquantityoforders.Value, " ] orders"); offer.AcceptOffer(); // Set next action + loyalty point timeout _nextAction = DateTime.Now.AddMilliseconds(WaitMillis); _loyaltyPointTimeout = DateTime.Now.AddSeconds(10); if (_quantity.HasValue) { _quantity = _quantity.Value - 1; if (_quantity.Value <= 0) { Log("Quantity limit reached"); _done = true; return; } } }
static void OnFrame(object sender, EventArgs e) { if (!_readyToStart) { return; } if (_chantlingScheduler && !string.IsNullOrEmpty(_character) && !_readyToStarta) { return; } if (DateTime.Now.Subtract(_lastPulse).TotalSeconds < _pulsedelay) { return; } _lastPulse = DateTime.Now; // If the session is ready, then we are done :) if (_directEve.Session.IsReady) { Logging.Log("[Startup] We've successfully logged in"); _done = true; return; } // We shouldn't get any window if (_directEve.Windows.Count != 0) { foreach (var window in _directEve.Windows) { if (string.IsNullOrEmpty(window.Html)) { continue; } Logging.Log("[Startup] windowtitles:" + window.Name + "::" + window.Html); // // Close these windows and continue // 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(); continue; } // Modal windows must be closed // But lets only close known modal windows if (window.Name == "modal") { bool close = false; bool restart = false; if (!string.IsNullOrEmpty(window.Html)) { // Server going down //Logging.Log("[Startup] (1) close is: " + close); close |= window.Html.Contains("Please make sure your characters are out of harms way"); close |= window.Html.Contains("The socket was closed"); close |= window.Html.Contains("accepting connections"); close |= window.Html.Contains("Could not connect"); close |= window.Html.Contains("The connection to the server was closed"); close |= window.Html.Contains("server was closed"); close |= window.Html.Contains("Unable to connect to the selected server. Please check the address and try again."); close |= window.Html.Contains("make sure your characters are out of harm"); close |= window.Html.Contains("Connection to server lost"); close |= window.Html.Contains("The socket was closed"); close |= window.Html.Contains("The specified proxy or server node"); close |= window.Html.Contains("Starting up"); close |= window.Html.Contains("Unable to connect to the selected server"); close |= window.Html.Contains("Could not connect to the specified address"); close |= window.Html.Contains("Connection Timeout"); close |= window.Html.Contains("The cluster is not currently accepting connections"); close |= window.Html.Contains("Your character is located within"); close |= window.Html.Contains("The transport has not yet been connected"); close |= window.Html.Contains("The user's connection has been usurped"); close |= window.Html.Contains("The EVE cluster has reached its maximum user limit"); close |= window.Html.Contains("The connection to the server was closed"); close |= window.Html.Contains("client is already connecting to the server"); //close |= window.Html.Contains("A client update is available and will now be installed"); // // eventually it would be nice to hit ok on this one and let it update // close |= window.Html.Contains("client update is available and will now be installed"); close |= window.Html.Contains("You are on a <b>14 day trial</b>."); // // these windows require a quit of eve all together // restart |= window.Html.Contains("The connection was closed"); restart |= window.Html.Contains("Connection to server lost."); //INFORMATION restart |= window.Html.Contains("Connection to server lost"); //INFORMATION restart |= window.Html.Contains("Local cache is corrupt"); restart |= window.Html.Contains("Local session information is corrupt"); restart |= window.Html.Contains("The client's local session"); // information is corrupt"); restart |= window.Html.Contains("restart the client prior to logging in"); //Logging.Log("[Startup] (2) close is: " + close); //Logging.Log("[Startup] (1) window.Html is: " + window.Html); _pulsedelay = 60; } if (restart) { Logging.Log("Startup: Restarting eve..."); Logging.Log("Startup: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); _directEve.ExecuteCommand(DirectCmd.CmdQuitGame); continue; } 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(); continue; } } if (string.IsNullOrEmpty(window.Html)) { continue; } if (window.Name == "telecom") { continue; } Logging.Log("[Startup] We've got an unexpected window, auto login halted."); Logging.Log("[Startup] window.Name is: " + window.Name); Logging.Log("[Startup] window.Caption is: " + window.Caption); Logging.Log("[Startup] window.ID is: " + window.Id); Logging.Log("[Startup] window.Html is: " + window.Html); _done = true; return; } return; } if (!string.IsNullOrEmpty(_scriptFile)) { try { // Replace this try block with the following once new DirectEve is pushed // _directEve.RunScript(_scriptFile); System.Reflection.MethodInfo info = _directEve.GetType().GetMethod("RunScript"); if (info == null) { Logging.Log("DirectEve.RunScript() doesn't exist. Upgrade DirectEve.dll!"); } else { Logging.Log(string.Format("Running {0}...", _scriptFile)); info.Invoke(_directEve, new Object[] { _scriptFile }); } } catch (System.Exception ex) { Logging.Log(string.Format("Exception {0}...", ex.ToString())); _done = true; } finally { _scriptFile = null; } return; } if (_directEve.Login.AtLogin) { if (DateTime.Now.Subtract(AppStarted).TotalSeconds > 60) { Logging.Log("[Startup] Login account [" + _username + "]"); _directEve.Login.Login(_username, _password); Logging.Log("[Startup] Waiting for Character Selection Screen"); _pulsedelay = (int)Time.QuestorBeforeLoginPulseDelay_milliseconds; return; } } if (_directEve.Login.AtCharacterSelection && _directEve.Login.IsCharacterSelectionReady) { if (DateTime.Now.Subtract(AppStarted).TotalSeconds > 90) { foreach (var slot in _directEve.Login.CharacterSlots) { if (slot.CharId.ToString() != _character && string.Compare(slot.CharName, _character, true) != 0) { continue; } Logging.Log("[Startup] Activating character [" + slot.CharName + "]"); slot.Activate(); return; } Logging.Log("[Startup] Character id/name [" + _character + "] not found, retrying in 10 seconds"); } } }