public static void GetProfit(ProfitTable profitTable, Shortcut currentlyMinedCoin, out ProfitTableRow maxCoinRow, out decimal maxProfit, out decimal currentProfit, out bool nothingChecked) { maxProfit = 0; maxCoinRow = null; nothingChecked = true; ProfitTableRow currentCoinRow = null; var coinName = currentlyMinedCoin?.GetName(); foreach (var row in profitTable.ProfitList) { if (currentlyMinedCoin != null && row.Name == coinName && row.Path == currentlyMinedCoin?.Path && row.Arguments == currentlyMinedCoin?.Arguments) { currentCoinRow = row; } if (row.Switchable) { nothingChecked = false; } if (row.Switchable && row.ProfitDay > maxProfit) { maxCoinRow = row; maxProfit = row.ProfitDay; } } currentProfit = 0; if (currentlyMinedCoin != null && currentCoinRow != null) { currentProfit = currentCoinRow.ProfitDay; } }
private async void SwitchManuallyCommand(object obj) { ProfitTablesEnabled = true; if (ProfitTables.Tables == null || ProfitTables.Tables.Count == 0) { ProfitTables.Tables.Clear(); for (var i = 0; i < Workers.WorkerList.Count; i++) { var worker = Workers.WorkerList[i]; if (worker.Query) { var newTable = new ProfitTable { Name = worker.Name, Index = i + 1, ThisPC = Helpers.ListContainsThisPC(worker.Computers), Description = worker.Description, Computers = new ObservableCollection <Computer>(), ProfitList = new List <ProfitTableRow>() }; foreach (var pc in worker.Computers) { newTable.Computers.Add(new Computer { Name = pc, IsExpanded = true }); } foreach (var ct in worker.CoinList) { newTable.ProfitList.Add(new ProfitTableRow { Name = ct.FullName, Symbol = ct.FullSymbol, Algorithm = ct.FullAlgorithm, Hashrate = ct.FullHashrate, Path = ct.Path, Arguments = ct.Arguments }); } var first = newTable.ProfitList.FirstOrDefault(); if (first != null) { first.ManualSwitch = true; } //Show the topmost coin as the new coin in Computers list newTable.HookPropertyChanched(); newTable.Row_PropertyChanged(newTable.ProfitList.FirstOrDefault(), new PropertyChangedEventArgs("ManualSwitch")); ProfitTables.Tables.Add(newTable); } } ScanLan.RaiseCanExecuteChanged(); ScanLanCommand(null); return; } Computer thisPc = null; var toDoList = new ObservableCollection <ProfitTable>(); bool noComputerIsOnline = true; var negativeProfitCoinLsit = new List <(string worker, string coin, string profit)>(); var alreadyMiningPcLsit = new List <(string worker, string pc, string coin)>(); var lessProfitablePcLsit = new List <(string worker, string pc, string currentCoin, string switchCoin)>(); foreach (var table in ProfitTables.Tables) { var selectedCoinRow = table.ProfitList.FirstOrDefault(x => x.ManualSwitch); var newTable = new ProfitTable { Name = table.Name, ProfitList = new List <ProfitTableRow> { selectedCoinRow }, Computers = new ObservableCollection <Computer>() }; bool switchChecked = false; foreach (var pc in table.Computers) { if (pc.OnlineStatus == Computer.OperationStatus.Success) { noComputerIsOnline = false; } if (pc.Switch) { switchChecked = true; } if (pc.OnlineStatus == Computer.OperationStatus.Success && (pc.Switch || pc.Restart)) { // Detect empty path if (pc.Switch && (selectedCoinRow.Path == null || selectedCoinRow.Path == string.Empty)) { MessageBox.Show($"The selected coin {selectedCoinRow.NameAndSymbol} in {table.Name} has the Path field empty. Define a path to an executable and try again.", "Path cannot be empty", MessageBoxButton.OK, MessageBoxImage.Error); OnSwitchManuallyExit(); return; } var fullName = $"{pc.CurrentCoinName} ({pc.CurrentCoinSymbol})"; // Detect that the SwitchCoin is already mined if (pc.Switch && selectedCoinRow.Name == pc.CurrentCoinName) { alreadyMiningPcLsit.Add((table.Name, pc.Name, fullName)); } // Detect that the SwitchCoin is less profitable that the currently mined one var currentlyMinedCoinRow = table.ProfitList.FirstOrDefault(x => x.Name == pc.CurrentCoinName); if (pc.Switch && currentlyMinedCoinRow != null && currentlyMinedCoinRow.ProfitDay > selectedCoinRow.ProfitDay) { lessProfitablePcLsit.Add((table.Name, pc.Name, fullName, selectedCoinRow.NameAndSymbol)); } var computer = new Computer { Name = pc.Name, CurrentCoinName = pc.CurrentCoinName, CurrentCoinSymbol = pc.CurrentCoinSymbol, Switch = pc.Switch, Restart = pc.Restart, SwitchStatus = Computer.OperationStatus.Indeterminate, RestartStatus = Computer.OperationStatus.Indeterminate, }; if (computer.IsThisPc && thisPc == null) { thisPc = computer; } newTable.Computers.Add(computer); } } // Detect negative profit if (switchChecked && selectedCoinRow.ProfitDay <= 0) { negativeProfitCoinLsit.Add((table.Name, selectedCoinRow.NameAndSymbol, selectedCoinRow.ProfitDay.ToString("N2"))); } if (newTable.Computers.Count != 0) { toDoList.Add(newTable); } } if (toDoList.Count == 0) { string message = null; if (noComputerIsOnline) { message = "There are no computers online."; } else { message = "There are some computers online but none is checked either for Switch or Restart."; } MessageBox.Show(message, "Nothing to do", MessageBoxButton.OK, MessageBoxImage.Information); OnSwitchManuallyExit(); return; } // Disable Switch button. Call OnSwitchManuallyExit before every return to re-enable it. SwitchManuallyIsInProgress = true; // Check if localhost is among the pcList machines and it has a background switch job running if (SwitchIsInProgress && thisPc != null) { var result = MessageBox.Show($"An unfinished switching task is currently running in the background. It may overwrite the results of this operation on {thisPc.Name} when it is done. Stop the background job and switch anyway?", "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result == MessageBoxResult.Yes) { SwitchCancelSource.Cancel(); while (SwitchIsInProgress) { await Task.Delay(100); } } else { OnSwitchManuallyExit(); return; } } // Warn if any issues detected if (negativeProfitCoinLsit.Count != 0 || alreadyMiningPcLsit.Count != 0 || lessProfitablePcLsit.Count != 0) { FlowDocument document = new FlowDocument(); int cnt = negativeProfitCoinLsit.Count; if (cnt != 0) { var paragraph = new Paragraph(new Run("The following selected coins have zero or negative profit:\r\n")); for (int i = 0; i < cnt; i++) { var entry = negativeProfitCoinLsit[i]; Run worker = new Run($"{entry.worker}: "); worker.FontWeight = FontWeights.Bold; paragraph.Inlines.Add(worker); paragraph.Inlines.Add($"The daily profit of {entry.coin} is {entry.profit}."); if (i < cnt - 1) { paragraph.Inlines.Add("\r\n"); } } document.Blocks.Add(paragraph); } cnt = alreadyMiningPcLsit.Count; if (alreadyMiningPcLsit.Count != 0) { var paragraph = new Paragraph(new Run("The following computers are already mining the selected coin:\r\n")); document.Blocks.Add(paragraph); for (int i = 0; i < cnt; i++) { var entry = alreadyMiningPcLsit[i]; Run worker = new Run($"{entry.worker}: "); worker.FontWeight = FontWeights.Bold; paragraph.Inlines.Add(worker); paragraph.Inlines.Add($"{entry.pc} is already mining {entry.coin}."); if (i < cnt - 1) { paragraph.Inlines.Add("\r\n"); } } document.Blocks.Add(paragraph); } cnt = lessProfitablePcLsit.Count; if (lessProfitablePcLsit.Count != 0) { var paragraph = new Paragraph(new Run("The following computers are mining a coin that is more profitable than the one you've selected:\r\n")); document.Blocks.Add(paragraph); for (int i = 0; i < cnt; i++) { var entry = lessProfitablePcLsit[i]; Run worker = new Run($"{entry.worker}: "); worker.FontWeight = FontWeights.Bold; paragraph.Inlines.Add(worker); paragraph.Inlines.Add($"{entry.pc} is mining {entry.currentCoin} which is more profitable than {entry.switchCoin}."); if (i < cnt - 1) { paragraph.Inlines.Add("\r\n"); } } document.Blocks.Add(paragraph); } var reportWindow = new Report(); reportWindow.RichTextBox.Document = document; reportWindow.Title = "Switch Inspector"; reportWindow.Header.Text = $"{Constants.AppName} has detected some issues:"; reportWindow.Footer.Text = "Press 'OK' to ignore warnings and proceed or 'Cancel' to abort switching:"; var reportDialogResult = reportWindow.ShowDialog(); if (reportDialogResult == false) { OnSwitchManuallyExit(); return; } } // Show Switch window var switchWindow = new SwitchWindow(); var vm = new SwitchWindowVM(toDoList); switchWindow.DataContext = vm; var switchDialogResult = switchWindow.ShowDialog(); if (vm.SwitchIsInProgress && vm.ManualSwitchCancelSource != null) { vm.ManualSwitchCancelSource.Cancel(); } if (vm.SwitchIsInProgress || (vm.SwitchIsFinished && switchDialogResult == true)) { ScanLanCommand(null); } OnSwitchManuallyExit(); }
public static List <ProfitTable> CreateProfitTables(Dictionary <string, WtmData> wtmDataDict, List <Worker> workerList, decimal powerCost, WtmSettingsObject settings, bool switchableOnly = false) { var btc = wtmDataDict["Bitcoin"]; var profitList = new List <ProfitTableRow>(); var profitTables = new List <ProfitTable>(); int j = 1; var workerCount = workerList.Count; foreach (var worker in workerList) { foreach (var entry in worker.CoinList) { if (switchableOnly && !entry.Switch) { continue; } var profitResult = CalculateProfit(entry, wtmDataDict, btc, settings, powerCost); decimal profit24 = profitResult.profit24; decimal revenueAllCoins = profitResult.revenue; bool multicell = (entry.Coins.Count > 1); var newRow = new ProfitTableRow { Name = entry.FullName, Symbol = entry.FullSymbol, Algorithm = entry.FullAlgorithm, Hashrate = entry.FullHashrate, Multicell = multicell, Switchable = entry.Switch, Revenue = revenueAllCoins, ProfitDay = profit24, ProfitWeek = profit24 * 7, ProfitMonth = profit24 * 30, ProfitYear = profit24 * 365, Path = entry.Path ?? string.Empty, Arguments = entry.Arguments ?? string.Empty, Notes = entry.Notes, }; profitList.Add(newRow); newRow = null; } var newProfitTable = new ProfitTable { Name = worker.Name, Index = j, ThisPC = Helpers.ListContainsThisPC(worker.Computers), Computers = new ObservableCollection <Computer>(worker?.Computers.Select(computer => new Computer { Name = computer })), Description = worker.Description, ProfitList = profitList.OrderByDescending(p => p.ProfitDay).ToList() }; var firstCoin = newProfitTable.ProfitList.FirstOrDefault(); if (firstCoin != null) { firstCoin.ManualSwitch = true; } //Show the topmost coin as the new coin in Computers list newProfitTable.HookPropertyChanched(); newProfitTable.Row_PropertyChanged(newProfitTable.ProfitList.FirstOrDefault(), new PropertyChangedEventArgs("ManualSwitch")); profitTables.Add(newProfitTable); profitList.Clear(); j++; } return(profitTables); }