Beispiel #1
0
        public void ProcessState()
        {
            var invIgnore = XDocument.Load(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\InvIgnore.xml"); //items to ignore
            var marketWindow = DirectEve.Instance.Windows.OfType<DirectMarketWindow>().FirstOrDefault();
            var hangar = DirectEve.Instance.GetItemHangar();
            var sellWindow = DirectEve.Instance.Windows.OfType<DirectMarketActionWindow>().FirstOrDefault(w => w.IsSellAction);
            var reprorcessingWindow = DirectEve.Instance.Windows.OfType<DirectReprocessingWindow>().FirstOrDefault();
            bool block;

            int random_number = ramdom.Next(2, 4);

            switch (State)
            {

                case ValueDumpState.Idle:
                case ValueDumpState.Done:
                    break;

                case ValueDumpState.Begin:
                    if(_form.RefineCheckBox.Checked && _form.cbxSell.Checked)
                    {
                        _form.cbxSell.Checked = false;
                        value_process = true;
                        State = ValueDumpState.GetItems;
                    }
                    else if(_form.RefineCheckBox.Checked && value_process)
                    {
                        _form.RefineCheckBox.Checked = false;
                        _form.cbxSell.Checked = true;
                        value_process = false;
                        State = ValueDumpState.GetItems;
                    }
                    else
                        State = ValueDumpState.GetItems;
                    break;

                case ValueDumpState.CheckMineralPrices:
                    _currentMineral = _form.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.Instance.ExecuteCommand(DirectCmd.OpenMarket);
                            _lastExecute = DateTime.Now;
                        }

                        return;
                    }

                    if (marketWindow.DetailTypeId != _currentMineral.Id)
                    {
                        if (DateTime.Now.Subtract(_lastExecute).TotalSeconds < 5)
                            return;

                        Logging.Log("ValueDump: Loading orders for " + _currentMineral.Name);

                        marketWindow.LoadTypeId(_currentMineral.Id);
                        _lastExecute = DateTime.Now;
                        return;
                    }

                    if (!marketWindow.BuyOrders.Any(o => o.StationId == DirectEve.Instance.Session.StationId))
                    {
                        _currentMineral.LastUpdate = DateTime.Now;

                        Logging.Log("ValueDump: 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.Instance.Session.StationId).OrderByDescending(o => o.Price).Take(5).Average(o => o.Price);
                    _currentMineral.LastUpdate = DateTime.Now;
                    State = ValueDumpState.CheckMineralPrices;

                    Logging.Log("ValueDump: Average price for " + _currentMineral.Name + " is " + _currentMineral.MedianBuy.Value.ToString("#,##0.00"));
                    break;

                case ValueDumpState.SaveMineralPrices:
                    Logging.Log("ValueDump: Saving InvItems.xml");

                    var xdoc = new XDocument(new XElement("invtypes"));
                    foreach (var type in _form.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)
                        {
                            Logging.Log("ValueDump: Opening hangar");
                            DirectEve.Instance.ExecuteCommand(DirectCmd.OpenHangarFloor);
                            _lastExecute = DateTime.Now;
                        }

                        return;
                    }

                    if (!hangar.IsReady)
                        return;

                    Logging.Log("ValueDump: Loading hangar items");

                    // Clear out the old
                    _form.Items.Clear();
                    var hangarItems = hangar.Items;
                    if (hangarItems != null)
                        _form.Items.AddRange(hangarItems.Where(i => i.ItemId > 0 && i.MarketGroupId > 0 && i.Quantity > 0).Select(i => new ItemCache(i, _form.RefineCheckBox.Checked)));

                    State = ValueDumpState.UpdatePrices;
                    break;

                case ValueDumpState.UpdatePrices:
                    foreach (var item in _form.Items)
                    {
                        InvType invType;
                        if (!_form.InvTypesById.TryGetValue(item.TypeId, out invType))
                        {
                            Logging.Log("ValueDump: Unknown TypeId " + item.TypeId + " for " + item.Name);
                            continue;
                        }

                        item.InvType = invType;
                        foreach (var material in item.RefineOutput)
                        {
                            if (!_form.InvTypesById.TryGetValue(material.TypeId, out invType))
                            {
                                Logging.Log("ValueDump: Unknown TypeId " + material.TypeId + " for " + material.Name);
                                continue;
                            }

                            material.InvType = invType;
                        }
                    }

                    _form.ItemsToSell.Clear();
                    _form.ItemsToRefine.Clear();
                    _form.ItemsToSell_unsorted.Clear();

                    if (_form.cbxSell.Checked)
                    {

                        if (_form.cbxUndersell.Checked)
                            _form.ItemsToSell_unsorted.AddRange(_form.Items.Where(i => i.InvType != null));
                        else
                            _form.ItemsToSell_unsorted.AddRange(_form.Items.Where(i => i.InvType != null && i.InvType.MinSell.HasValue));

                        _form.ItemsToSell = _form.ItemsToSell_unsorted.OrderBy(i => i.Name).ToList();
                        State = ValueDumpState.NextItem;
                    }
                    else if (_form.RefineCheckBox.Checked)
                    {
                        _form.ItemsToSell_unsorted.AddRange(_form.Items.Where(i => i.InvType != null && i.InvType.MaxBuy.HasValue));
                        _form.ItemsToSell = _form.ItemsToSell_unsorted.OrderBy(i => i.Name).ToList();
                        State = ValueDumpState.NextItem;
                    }
                    else
                        State = ValueDumpState.Done;

                    break;

                case ValueDumpState.NextItem:

                    if (_form.ItemsToSell.Count == 0)
                    {
                        if (_form.ItemsToRefine.Count != 0)
                            State = ValueDumpState.RefineItems;
                        else
                            State = ValueDumpState.Done;
                        break;
                    }
                    block = false;
                    if(!_form.RefineCheckBox.Checked)
                        Logging.Log("ValueDump: " + _form.ItemsToSell.Count + " items left to sell");

                    _currentItem = _form.ItemsToSell[0];
                    _form.ItemsToSell.RemoveAt(0);

                    // Dont sell containers
                    if (_currentItem.GroupId == 448 || _currentItem.GroupId == 649)
                    {
                        Logging.Log("ValueDump: Skipping " + _currentItem.Name);
                        break;
                    }
                    // Dont sell items in invignore.xml
                    foreach (var element in invIgnore.Root.Elements("invtype"))
                    {
                        if (_currentItem.TypeId == (int)element.Attribute("id"))
                        {
                            Logging.Log("ValueDump: Skipping (block list) " + _currentItem.Name);
                            block = true;
                            break;
                        }
                    }
                    if (block)
                        break;

                    State = ValueDumpState.StartQuickSell;
                    break;

                case ValueDumpState.StartQuickSell:
                    if ((DateTime.Now.Subtract(_lastExecute).TotalSeconds < random_number) && _form.cbxSell.Checked)
                        break;
                    _lastExecute = DateTime.Now;

                    var directItem = hangar.Items.FirstOrDefault(i => i.ItemId == _currentItem.Id);
                    if (directItem == null)
                    {
                        Logging.Log("ValueDump: Item " + _currentItem.Name + " no longer exists in the hanger");
                        break;
                    }

                    // Update Quantity
                    _currentItem.QuantitySold = _currentItem.Quantity - directItem.Quantity;

                    if (_form.cbxSell.Checked)
                    {
                        Logging.Log("ValueDump: Starting QuickSell for " + _currentItem.Name);
                        if (!directItem.QuickSell())
                        {
                            _lastExecute = DateTime.Now.AddSeconds(-5);

                            Logging.Log("ValueDump: QuickSell failed for " + _currentItem.Name + ", retrying in 5 seconds");
                            break;
                        }

                        State = ValueDumpState.WaitForSellWindow;
                    }
                    else
                    {
                        State = ValueDumpState.InspectRefinery;
                    }
                    break;

                case ValueDumpState.WaitForSellWindow:
                    if (sellWindow == null || !sellWindow.IsReady || sellWindow.Item.ItemId != _currentItem.Id)
                        break;

                    // Mark as new execution
                    _lastExecute = DateTime.Now;

                    Logging.Log("ValueDump: Inspecting sell order for " + _currentItem.Name);
                    State = ValueDumpState.InspectOrder;
                    break;

                case ValueDumpState.InspectOrder:
                    // Let the order window stay open for random number
                    if (DateTime.Now.Subtract(_lastExecute).TotalSeconds < random_number)
                        break;

                    if (!sellWindow.OrderId.HasValue || !sellWindow.Price.HasValue || !sellWindow.RemainingVolume.HasValue)
                    {
                        Logging.Log("ValueDump: 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 (!_form.cbxUndersell.Checked)
                    {
                        var perc = _currentItem.InvType.MinSell.Value / price;
                        var total = _currentItem.InvType.MinSell.Value * _currentItem.Quantity;
                        // If percentage >= 130% and total price >= 1m isk then skip this item (we don't undersell)
                        if (perc >= 1.4 && ((total-totalPrice) >= 2000000))
                        {
                            Logging.Log("ValueDump: Not underselling item " + _currentItem.Name + " [Min sell price: " + _currentItem.InvType.MinSell.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;

                    Logging.Log("ValueDump: Selling " + quantity + " of " + _currentItem.Name + " [Sell price: " + (price * quantity).ToString("#,##0.00") + "]" + otherPrices);
                    sellWindow.Accept();

                    // Requeue to check again
                    if (_currentItem.QuantitySold < _currentItem.Quantity)
                        _form.ItemsToSell.Add(_currentItem);

                    _lastExecute = DateTime.Now;
                    State = ValueDumpState.WaitingToFinishQuickSell;
                    break;

                case ValueDumpState.InspectRefinery:

                    var price_r = _currentItem.InvType.MaxBuy.Value;
                    var quantity_r = _currentItem.Quantity;
                    var totalPrice_r = quantity_r * price_r;
                    var portions = quantity_r / _currentItem.PortionSize;
                    var refinePrice = _currentItem.RefineOutput.Any() ? _currentItem.RefineOutput.Sum(m => m.Quantity * m.InvType.MaxBuy ?? 0) * portions : 0;
                    refinePrice *= (double)_form.RefineEfficiencyInput.Value / 100;

                    if (refinePrice > totalPrice_r || totalPrice_r <= 1500000)
                    {
                        //Logging.Log("ValueDump: Refining gives a better price for item " + _currentItem.Name + " [Refine price: " + refinePrice.ToString("#,##0.00") + "][Sell price: " + totalPrice_r.ToString("#,##0.00") + "]");
                        // Add it to the refine list
                        _form.ItemsToRefine.Add(_currentItem);
                    }
                    /*else
                    {
                        Logging.Log("Selling gives a better price for item " + _currentItem.Name + " [Refine price: " + refinePrice.ToString("#,##0.00") + "][Sell price: " + totalPrice_r.ToString("#,##0.00") + "]");
                    }*/

                    _lastExecute = DateTime.Now;
                    State = ValueDumpState.NextItem;

                    break;

                case ValueDumpState.WaitingToFinishQuickSell:
                    if (sellWindow == null || !sellWindow.IsReady || sellWindow.Item.ItemId != _currentItem.Id)
                    {
                        var modal = DirectEve.Instance.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 > random_number)
                        {

                            var refineItems = hangar.Items.Where(i => _form.ItemsToRefine.Any(r => r.Id == i.ItemId));
                            DirectEve.Instance.ReprocessStationItems(refineItems);

                            _lastExecute = DateTime.Now;
                        }
                        return;
                    }

                    if (reprorcessingWindow.NeedsQuote)
                    {
                        if (DateTime.Now.Subtract(_lastExecute).TotalSeconds > random_number)
                        {
                            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();
                        _lastExecute = DateTime.Now;
                        Logging.Log("Waiting 17 second");
                        State = ValueDumpState.WaitingToBack;
                    }
                    break;

                case ValueDumpState.WaitingToBack:
                    if(DateTime.Now.Subtract(_lastExecute).TotalSeconds > 17 && value_process)
                    {
                        if(value_process)
                            State = ValueDumpState.Begin;
                        else
                            State = ValueDumpState.Done;
                    }
                    break;
            }
        }
Beispiel #2
0
        public void ProcessState()
        {
            var marketWindow        = DirectEve.Instance.Windows.OfType <DirectMarketWindow>().FirstOrDefault();
            var hangar              = DirectEve.Instance.GetItemHangar();
            var sellWindow          = DirectEve.Instance.Windows.OfType <DirectMarketActionWindow>().FirstOrDefault(w => w.IsSellAction);
            var reprorcessingWindow = DirectEve.Instance.Windows.OfType <DirectReprocessingWindow>().FirstOrDefault();

            switch (State)
            {
            case ValueDumpState.Idle:
            case ValueDumpState.Done:
                break;

            case ValueDumpState.Begin:
                State = ValueDumpState.GetItems;
                break;

            case ValueDumpState.CheckMineralPrices:
                _currentMineral = _form.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.Instance.ExecuteCommand(DirectCmd.OpenMarket);
                        _lastExecute = DateTime.Now;
                    }

                    return;
                }

                if (marketWindow.DetailTypeId != _currentMineral.Id)
                {
                    if (DateTime.Now.Subtract(_lastExecute).TotalSeconds < 5)
                    {
                        return;
                    }

                    Logging.Log("ValueDump: Loading orders for " + _currentMineral.Name);

                    marketWindow.LoadTypeId(_currentMineral.Id);
                    _lastExecute = DateTime.Now;
                    return;
                }

                if (!marketWindow.BuyOrders.Any(o => o.StationId == DirectEve.Instance.Session.StationId))
                {
                    _currentMineral.LastUpdate = DateTime.Now;

                    Logging.Log("ValueDump: 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.Instance.Session.StationId).OrderByDescending(o => o.Price).Take(5).Average(o => o.Price);
                _currentMineral.LastUpdate = DateTime.Now;
                State = ValueDumpState.CheckMineralPrices;

                Logging.Log("ValueDump: Average price for " + _currentMineral.Name + " is " + _currentMineral.MedianBuy.Value.ToString("#,##0.00"));
                break;

            case ValueDumpState.SaveMineralPrices:
                Logging.Log("ValueDump: Saving InvItems.xml");

                var xdoc = new XDocument(new XElement("invtypes"));
                foreach (var type in _form.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)
                    {
                        Logging.Log("ValueDump: Opening hangar");
                        DirectEve.Instance.ExecuteCommand(DirectCmd.OpenHangarFloor);
                        _lastExecute = DateTime.Now;
                    }

                    return;
                }

                if (!hangar.IsReady)
                {
                    return;
                }

                Logging.Log("ValueDump: Loading hangar items");

                // Clear out the old
                _form.Items.Clear();
                var hangarItems = hangar.Items;
                if (hangarItems != null)
                {
                    _form.Items.AddRange(hangarItems.Where(i => i.ItemId > 0 && i.MarketGroupId > 0 && i.Quantity > 0).Select(i => new ItemCache(i, _form.RefineCheckBox.Checked)));
                }


                State = ValueDumpState.UpdatePrices;
                break;

            case ValueDumpState.UpdatePrices:
                foreach (var item in _form.Items)
                {
                    InvType invType;
                    if (!_form.InvTypesById.TryGetValue(item.TypeId, out invType))
                    {
                        Logging.Log("ValueDump: Unknown TypeId " + item.TypeId + " for " + item.Name);
                        continue;
                    }

                    item.InvType = invType;
                    foreach (var material in item.RefineOutput)
                    {
                        if (!_form.InvTypesById.TryGetValue(material.TypeId, out invType))
                        {
                            Logging.Log("ValueDump: Unknown TypeId " + material.TypeId + " for " + material.Name);
                            continue;
                        }

                        material.InvType = invType;
                    }
                }


                if (_form.cbxSell.Checked)
                {
                    // Copy the items to sell list
                    _form.ItemsToSell.Clear();
                    _form.ItemsToRefine.Clear();
                    if (_form.cbxUndersell.Checked)
                    {
                        _form.ItemsToSell.AddRange(_form.Items.Where(i => i.InvType != null));
                    }
                    else
                    {
                        _form.ItemsToSell.AddRange(_form.Items.Where(i => i.InvType != null && i.InvType.MedianBuy.HasValue));
                    }

                    State = ValueDumpState.NextItem;
                }
                else
                {
                    State = ValueDumpState.Done;
                }

                break;

            case ValueDumpState.NextItem:

                if (_form.ItemsToSell.Count == 0)
                {
                    if (_form.ItemsToRefine.Count != 0)
                    {
                        State = ValueDumpState.RefineItems;
                    }
                    else
                    {
                        State = ValueDumpState.Done;
                    }
                    break;
                }

                Logging.Log("ValueDump: " + _form.ItemsToSell.Count + " items left to sell");

                _currentItem = _form.ItemsToSell[0];
                _form.ItemsToSell.RemoveAt(0);

                // Dont sell containers
                if (_currentItem.GroupId == 448 || _currentItem.GroupId == 649)
                {
                    Logging.Log("ValueDump: 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)
                {
                    Logging.Log("ValueDump: Item " + _currentItem.Name + " no longer exists in the hanger");
                    break;
                }

                // Update Quantity
                _currentItem.QuantitySold = _currentItem.Quantity - directItem.Quantity;

                Logging.Log("ValueDump: Starting QuickSell for " + _currentItem.Name);
                if (!directItem.QuickSell())
                {
                    _lastExecute = DateTime.Now.AddSeconds(-5);

                    Logging.Log("ValueDump: 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;

                Logging.Log("ValueDump: 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)
                {
                    Logging.Log("ValueDump: 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 (_form.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)_form.RefineEfficiencyInput.Value / 100;

                    otherPrices += "[Refine price: " + refinePrice.ToString("#,##0.00") + "]";

                    if (refinePrice > totalPrice)
                    {
                        Logging.Log("ValueDump: 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
                        _form.ItemsToRefine.Add(_currentItem);

                        sellWindow.Cancel();
                        State = ValueDumpState.WaitingToFinishQuickSell;
                        break;
                    }
                }

                if (!_form.cbxUndersell.Checked)
                {
                    if (!_currentItem.InvType.MedianBuy.HasValue)
                    {
                        Logging.Log("ValueDump: 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)
                    {
                        Logging.Log("ValueDump: 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;

                Logging.Log("ValueDump: Selling " + quantity + " of " + _currentItem.Name + " [Sell price: " + (price * quantity).ToString("#,##0.00") + "]" + otherPrices);
                sellWindow.Accept();

                // Requeue to check again
                if (_currentItem.QuantitySold < _currentItem.Quantity)
                {
                    _form.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.Instance.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 => _form.ItemsToRefine.Any(r => r.Id == i.ItemId));
                        DirectEve.Instance.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.Done;
                }
                break;
            }
        }