public SystemProxyManager()
        {
            AppDomain.CurrentDomain.ProcessExit += (o, args) => RestoreOriginalSettings();
            if (Environment.UserInteractive && NativeMethods.GetConsoleWindow() != IntPtr.Zero)
            {
                var handler = new NativeMethods.ConsoleEventDelegate(eventType =>
                {
                    if (eventType != 2)
                    {
                        return(false);
                    }

                    RestoreOriginalSettings();
                    return(false);
                });
                NativeMethods.Handler = handler;

                // On Console exit make sure we also exit the proxy
                NativeMethods.SetConsoleCtrlHandler(handler, true);
            }
        }
Ejemplo n.º 2
0
        static void Main()
        {
            Initialize();

            #region Error Mode
            //Prevent error dialog popups, this prevents the miner sub process from hanging by a windows error popup during a crash
            NativeMethods.SetErrorMode(NativeMethods.ErrorModes.SemFailcriticalerrors | NativeMethods.ErrorModes.SemNogpfaulterrorbox);
            #endregion

            #region Console Hooks
            //Hook Console to catch Close Event
            Handler = ConsoleEventCallback;
            NativeMethods.SetConsoleCtrlHandler(Handler, true);

            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                _running = false;
                PrettyConsole.WriteLine("Gracefully exiting...", ConsoleColor.Magenta);
            };
            #endregion


