public static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { try { Windows.TaskKill.Kill(mineContext.Kernel.GetProcessName(), waitForExit: true); Thread.Sleep(1000); if (_preExtractPackage != mineContext.Kernel.Package) { _preExtractPackage = mineContext.Kernel.Package; Logger.InfoDebugLine("解压内核包"); // 解压内核包 if (!mineContext.Kernel.ExtractPackage()) { VirtualRoot.Happened(new StartingMineFailedEvent("内核解压失败。")); } } Logger.InfoDebugLine("组装命令"); // 组装命令 BuildCmdLine(mineContext, out var kernelExeFileFullName, out var arguments); bool isLogFile = arguments.Contains("{logfile}"); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { Logger.ErrorDebugLine(kernelExeFileFullName + "文件不存在,请检查是否有拼写错误"); } if (isLogFile) { Logger.InfoDebugLine("创建日志文件型进程"); // 如果内核支持日志文件 // 推迟打印cmdLine,因为{logfile}变量尚未求值 CreateLogfileProcess(mineContext, kernelExeFileFullName, arguments); } else { Logger.InfoDebugLine("创建管道型进程"); // 如果内核不支持日志文件 CreatePipProcess(mineContext, kernelExeFileFullName, arguments); } Write.UserOk("开始挖矿"); VirtualRoot.Happened(new MineStartedEvent(mineContext)); } catch (Exception e) { Logger.ErrorDebugLine(e.Message, e); Write.UserFail("挖矿内核启动失败,请联系开发人员解决"); } }); }
public static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { lock (_locker) { try { #if DEBUG Write.Stopwatch.Restart(); #endif // 清理除当前外的Temp/Kernel Cleaner.Instance.Clear(); #if DEBUG Write.DevTimeSpan($"耗时{Write.Stopwatch.ElapsedMilliseconds}毫秒 {nameof(MinerProcess)}.{nameof(CreateProcessAsync)}[{nameof(Cleaner)}.{nameof(Cleaner.Clear)}]"); #endif Write.UserOk("场地打扫完毕"); // 应用超频 if (Instance.GpuProfileSet.IsOverClockEnabled(mineContext.MainCoin.GetId())) { Write.UserWarn("应用超频,如果CPU性能较差耗时可能超过1分钟,请耐心等待"); var cmd = new CoinOverClockCommand(mineContext.MainCoin.GetId()); // N卡超频当cpu性能非常差时较耗时,所以这里弄个回调 IMessagePathId callback = null; callback = VirtualRoot.BuildEventPath <CoinOverClockDoneEvent>("超频完成后继续流程", LogEnum.DevConsole, message => { if (mineContext != Instance.CurrentMineContext) { VirtualRoot.DeletePath(callback); } else if (message.CmdId == cmd.Id) { VirtualRoot.DeletePath(callback); ContinueCreateProcess(mineContext); } }); VirtualRoot.Execute(cmd); } else { ContinueCreateProcess(mineContext); } } catch (Exception e) { Logger.ErrorDebugLine(e); Write.UserFail("挖矿内核启动失败,请联系开发人员解决"); } } }); }
public static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { lock (_locker) { try { #if DEBUG NTStopwatch.Start(); #endif // 清理除当前外的Temp/Kernel Cleaner.Instance.Clear(); #if DEBUG var elapsedMilliseconds = NTStopwatch.Stop(); if (elapsedMilliseconds.ElapsedMilliseconds > NTStopwatch.ElapsedMilliseconds) { Write.DevTimeSpan($"耗时{elapsedMilliseconds} {nameof(MinerProcess)}.{nameof(CreateProcessAsync)}[{nameof(Cleaner)}.{nameof(Cleaner.Clear)}]"); } #endif Write.UserOk("场地打扫完毕"); // 应用超频 if (Instance.GpuProfileSet.IsOverClockEnabled(mineContext.MainCoin.GetId())) { Write.UserWarn("应用超频,如果CPU性能较差耗时可能超过1分钟,请耐心等待"); var cmd = new CoinOverClockCommand(mineContext.MainCoin.GetId()); VirtualRoot.AddOnecePath <CoinOverClockDoneEvent>("超频完成后继续流程", LogEnum.DevConsole, message => { if (mineContext == Instance.LockedMineContext) { ContinueCreateProcess(mineContext); } }, location: typeof(MinerProcess), pathId: cmd.Id); // 超频是在另一个线程执行的,因为N卡超频当cpu性能非常差时较耗时 VirtualRoot.Execute(cmd); } else { ContinueCreateProcess(mineContext); } } catch (Exception e) { Logger.ErrorDebugLine(e); Write.UserFail("挖矿内核启动失败,请联系开发人员解决"); } } }); }
protected override void OnStartup(StartupEventArgs e) { RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; // 通过群控升级挖矿端的时候升级器可能不存在所以需要下载,下载的时候需要用到下载器所以下载器需要提前注册 VirtualRoot.Window <ShowFileDownloaderCommand>(LogEnum.DevConsole, action: message => { UIThread.Execute(() => { FileDownloader.ShowWindow(message.DownloadFileUrl, message.FileTitle, message.DownloadComplete); }); }); VirtualRoot.Window <UpgradeCommand>(LogEnum.DevConsole, action: message => { AppStatic.Upgrade(message.FileName, message.Callback); }); if (!string.IsNullOrEmpty(CommandLineArgs.Upgrade)) { VirtualRoot.Execute(new UpgradeCommand(CommandLineArgs.Upgrade, () => { UIThread.Execute(() => { Environment.Exit(0); }); })); } else { try { appMutex = new Mutex(true, s_appPipName, out createdNew); } catch (Exception) { createdNew = false; } if (createdNew) { Logger.InfoDebugLine($"==================NTMiner.exe {NTMinerRoot.CurrentVersion.ToString()}=================="); if (!NTMiner.Windows.WMI.IsWmiEnabled) { DialogWindow.ShowDialog(message: "开源矿工无法运行所需的组件,因为本机未开启WMI服务,开源矿工需要使用WMI服务检测windows的内存、显卡等信息,请先手动开启WMI。", title: "提醒", icon: "Icon_Error"); Shutdown(); Environment.Exit(0); } NTMinerOverClockUtil.ExtractResource(); VirtualRoot.SetIsMinerClient(true); NotiCenterWindowViewModel.IsHotKeyEnabled = true; Window splashWindow = _appViewFactory.CreateSplashWindow(); splashWindow.Show(); NotiCenterWindow.Instance.Show(); if (DevMode.IsDevMode) { HandlerIdsWindow window = new HandlerIdsWindow(); window.Show(); } if (!NTMiner.Windows.Role.IsAdministrator) { NotiCenterWindowViewModel.Instance.Manager .CreateMessage() .Warning("请以管理员身份运行。") .WithButton("点击以管理员身份运行", button => { Wpf.Util.RunAsAdministrator(); }) .Dismiss().WithButton("忽略", button => { }).Queue(); } VirtualRoot.On <StartingMineFailedEvent>("开始挖矿失败", LogEnum.DevConsole, action: message => { AppContext.Instance.MinerProfileVm.IsMining = false; Write.UserFail(message.Message); }); NTMinerRoot.Instance.Init(() => { _appViewFactory.Link(); if (NTMinerRoot.Instance.GpuSet.Count == 0) { NotiCenterWindowViewModel.Instance.Manager.ShowErrorMessage("没有矿卡或矿卡未驱动。"); } UIThread.Execute(() => { if (NTMinerRoot.GetIsNoUi() && NTMinerRegistry.GetIsAutoStart()) { MainWindow = NotiCenterWindow.Instance; NotiCenterWindowViewModel.Instance.Manager.ShowSuccessMessage("已切换为无界面模式运行,可在选项页调整设置", "开源矿工"); } else { _appViewFactory.ShowMainWindow(isToggle: false); } AppContext.NotifyIcon = ExtendedNotifyIcon.Create("开源矿工", isMinerStudio: false); splashWindow?.Close(); }); #region 处理显示主界面命令 VirtualRoot.Window <ShowMainWindowCommand>("处理显示主界面命令", LogEnum.DevConsole, action: message => { ShowMainWindow(message.IsToggle); }); #endregion Task.Factory.StartNew(() => { try { HttpServer.Start($"http://localhost:{Consts.MinerClientPort}"); NTMinerRoot.Instance.Start(); Daemon.DaemonUtil.RunNTMinerDaemon(); } catch (Exception ex) { Logger.ErrorDebugLine(ex); } }); }); Link(); } else { try { _appViewFactory.ShowMainWindow(this, MinerServer.NTMinerAppType.MinerClient); } catch (Exception) { DialogWindow.ShowDialog(message: "另一个NTMiner正在运行,请手动结束正在运行的NTMiner进程后再次尝试。", title: "提醒", icon: "Icon_Error"); Process currentProcess = Process.GetCurrentProcess(); NTMiner.Windows.TaskKill.KillOtherProcess(currentProcess); } } } base.OnStartup(e); }
private static void ReadPrintLoopLogFileAsync(IMineContext mineContext, string logFile) { Task.Factory.StartNew(() => { bool isLogFileCreated = true; int n = 0; while (!File.Exists(logFile)) { if (n >= 20) { // 20秒钟都没有建立日志文件,不可能 isLogFileCreated = false; Write.UserFail("呃!意外,竟然20秒钟未产生内核输出文件,请联系开发人员解决。"); break; } Thread.Sleep(1000); if (n == 0) { Write.UserInfo("等待内核出场"); } if (mineContext != Instance.CurrentMineContext) { Write.UserInfo("挖矿上下文变更,结束内核输出等待。"); isLogFileCreated = false; break; } n++; } if (isLogFileCreated) { Write.UserOk("内核已上场,下面把舞台交给内核。"); StreamReader sreader = null; try { sreader = new StreamReader(File.Open(logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.Default); while (mineContext == Instance.CurrentMineContext) { string outline = sreader.ReadLine(); if (string.IsNullOrEmpty(outline) && sreader.EndOfStream) { Thread.Sleep(1000); } else { string input = outline; Guid kernelOutputId = mineContext.Kernel.KernelOutputId; Instance.KernelOutputFilterSet.Filter(kernelOutputId, ref input); ConsoleColor color = ConsoleColor.White; Instance.KernelOutputTranslaterSet.Translate(kernelOutputId, ref input, ref color, isPre: true); // 使用Claymore挖其非ETH币种时它也打印ETH,所以这里需要纠正它 if ("Claymore".Equals(mineContext.Kernel.Code, StringComparison.OrdinalIgnoreCase)) { if (mineContext.MainCoin.Code != "ETH" && input.Contains("ETH")) { input = input.Replace("ETH", mineContext.MainCoin.Code); } } Instance.KernelOutputSet.Pick(kernelOutputId, ref input, mineContext); if (IsUiVisible) { Instance.KernelOutputTranslaterSet.Translate(kernelOutputId, ref input, ref color); } if (!string.IsNullOrEmpty(input)) { if (Instance.KernelOutputSet.TryGetKernelOutput(kernelOutputId, out IKernelOutput kernelOutput)) { if (kernelOutput.PrependDateTime) { Write.UserLine($"{DateTime.Now} {input}", color); } else { Write.UserLine(input, color); } } else { Write.UserLine(input, color); } } } } } catch (Exception e) { Logger.ErrorDebugLine(e); } finally { sreader?.Close(); sreader?.Dispose(); } Write.UserInfo("内核表演结束"); } }, TaskCreationOptions.LongRunning); }
public static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { lock (_locker) { try { Write.UserInfo("清理内核进程"); #if DEBUG VirtualRoot.Stopwatch.Restart(); #endif // 清理除当前外的Temp/Kernel Cleaner.Clear(); #if DEBUG Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {nameof(MinerProcess)}.{nameof(CreateProcessAsync)}[{nameof(Cleaner)}.{nameof(Cleaner.Clear)}]"); #endif Write.UserOk("内核进程清理完毕"); Thread.Sleep(1000); Write.UserInfo($"解压内核包{mineContext.Kernel.Package}"); // 解压内核包 if (!mineContext.Kernel.ExtractPackage()) { VirtualRoot.Happened(new StartingMineFailedEvent("内核解压失败,请卸载内核重试。")); } else { Write.UserOk("内核包解压成功"); } // 执行文件书写器 mineContext.ExecuteFileWriters(); Write.UserInfo("总成命令"); // 组装命令 BuildCmdLine(mineContext, out string kernelExeFileFullName, out string arguments); bool isLogFile = arguments.Contains("{logfile}"); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { Write.UserError(kernelExeFileFullName + "文件不存在,可能是小编拼写错误导致,请QQ群联系小编。"); } if (isLogFile) { Logger.InfoDebugLine("创建日志文件型进程"); // 如果内核支持日志文件 // 推迟打印cmdLine,因为{logfile}变量尚未求值 CreateLogfileProcess(mineContext, kernelExeFileFullName, arguments); } else { Logger.InfoDebugLine("创建管道型进程"); // 如果内核不支持日志文件 CreatePipProcess(mineContext, kernelExeFileFullName, arguments); } VirtualRoot.Happened(new MineStartedEvent(mineContext)); } catch (Exception e) { Logger.ErrorDebugLine(e); Write.UserFail("挖矿内核启动失败,请联系开发人员解决"); } } }); }
private static void UpdateAsync() { Task.Factory.StartNew(() => { try { var vdsUUDataTask = GetHtmlAsync("https://uupool.cn/api/getAllInfo.php"); var vdsZtDataTask = GetHtmlAsync("https://www.zt.com/api/v1/symbol"); var htmlDataTask = GetHtmlAsync("https://www.f2pool.com/"); byte[] htmlData = null; byte[] vdsUUData = null; byte[] vdsZtData = null; try { Task.WaitAll(new Task[] { vdsUUDataTask, vdsZtDataTask, htmlDataTask }, 30 * 1000); htmlData = htmlDataTask.Result; vdsUUData = vdsUUDataTask.Result; vdsZtData = vdsZtDataTask.Result; } catch { } if (htmlData != null && htmlData.Length != 0) { Write.UserOk($"{DateTime.Now} - 鱼池首页html获取成功"); string html = Encoding.UTF8.GetString(htmlData); string vdsUUHtml = string.Empty; string vdsZtHtml = string.Empty; if (vdsUUData != null && vdsUUData.Length != 0) { vdsUUHtml = Encoding.UTF8.GetString(vdsUUData); } if (vdsZtData != null && vdsZtData.Length != 0) { vdsZtHtml = Encoding.UTF8.GetString(vdsZtData); } double usdCny = PickUsdCny(html); Write.UserInfo($"usdCny={usdCny}"); List <IncomeItem> incomeItems = PickIncomeItems(html); IncomeItem vdsIncomeItem = PickVDSIncomeItem(vdsUUHtml, vdsZtHtml, usdCny); if (vdsIncomeItem != null && incomeItems.All(a => a.CoinCode != "VDS")) { incomeItems.Add(vdsIncomeItem); } Write.UserInfo($"鱼池首页有{incomeItems.Count}个币种"); FillCny(incomeItems, usdCny); NeatenSpeedUnit(incomeItems); if (incomeItems != null && incomeItems.Count != 0) { Login(); OfficialServer.CalcConfigService.GetCalcConfigsAsync(data => { Write.UserInfo($"NTMiner有{data.Count}个币种"); HashSet <string> coinCodes = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (CalcConfigData calcConfigData in data) { IncomeItem incomeItem = incomeItems.FirstOrDefault(a => string.Equals(a.CoinCode, calcConfigData.CoinCode, StringComparison.OrdinalIgnoreCase)); if (incomeItem != null) { coinCodes.Add(calcConfigData.CoinCode); calcConfigData.Speed = incomeItem.Speed; calcConfigData.SpeedUnit = incomeItem.SpeedUnit; calcConfigData.IncomePerDay = incomeItem.IncomeCoin; calcConfigData.IncomeUsdPerDay = incomeItem.IncomeUsd; calcConfigData.IncomeCnyPerDay = incomeItem.IncomeCny; calcConfigData.ModifiedOn = DateTime.Now; } } OfficialServer.CalcConfigService.SaveCalcConfigsAsync(data, callback: (res, e) => { if (!res.IsSuccess()) { Write.UserFail(res.ReadMessage(e)); } }); foreach (IncomeItem incomeItem in incomeItems) { if (coinCodes.Contains(incomeItem.CoinCode)) { continue; } Write.UserInfo(incomeItem.ToString()); } foreach (var incomeItem in incomeItems) { if (!coinCodes.Contains(incomeItem.CoinCode)) { continue; } Write.UserOk(incomeItem.ToString()); } Write.UserOk($"更新了{coinCodes.Count}个币种:{string.Join(",", coinCodes)}"); int unUpdatedCount = data.Count - coinCodes.Count; Write.UserWarn($"{unUpdatedCount}个币种未更新{(unUpdatedCount == 0 ? string.Empty : ":" + string.Join(",", data.Select(a => a.CoinCode).Except(coinCodes)))}"); }); } } } catch (Exception e) { Logger.ErrorDebugLine(e); } }); }
/// <summary> /// 打开远程桌面窗口连接给定ip的windows主机 /// </summary> public static void OpenRemoteDesktop(RemoteDesktopInput input) { UIThread.Execute(() => { string serverIp = input.ServerIp; string userName = input.UserName; string password = input.Password; string description = input.Description; Action <string> onDisconnected = input.OnDisconnected; string[] serverIps = serverIp.Split(':'); serverIp = serverIps[0]; string id = serverIp.Replace(".", ""); string formName = $"form_{id}"; string formText = $"开源矿工远程桌面 - {description} ({serverIp})"; AxMsRdpClient7NotSafeForScripting axMsRdpc = null; string axMsRdpcName = $"axMsRdpc_{id}"; if (SFormsByName.ContainsKey(formName)) { Form form = SFormsByName[formName]; form.Show(); if (form.WindowState == FormWindowState.Minimized) { form.WindowState = FormWindowState.Normal; } form.Activate(); return; } else { axMsRdpc = new AxMsRdpClient7NotSafeForScripting(); } Form axMsRdpcForm = new Form { ShowIcon = false, Name = formName, Text = formText, Size = new Size(1200, 900), StartPosition = FormStartPosition.CenterScreen, MaximizeBox = false, WindowState = FormWindowState.Normal }; axMsRdpcForm.FormClosed += (object sender, FormClosedEventArgs e) => { Form frm = (Form)sender; foreach (Control ctrl in frm.Controls) { if (ctrl.GetType().Name == nameof(AxMsRdpClient7NotSafeForScripting)) { if (SFormsByName.ContainsKey(frm.Name)) { SFormsByName.Remove(frm.Name); } var axMsRdp = (AxMsRdpClient7NotSafeForScripting)ctrl; if (axMsRdp != null && axMsRdp.Connected != 0) { axMsRdp.Disconnect(); axMsRdp.Dispose(); } } } }; SFormsByName.Add(formName, axMsRdpcForm); ((System.ComponentModel.ISupportInitialize)(axMsRdpc)).BeginInit(); axMsRdpc.Dock = DockStyle.Fill; axMsRdpc.Enabled = true; axMsRdpc.OnConnecting += (object sender, EventArgs e) => { var axMsRdp = sender as AxMsRdpClient7NotSafeForScripting; axMsRdp.ConnectingText = axMsRdp.GetStatusText(Convert.ToUInt32(axMsRdp.Connected)); axMsRdp.FindForm().WindowState = FormWindowState.Normal; }; axMsRdpc.OnDisconnected += (object sender, IMsTscAxEvents_OnDisconnectedEvent e) => { var axMsRdp = sender as AxMsRdpClient7NotSafeForScripting; string disconnectedText = $"{formText}远程桌面连接已断开!"; axMsRdp.DisconnectedText = disconnectedText; axMsRdp.FindForm().Close(); Write.UserFail(disconnectedText); onDisconnected?.Invoke(disconnectedText); }; axMsRdpcForm.Controls.Add(axMsRdpc); axMsRdpcForm.Show(); ((System.ComponentModel.ISupportInitialize)(axMsRdpc)).EndInit(); axMsRdpc.Name = axMsRdpcName; axMsRdpc.Server = serverIp; axMsRdpc.UserName = userName; axMsRdpc.AdvancedSettings7.RDPPort = serverIps.Length == 1 ? 3389 : Convert.ToInt32(serverIps[1]); // 启用CredSSP身份验证(有些服务器连接没有反应,需要开启这个) axMsRdpc.AdvancedSettings7.EnableCredSspSupport = true; axMsRdpc.AdvancedSettings7.ClearTextPassword = password; // 禁用公共模式 //axMsRdpc.AdvancedSettings7.PublicMode = false; // 颜色位数 8,16,24,32 axMsRdpc.ColorDepth = 32; axMsRdpc.FullScreen = false; axMsRdpc.DesktopWidth = axMsRdpcForm.ClientRectangle.Width; axMsRdpc.DesktopHeight = axMsRdpcForm.ClientRectangle.Height; axMsRdpc.Connect(); }); }
public static void CreateProcessAsync(IMineContext mineContext) { Task.Factory.StartNew(() => { lock (_locker) { try { Write.UserInfo("清理内核进程"); HashSet <string> allKernelProcessNames = Instance.KernelSet.GetAllKernelProcessNames(); #if DEBUG VirtualRoot.Stopwatch.Restart(); #endif foreach (var processName in allKernelProcessNames) { Windows.TaskKill.Kill(processName, waitForExit: true); } #if DEBUG Write.DevWarn($"耗时{VirtualRoot.Stopwatch.ElapsedMilliseconds}毫秒 {nameof(MinerProcess)}.{nameof(CreateProcessAsync)}[{nameof(allKernelProcessNames)}]"); #endif Write.UserOk("内核进程清理完毕"); Thread.Sleep(1000); Write.UserInfo($"解压内核包{mineContext.Kernel.Package}"); // 解压内核包 if (!mineContext.Kernel.ExtractPackage()) { Write.UserFail("内核解压失败"); VirtualRoot.Happened(new StartingMineFailedEvent("内核解压失败。")); } else { Write.UserOk("内核包解压成功"); } Write.UserInfo("总成命令"); // 组装命令 BuildCmdLine(mineContext, out var kernelExeFileFullName, out var arguments); bool isLogFile = arguments.Contains("{logfile}"); // 这是不应该发生的,如果发生很可能是填写命令的时候拼写错误了 if (!File.Exists(kernelExeFileFullName)) { Write.UserError(kernelExeFileFullName + "文件不存在,可能是小编拼写错误导致,请QQ群联系小编。"); } if (isLogFile) { Logger.InfoDebugLine("创建日志文件型进程"); // 如果内核支持日志文件 // 推迟打印cmdLine,因为{logfile}变量尚未求值 CreateLogfileProcess(mineContext, kernelExeFileFullName, arguments); } else { Logger.InfoDebugLine("创建管道型进程"); // 如果内核不支持日志文件 CreatePipProcess(mineContext, kernelExeFileFullName, arguments); } VirtualRoot.Happened(new MineStartedEvent(mineContext)); } catch (Exception e) { Logger.ErrorDebugLine(e); Write.UserFail("挖矿内核启动失败,请联系开发人员解决"); } } }); }
private static void ReadPrintLoopLogFileAsync(IMineContext mineContext, bool isWriteToConsole) { Task.Factory.StartNew(() => { bool isLogFileCreated = true; int n = 0; while (!File.Exists(mineContext.LogFileFullName)) { if (n >= 20) { // 20秒钟都没有建立日志文件,不可能 isLogFileCreated = false; Write.UserFail("呃!意外,竟然20秒钟未产生内核输出。常见原因:1.挖矿内核被杀毒软件删除; 2.没有磁盘空间了; 3.反馈给开发人员"); break; } Thread.Sleep(1000); if (n == 0) { Write.UserInfo("等待内核出场"); } if (mineContext != Instance.LockedMineContext) { Write.UserWarn("结束内核输出等待。"); isLogFileCreated = false; break; } n++; } if (isLogFileCreated) { StreamReader sreader = null; try { sreader = new StreamReader(File.Open(mineContext.LogFileFullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.Default); while (mineContext == Instance.LockedMineContext) { string outline = sreader.ReadLine(); if (string.IsNullOrEmpty(outline) && sreader.EndOfStream) { Thread.Sleep(1000); } else { string input = outline; Guid kernelOutputId = Guid.Empty; if (mineContext.KernelOutput != null) { kernelOutputId = mineContext.KernelOutput.GetId(); } // 前译 Instance.ServerContext.KernelOutputTranslaterSet.Translate(kernelOutputId, ref input, isPre: true); Instance.ServerContext.KernelOutputSet.Pick(ref input, mineContext); var kernelOutputKeywords = Instance.KernelOutputKeywordSet.GetKeywords(mineContext.KernelOutput.GetId()); if (kernelOutputKeywords != null && kernelOutputKeywords.Count != 0) { foreach (var keyword in kernelOutputKeywords) { if (input.Contains(keyword.Keyword)) { if (keyword.MessageType.TryParse(out LocalMessageType messageType)) { string content = input; if (!string.IsNullOrEmpty(keyword.Description)) { content += $" 大意:{keyword.Description}"; } VirtualRoot.LocalMessage(LocalMessageChannel.Kernel, nameof(MinerProcess), messageType, content, OutEnum.None, toConsole: false); } } } } if (isWriteToConsole) { if (!string.IsNullOrEmpty(input)) { Write.UserLine(input, ConsoleColor.White); } } } } } catch (Exception e) { Logger.ErrorDebugLine(e); } finally { sreader?.Close(); sreader?.Dispose(); } Write.UserWarn("内核表演结束"); } if (_kernelProcess != null) { lock (_kernelProcessLocker) { if (_kernelProcess != null) { _kernelProcess.Dispose(); _kernelProcess = null; } } } }, TaskCreationOptions.LongRunning); }
private static void ReadPrintLoopLogFileAsync(IMineContext mineContext, bool isWriteToConsole) { Task.Factory.StartNew(() => { bool isLogFileCreated = true; int n = 0; while (!File.Exists(mineContext.LogFileFullName)) { if (n >= 20) { // 20秒钟都没有建立日志文件,不可能 isLogFileCreated = false; Write.UserFail("呃!意外,竟然20秒钟未产生内核输出。常见原因:1.挖矿内核被杀毒软件删除; 2.没有磁盘空间了; 3.反馈给开发人员"); break; } Thread.Sleep(1000); if (n == 0) { Write.UserInfo("等待内核出场"); } if (mineContext != Instance.CurrentMineContext) { Write.UserWarn("结束内核输出等待。"); isLogFileCreated = false; break; } n++; } if (isLogFileCreated) { StreamReader sreader = null; try { sreader = new StreamReader(File.Open(mineContext.LogFileFullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.Default); while (mineContext == Instance.CurrentMineContext) { string outline = sreader.ReadLine(); if (string.IsNullOrEmpty(outline) && sreader.EndOfStream) { Thread.Sleep(1000); } else { string input = outline; Guid kernelOutputId = Guid.Empty; if (mineContext.KernelOutput != null) { kernelOutputId = mineContext.KernelOutput.GetId(); } Instance.KernelOutputFilterSet.Filter(kernelOutputId, ref input); ConsoleColor color = ConsoleColor.White; // 前译 Instance.KernelOutputTranslaterSet.Translate(kernelOutputId, ref input, ref color, isPre: true); // 使用Claymore挖其非ETH币种时它也打印ETH,所以这里需要纠正它 if ("Claymore".Equals(mineContext.Kernel.Code, StringComparison.OrdinalIgnoreCase)) { if (mineContext.MainCoin.Code != "ETH" && input.Contains("ETH")) { input = input.Replace("ETH", mineContext.MainCoin.Code); } } Instance.KernelOutputSet.Pick(ref input, mineContext); if (isWriteToConsole) { if (!string.IsNullOrEmpty(input)) { Write.UserLine(input, ConsoleColor.White); } } } } } catch (Exception e) { Logger.ErrorDebugLine(e); } finally { sreader?.Close(); sreader?.Dispose(); } Write.UserWarn("内核表演结束"); } if (_kernelProcess != null) { lock (_kernelProcessLocker) { if (_kernelProcess != null) { _kernelProcess.Dispose(); _kernelProcess = null; } } } }, TaskCreationOptions.LongRunning); }
private static void StartConsumer(IModel channel, AbstractMqMessagePath[] mqMessagePaths) { Task.Factory.StartNew(() => { DateTime startOn = DateTime.Now; bool isTimeout = false; while (!mqMessagePaths.All(a => a.IsReadyToBuild)) { if (startOn.AddSeconds(20) < DateTime.Now) { isTimeout = true; break; } System.Threading.Thread.Sleep(100); } if (isTimeout) { Write.UserFail("订阅Mq失败,因为超时"); } else { foreach (var mqMessagePathsByQueue in mqMessagePaths.GroupBy(a => a.Queue)) { string queue = mqMessagePathsByQueue.Key; bool durable = queue.EndsWith(MqKeyword.DurableQueueEndsWith); channel.QueueDeclare( queue: queue, durable: durable, exclusive: false, autoDelete: !durable, arguments: null); EventingBasicConsumer consumer = new EventingBasicConsumer(channel); foreach (var mqMessagePath in mqMessagePathsByQueue) { mqMessagePath.Build(channel); } consumer.Received += (model, ea) => { foreach (var mqMessagePath in mqMessagePathsByQueue) { try { mqMessagePath.Go(ea); } catch (Exception e) { Logger.ErrorDebugLine(e); } } if (durable) { channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); } }; if (durable) { channel.BasicConsume(queue: queue, autoAck: false, consumer: consumer); } else { channel.BasicConsume(queue: queue, autoAck: true, consumer: consumer); } } Write.UserOk("订阅Mq成功"); } }); }