Startup:
            try
            {
                ConnectToMonitoringSocket();

                //Every minute the miner is running, it updates this file with how many minutes it has mined % MinutesInRotation
                var text = "";
                try
                {
                    text = File.ReadAllText(MiningMinuteFile);
                }
                catch (Exception ex)
                {
                    Log.Warning(ex);
                }

                if (!int.TryParse(text, out _miningMinute))
                {
                    Log.Warning($"Unable to read Mining Minute, defaulting to 0. Text received from {MiningMinuteFile}: {text}");
                }

                int currentMinute = -1;

                var freshStart = new List <string> {
                    "XzonControlPanel"
                };
                foreach (MinerConfig miner in _miners)
                {
                    var exeName = Path.GetFileNameWithoutExtension(miner.ExeLocation);
                    if (!freshStart.Contains(exeName))
                    {
                        freshStart.Add(exeName);
                    }
                }

                foreach (var p in freshStart)
                {
                    ProcessHelper.KillProcess(p);
                }
                Thread.Sleep(1000);

                PrettyConsole.Write("Max Allowed GPU Temperature is ");
                PrettyConsole.WriteLine($"{MaxTemp}°c", ConsoleColor.Red);
                PrettyConsole.WriteLine();

                Log.Warning("Miner Has Started");

                //Main Loop
                while (_running)
                {
                    Temperature.Refresh();

                    #region Scheduling
                    if (DateTime.Now.Hour * 60 + DateTime.Now.Minute != currentMinute && !_paused)
                    {
                        //Minute changed, increment
                        _miningMinute = (_miningMinute + 1) % MinutesInRotation;
                        UpdateMiningMinute(_miningMinute);
                        currentMinute = DateTime.Now.Hour * 60 + DateTime.Now.Minute;

                        PrettyConsole.WriteLine($"Current Minute: {_miningMinute}", ConsoleColor.DarkYellow);

                        //Check if it is time to use the next miner config in the schedule
                        MinerConfig newMinerConfig = _miners[0];
                        foreach (MinerConfig miner in _miners)
                        {
                            if (miner.StartMinute <= _miningMinute)
                            {
                                newMinerConfig = miner;
                            }
                            else
                            {
                                PrettyConsole.WriteLine($"Will start {miner.Name} at minute {miner.StartMinute}", ConsoleColor.DarkYellow);
                            }
                        }
                        if (!newMinerConfig.Equals(_currentMiningConfig))
                        {
                            SetActiveMiner(newMinerConfig);
                        }
                    }
                    #endregion

                    VerifyProcesses();
                    if (!_running)
                    {
                        break;
                    }

                    if (_paused)
                    {
                        Log.Informational("Miner is paused");

                        //If reboot after paused X minutes is set, reboot after X minutes
                        if (RebootAfterPausedXMinutes > 0 && _pausedTime != null)
                        {
                            if (DateTime.Now > _pausedTime.Value.AddMinutes(RebootAfterPausedXMinutes))
                            {
                                Log.Warning("Rebooting Machine");
                                Process.Start("shutdown.exe", "-r -t 30");
                                _running = false;
                            }
                            else
                            {
                                Log.Informational($"Rebooting machine in {_pausedTime.Value.AddMinutes(RebootAfterPausedXMinutes).Subtract(DateTime.Now).TotalSeconds} seconds", true);
                                PrettyConsole.Write("Rebooting machine in ");
                                PrettyConsole.Write($"{_pausedTime.Value.AddMinutes(RebootAfterPausedXMinutes).Subtract(DateTime.Now).TotalSeconds}", ConsoleColor.Yellow);
                                PrettyConsole.WriteLine(" seconds");
                            }
                        }
                    }

                    List <Gpu> gpus = new List <Gpu>();
                    List <Cpu> cpus = new List <Cpu>();

                    if (Temperature.GpuTemperatures == null)
                    {
                        Log.Warning("Unable to read GPU Temperatures, killing miner");
                        Pause();
                        KillMiner();
                        continue;
                    }

                    foreach (var temp in Temperature.CpuTemperatures)
                    {
                        PrettyConsole.Write($"{temp.InstanceName} ({temp.InstanceId}): ");
                        PrettyConsole.WriteLine($"{temp.CurrentValue}°c", ConsoleColor.Cyan);
                        cpus.Add(new Cpu {
                            Color = "Cyan", Id = temp.InstanceId, Name = temp.InstanceName, Temp = (int)temp.CurrentValue
                        });
                    }

                    foreach (var temp in Temperature.GpuTemperatures)
                    {
                        PrettyConsole.Write($"{temp.InstanceName} ({temp.InstanceId}): ");
                        var outputColor = ConsoleColor.Cyan;

                        if (temp.CurrentValue >= MaxTemp)
                        {
                            outputColor = ConsoleColor.Red;
                            PrettyConsole.Write($"{temp.CurrentValue}", outputColor);
                            PrettyConsole.Write(@"°c");
                        }
                        else if (temp.CurrentValue >= WarningTemp)
                        {
                            outputColor = ConsoleColor.Yellow;
                            PrettyConsole.Write($"{temp.CurrentValue}", outputColor);
                            PrettyConsole.Write(@"°c");
                        }
                        else if (Math.Abs(temp.CurrentValue) < 1)
                        {
                            //Check if GPU went offline, if it did its reported temperature is 0, check for <1 because floating point numbers doing their thing
                            outputColor = ConsoleColor.Red;
                            PrettyConsole.Write($"{temp.CurrentValue}", outputColor);
                            PrettyConsole.Write(@"°c");
                            Log.Error($"GPU {temp.InstanceName} ({temp.InstanceId}) Went Offline.");
                            KillMiner();
                            Pause();
                        }
                        else
                        {
                            PrettyConsole.Write($"{temp.CurrentValue}", outputColor);
                            PrettyConsole.Write(@"°c");
                        }

                        decimal gpuHr = -1;

                        try
                        {
                            int gpuId;
                            if (int.TryParse(temp.InstanceId.Substring(temp.InstanceId.LastIndexOf("/", StringComparison.Ordinal) + 1), out gpuId))
                            {
                                lock (RecentGpuHashrates)
                                {
                                    if (RecentGpuHashrates.ContainsKey(gpuId) && RecentGpuHashrates[gpuId].Count > 0)
                                    {
                                        gpuHr = decimal.Round(RecentGpuHashrates[gpuId].Average(), 2);
                                        PrettyConsole.Write($" ({gpuHr} {_units}/s)", ConsoleColor.Gray);
                                    }
                                }
                            }
                        }
                        catch (Exception)
                        {
                            //Do nothing
                        }
                        finally
                        {
                            PrettyConsole.WriteLine();
                        }


                        gpus.Add(new Gpu
                        {
                            Color = outputColor.ToString(),
                            Name  = temp.InstanceName,
                            Id    = temp.InstanceId,
                            Temp  = (int)temp.CurrentValue,
                            Rate  = gpuHr
                        });

                        if (temp.CurrentValue > MaxTemp)
                        {
                            Log.Error($"Killing miner, GPU Temperature is {temp.CurrentValue}°c but the max is set for {MaxTemp}°c");

                            //Hard shut down
                            //Exit(1);

                            //Soft shut down
                            KillMiner();
                            Pause();
                        }
                    }

                    //Check average hash rate
                    decimal      averageHashrate = 0;
                    ConsoleColor hashrateColor   = ConsoleColor.Red;
                    if (RecentHashrates.Count > 0)
                    {
                        Queue <decimal> localQueue = new Queue <decimal>(RecentHashrates);
                        averageHashrate = decimal.Round(localQueue.Average(), 3);

                        hashrateColor = ConsoleColor.Green;
                        if (averageHashrate < _currentMiningConfig.HashrateError)
                        {
                            hashrateColor = ConsoleColor.Red;
                            if (localQueue.Count == TotalReadingsToAverage)
                            {
                                var error = $"Average Hashrate {averageHashrate} dropped below configured error rate ({_currentMiningConfig.HashrateError}). Killing miner.";
                                Log.Error(error);
                                KillMiner();
                            }
                        }
                        else if (averageHashrate < _currentMiningConfig.HashrateWarning)
                        {
                            hashrateColor = ConsoleColor.Yellow;
                            if (localQueue.Count == TotalReadingsToAverage)
                            {
                                Log.Warning($"Average Hashrate {averageHashrate} dropped below configured warning rate {_currentMiningConfig.HashrateWarning}.");
                            }
                        }

                        if (localQueue.Count > 0)
                        {
                            PrettyConsole.Write(@"Current Average Hashrate: ");

                            PrettyConsole.Write($"{averageHashrate} {_units}/s", hashrateColor);

                            PrettyConsole.WriteLine();
                        }

                        PrettyConsole.Write(@"Solutions Found: ");
                        PrettyConsole.Write($"{_solutionsFound}", _solutionsFound > 0 ? ConsoleColor.Green : ConsoleColor.Yellow);

                        if (_rejectedSolutions > 0)
                        {
                            PrettyConsole.Write(@". Rejected: ");
                            PrettyConsole.Write($"{_rejectedSolutions}", ConsoleColor.Red);
                        }

                        PrettyConsole.WriteLine(@".");
                    }

                    UpdateMonitoringSockets(gpus, cpus, averageHashrate, hashrateColor);

                    //foreach (var config in _miners)
                    //{
                    //    PrettyConsole.WriteLine($"({config.Wallet}){WalletHelper.GetWalletBalance(config.CurrencyCode, config.Wallet)}", ConsoleColor.DarkGreen);
                    //}

                    Thread.Sleep(10000);

                    if (File.Exists("stop.txt"))
                    {
                        File.Delete("stop.txt");
                        _running = false;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);

                if (_running)
                {
                    Log.Warning(ex);
                    Log.Informational("Attempting to restart from the beginning...");
                    goto Startup;
                }
            }

            KillMiner();
            Exit();
        }