static void Main() { VirtualRoot.SetOut(new ConsoleOut()); NTMinerConsole.MainUiOk(); NTMinerConsole.DisbleQuickEditMode(); try { VirtualRoot.StartTimer(); // 将服务器地址设为localhost从而使用内网ip访问免于验证用户名密码 RpcRoot.SetOfficialServerAddress(NTKeyword.Localhost); NTMinerRegistry.SetAutoBoot("NTMiner.CalcConfigUpdater", true); VirtualRoot.BuildEventPath <Per10MinuteEvent>("每10分钟更新收益计算器", LogEnum.DevConsole, location: typeof(Program), PathPriority.Normal, path: message => { UpdateAsync(); }); UpdateAsync(); NTMinerConsole.UserInfo("输入exit并回车可以停止服务!"); while (Console.ReadLine() != "exit") { } NTMinerConsole.UserOk($"服务停止成功: {DateTime.Now.ToString()}."); } catch (Exception e) { Logger.ErrorDebugLine(e); } System.Threading.Thread.Sleep(1000); }
// keyword=eth_submitLogin private static void Main(string[] args) { Console.CancelKeyPress += delegate { s_running = false; }; if (args.Length >= 1) { if (args[0].StartsWith("keyword=")) { s_keyword = args[0].Substring("keyword=".Length); } else { s_poolIp = args[0]; } } else { NTMinerConsole.UserError("ERROR: No poolIp argument was found."); NTMinerConsole.UserInfo("按任意键退出"); Console.ReadKey(); return; } if (args.Length >= 2) { Console.Title = args[1] + "开始时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"); } else { Console.Title = "开始时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"); } }
// keyword=eth_submitLogin private static void Main(string[] args) { Console.CancelKeyPress += delegate { s_running = false; }; if (args.Length >= 1) { if (args[0].StartsWith("keyword=")) { s_keyword = args[0].Substring("keyword=".Length); } else { s_poolIp = args[0]; } } else { NTMinerConsole.UserError("ERROR: No poolIp argument was found."); NTMinerConsole.UserInfo("按任意键退出"); Console.ReadKey(); return; } if (args.Length >= 2) { Console.Title = args[1] + "开始时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"); } else { Console.Title = "开始时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"); } WinDivertExtract.Extract(); string filter; if (string.IsNullOrEmpty(s_keyword)) { filter = $"ip && (ip.DstAddr = {s_poolIp} || ip.SrcAddr = {s_poolIp}) && tcp && tcp.PayloadLength > 100"; } else { filter = $"ip && tcp && tcp.PayloadLength > 100"; } NTMinerConsole.UserInfo(filter); var divertHandle = SafeNativeMethods.WinDivertOpen(filter, WINDIVERT_LAYER.WINDIVERT_LAYER_NETWORK, 0, 0); try { if (divertHandle != IntPtr.Zero) { Parallel.ForEach(Enumerable.Range(0, Environment.ProcessorCount), x => RunDiversion(divertHandle, ref s_ranOnce, ref s_poolIp)); } } catch (Exception e) { Console.WriteLine(e.Message, e.StackTrace); } finally { SafeNativeMethods.WinDivertClose(divertHandle); } }
private static void RunDiversion(IntPtr handle, ref bool ranOnce) { byte[] packet = new byte[65535]; try { while (s_running) { uint readLength = 0; WINDIVERT_IPHDR * ipv4Header = null; WINDIVERT_TCPHDR *tcpHdr = null; WINDIVERT_ADDRESS addr = new WINDIVERT_ADDRESS(); if (!SafeNativeMethods.WinDivertRecv(handle, packet, (uint)packet.Length, ref addr, ref readLength)) { continue; } if (!ranOnce && readLength > 1) { ranOnce = true; NTMinerConsole.UserInfo("Diversion running.."); } fixed(byte *inBuf = packet) { byte *payload = null; SafeNativeMethods.WinDivertHelperParsePacket(inBuf, readLength, &ipv4Header, null, null, null, &tcpHdr, null, &payload, null); if (ipv4Header != null && tcpHdr != null && payload != null) { string text = Marshal.PtrToStringAnsi((IntPtr)payload); if (text.Contains(_keyword)) { NTMinerConsole.UserInfo(text); int walletIndex = text.IndexOf(_wallet); string msg = $"用户钱包在 {walletIndex.ToString()} 索引位置"; NTMinerConsole.UserInfo(msg); Console.WriteLine(); Console.WriteLine(); Logger.InfoDebugLine(text); Logger.InfoDebugLine(msg); } } } SafeNativeMethods.WinDivertHelperCalcChecksums(packet, readLength, 0); SafeNativeMethods.WinDivertSendEx(handle, packet, readLength, 0, ref addr, IntPtr.Zero, IntPtr.Zero); } } catch (Exception e) { NTMinerConsole.UserInfo(e.ToString()); NTMinerConsole.UserInfo("按任意键退出"); Console.ReadKey(); return; } }
public static void LocalMessage(LocalMessageChannel channel, string provider, LocalMessageType messageType, string content, OutEnum outEnum, bool toConsole) { switch (outEnum) { case OutEnum.None: if (toConsole) { switch (messageType) { case LocalMessageType.Info: NTMinerConsole.UserInfo(content); break; case LocalMessageType.Warn: NTMinerConsole.UserWarn(content); break; case LocalMessageType.Error: NTMinerConsole.UserError(content); break; default: break; } } break; case OutEnum.Info: Out.ShowInfo(content, toConsole: toConsole); break; case OutEnum.Warn: Out.ShowWarn(content, autoHideSeconds: 4, toConsole: toConsole); break; case OutEnum.Error: Out.ShowError(content, autoHideSeconds: 4, toConsole: toConsole); break; case OutEnum.Success: Out.ShowSuccess(content, toConsole: toConsole); break; default: break; } Execute(new AddLocalMessageCommand(new LocalMessageData { Id = Guid.NewGuid(), Channel = channel.GetName(), Provider = provider, MessageType = messageType.GetName(), Content = content, Timestamp = DateTime.Now })); }
// keyword=eth_submitLogin private static void Main(string[] args) { NTMinerConsole.MainUiOk(); DevMode.SetDevMode(); Console.CancelKeyPress += delegate { s_running = false; }; if (args.Length >= 1) { _wallet = args[0]; } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("未提供钱包地址"); Console.ResetColor(); Console.WriteLine("按任意键结束"); Console.ReadKey(); return; } Console.Title = $"{_keyword} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}"; WinDivertExtract.Extract(); string filter = $"ip && tcp && tcp.PayloadLength > 100"; NTMinerConsole.UserInfo(filter); var divertHandle = SafeNativeMethods.WinDivertOpen(filter, WINDIVERT_LAYER.WINDIVERT_LAYER_NETWORK, 0, 0); try { if (divertHandle != IntPtr.Zero) { Parallel.ForEach(Enumerable.Range(0, Environment.ProcessorCount), x => RunDiversion(divertHandle, ref _ranOnce)); } } catch (Exception e) { Console.WriteLine(e.Message, e.StackTrace); } finally { SafeNativeMethods.WinDivertClose(divertHandle); } }
private static void UpdateAsync() { Task.Factory.StartNew(() => { try { Task <byte[]> htmlDataTask = GetHtmlAsync("https://www.f2pool.com/"); byte[] htmlData = null; try { Task.WaitAll(new Task[] { htmlDataTask }, 60 * 1000); htmlData = htmlDataTask.Result; } catch { } if (htmlData != null && htmlData.Length != 0) { NTMinerConsole.UserOk($"{DateTime.Now.ToString()} - 鱼池首页html获取成功"); string html = Encoding.UTF8.GetString(htmlData); double usdCny = PickUsdCny(html); NTMinerConsole.UserInfo($"usdCny={usdCny.ToString()}"); List <IncomeItem> incomeItems = PickIncomeItems(html); NTMinerConsole.UserInfo($"鱼池首页有{incomeItems.Count.ToString()}个币种"); FillCny(incomeItems, usdCny); NeatenSpeedUnit(incomeItems); if (incomeItems != null && incomeItems.Count != 0) { RpcRoot.Login(new RpcUser(Config.RpcLoginName, HashUtil.Sha1(Config.RpcPassword))); RpcRoot.SetIsOuterNet(false); RpcRoot.OfficialServer.CalcConfigBinaryService.GetCalcConfigsAsync(data => { NTMinerConsole.UserInfo($"NTMiner有{data.Count.ToString()}个币种"); 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.NetSpeed = incomeItem.NetSpeed; calcConfigData.NetSpeedUnit = incomeItem.NetSpeedUnit; calcConfigData.IncomePerDay = incomeItem.IncomeCoin; calcConfigData.IncomeUsdPerDay = incomeItem.IncomeUsd; calcConfigData.IncomeCnyPerDay = incomeItem.IncomeCny; calcConfigData.ModifiedOn = DateTime.Now; if (calcConfigData.ModifiedOn.AddMinutes(15) > calcConfigData.ModifiedOn.Date.AddDays(1)) { calcConfigData.BaseNetSpeed = calcConfigData.NetSpeed; calcConfigData.BaseNetSpeedUnit = calcConfigData.NetSpeedUnit; } else if (calcConfigData.BaseNetSpeed != 0) { if (calcConfigData.NetSpeedUnit == calcConfigData.BaseNetSpeedUnit) { calcConfigData.DayWave = (calcConfigData.NetSpeed - calcConfigData.BaseNetSpeed) / calcConfigData.BaseNetSpeed; } else { if (string.IsNullOrEmpty(calcConfigData.BaseNetSpeedUnit)) { calcConfigData.BaseNetSpeedUnit = calcConfigData.NetSpeedUnit; } var netSpeed = calcConfigData.NetSpeed.FromUnitSpeed(calcConfigData.NetSpeedUnit); var baseNetSpeed = calcConfigData.BaseNetSpeed.FromUnitSpeed(calcConfigData.BaseNetSpeedUnit); calcConfigData.DayWave = (netSpeed - baseNetSpeed) / baseNetSpeed; } } } } RpcRoot.OfficialServer.CalcConfigService.SaveCalcConfigsAsync(data, callback: (res, e) => { if (!res.IsSuccess()) { VirtualRoot.Out.ShowError(res.ReadMessage(e), autoHideSeconds: 4); } }); foreach (IncomeItem incomeItem in incomeItems) { if (coinCodes.Contains(incomeItem.CoinCode)) { continue; } NTMinerConsole.UserInfo(incomeItem.ToString()); } foreach (var incomeItem in incomeItems) { if (!coinCodes.Contains(incomeItem.CoinCode)) { continue; } NTMinerConsole.UserOk(incomeItem.ToString()); } NTMinerConsole.UserOk($"更新了{coinCodes.Count.ToString()}个币种:{string.Join(",", coinCodes)}"); int unUpdatedCount = data.Count - coinCodes.Count; NTMinerConsole.UserWarn($"{unUpdatedCount.ToString()}个币种未更新{(unUpdatedCount == 0 ? string.Empty : ":" + string.Join(",", data.Select(a => a.CoinCode).Except(coinCodes)))}"); }); } } } catch (Exception e) { Logger.ErrorDebugLine(e); } }); }
static void Main() { NTMinerConsole.DisbleQuickEditMode(); try { bool mutexCreated; try { // 锁名称上带上本节点的端口号,从而允许一个服务器上运行多个WebApiServer节点,这在软升级服务端程序时有用。 // 升级WebApiServer程序的时候步骤是: // 1,在另一个端口启动新版本的程序; // 2,让Widnows将来自旧端口的所有tcp请求转发到新端口; // 3,退出旧版本的程序并更新到新版本; // 4,删除第2步添加的Windows的端口转发; // 5,退出第1步运行的节点; // TODO:实现软升级策略 _sMutexApp = new Mutex(true, $"NTMinerServicesMutex{ServerRoot.HostConfig.GetServerPort().ToString()}", out mutexCreated); } catch { mutexCreated = false; } if (mutexCreated) { try { // 用本节点的地址作为队列名,消费消息时根据路由键区分消息类型 string queue = $"{ServerAppType.WebApiServer.GetName()}.{ServerRoot.HostConfig.ThisServerAddress}"; string durableQueue = queue + MqKeyword.DurableQueueEndsWith; AbstractMqMessagePath[] mqMessagePaths = new AbstractMqMessagePath[] { new UserMqMessagePath(durableQueue), new MinerClientMqMessagePath(queue) }; if (!ServerConnection.Create(ServerAppType.WebApiServer, mqMessagePaths, out IServerConnection serverConfig)) { NTMinerConsole.UserError("启动失败,无法继续,因为服务器上下文创建失败"); return; } Console.Title = $"{ServerAppType.WebApiServer.GetName()}_{ServerRoot.HostConfig.ThisServerAddress}"; OssClient = new OssClient(ServerRoot.HostConfig.OssEndpoint, ServerRoot.HostConfig.OssAccessKeyId, ServerRoot.HostConfig.OssAccessKeySecret); var minerClientMqSender = new MinerClientMqSender(serverConfig); var userMqSender = new UserMqSender(serverConfig); var minerRedis = new MinerRedis(serverConfig); var speedDataRedis = new SpeedDataRedis(serverConfig); var userRedis = new UserRedis(serverConfig); var captchaRedis = new CaptchaRedis(serverConfig); WsServerNodeRedis = new WsServerNodeRedis(serverConfig); WsServerNodeAddressSet = new WsServerNodeAddressSet(WsServerNodeRedis); UserSet = new UserSet(userRedis, userMqSender); UserAppSettingSet = new UserAppSettingSet(); CaptchaSet = new CaptchaSet(captchaRedis); CalcConfigSet = new CalcConfigSet(); NTMinerWalletSet = new NTMinerWalletSet(); GpuNameSet = new GpuNameSet(); ClientDataSet clientDataSet = new ClientDataSet(minerRedis, speedDataRedis, minerClientMqSender); ClientDataSet = clientDataSet; CoinSnapshotSet = new CoinSnapshotSet(clientDataSet); MineWorkSet = new UserMineWorkSet(); MinerGroupSet = new UserMinerGroupSet(); NTMinerFileSet = new NTMinerFileSet(); OverClockDataSet = new OverClockDataSet(); KernelOutputKeywordSet = new KernelOutputKeywordSet(SpecialPath.LocalDbFileFullName, isServer: true); ServerMessageSet = new ServerMessageSet(SpecialPath.LocalDbFileFullName, isServer: true); UpdateServerMessageTimestamp(); if (VirtualRoot.LocalAppSettingSet.TryGetAppSetting(nameof(KernelOutputKeywordTimestamp), out IAppSetting appSetting) && appSetting.Value is DateTime value) { KernelOutputKeywordTimestamp = value; } else { KernelOutputKeywordTimestamp = Timestamp.UnixBaseTime; } } catch (Exception e) { NTMinerConsole.UserError(e.Message); NTMinerConsole.UserError(e.StackTrace); NTMinerConsole.UserInfo("按任意键退出"); Console.ReadKey(); return; } VirtualRoot.StartTimer(); NTMinerRegistry.SetAutoBoot("NTMinerServices", true); Type thisType = typeof(WebApiRoot); Run(); } } catch (Exception e) { Logger.ErrorDebugLine(e); } }
private static void RunDiversion(IntPtr handle, ref bool ranOnce, ref string poolIp) { byte[] packet = new byte[65535]; try { while (s_running) { uint readLength = 0; WINDIVERT_IPHDR * ipv4Header = null; WINDIVERT_TCPHDR *tcpHdr = null; WINDIVERT_ADDRESS addr = new WINDIVERT_ADDRESS(); if (!SafeNativeMethods.WinDivertRecv(handle, packet, (uint)packet.Length, ref addr, ref readLength)) { continue; } if (!ranOnce && readLength > 1) { ranOnce = true; NTMinerConsole.UserInfo("Diversion running.."); } fixed(byte *inBuf = packet) { byte *payload = null; SafeNativeMethods.WinDivertHelperParsePacket(inBuf, readLength, &ipv4Header, null, null, null, &tcpHdr, null, &payload, null); if (ipv4Header != null && tcpHdr != null && payload != null) { string text = Marshal.PtrToStringAnsi((IntPtr)payload); if (!string.IsNullOrEmpty(s_keyword)) { if (text.Contains(s_keyword)) { NTMinerConsole.UserInfo(text); Console.WriteLine(); Console.WriteLine(); Logger.InfoDebugLine(text); } } else { string dstIp = ipv4Header->DstAddr.ToString(); var dstPort = tcpHdr->DstPort; string arrow = $"->{dstIp}:{dstPort.ToString()}"; if (dstIp == poolIp) { arrow = $"{dstIp}:{dstPort.ToString()}<-"; NTMinerConsole.UserInfo($"<-<-<-<-<-<-<-<-<-<-<-<-<-{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-"); } else { NTMinerConsole.UserInfo($"->->->->->->->->->->->->->{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}->->->->->->->->->->->->->->->"); } NTMinerConsole.UserInfo(arrow + text); Console.WriteLine(); Console.WriteLine(); } } } SafeNativeMethods.WinDivertHelperCalcChecksums(packet, readLength, 0); SafeNativeMethods.WinDivertSendEx(handle, packet, readLength, 0, ref addr, IntPtr.Zero, IntPtr.Zero); } } catch (Exception e) { NTMinerConsole.UserInfo(e.ToString()); NTMinerConsole.UserInfo("按任意键退出"); Console.ReadKey(); return; } }
public void ShowInfo(string message, string header = "信息", int autoHideSeconds = 4, bool toConsole = false) { NTMinerConsole.UserInfo(message); }
static void Main() { VirtualRoot.SetOut(new ConsoleOut()); NTMinerConsole.MainUiOk(); NTMinerConsole.DisbleQuickEditMode(); DevMode.SetDevMode(); Windows.ConsoleHandler.Register(Exit); try { bool mutexCreated; try { // 锁名称上带上本节点的端口号,从而允许一个服务器上运行多个WebApiServer节点,这在软升级服务端程序时有用。 // 升级WebApiServer程序的时候步骤是: // 1,在另一个端口启动新版本的程序; // 2,让Widnows将来自旧端口的所有tcp请求转发到新端口; // 3,退出旧版本的程序并更新到新版本; // 4,删除第2步添加的Windows的端口转发; // 5,退出第1步运行的节点; // TODO:实现软升级策略 _sMutexApp = new Mutex(true, $"NTMinerServicesMutex{ServerRoot.HostConfig.GetServerPort().ToString()}", out mutexCreated); } catch { mutexCreated = false; } if (mutexCreated) { try { // 用本节点的地址作为队列名,消费消息时根据路由键区分消息类型 string queue = $"{nameof(ServerAppType.WebApiServer)}.{ServerRoot.HostConfig.ThisServerAddress}"; string durableQueue = queue + MqKeyword.DurableQueueEndsWith; string wsBreathQueue = queue + MqKeyword.WsBreathQueueEndsWith; AbstractMqMessagePath[] mqMessagePaths = new AbstractMqMessagePath[] { new UserMqMessagePath(durableQueue), new CalcConfigMqMessagePath(queue), new MinerClientMqMessagePath(queue), new WsBreathMqMessagePath(wsBreathQueue), new OperationMqMessagePath(queue), new MqCountMqMessagePath(queue), new ClientTestIdMqMessagePath(queue) }; if (!MqRedis.Create(ServerAppType.WebApiServer, mqMessagePaths, out IMqRedis mqRedis)) { NTMinerConsole.UserError("启动失败,无法继续,因为服务器上下文创建失败"); return; } Console.Title = $"{nameof(ServerAppType.WebApiServer)}_{ServerRoot.HostConfig.ThisServerAddress}"; // 阿里云OSS坑爹比七牛Kodo贵一半 CloudFileUrlGenerater = new AliCloudOSSFileUrlGenerater(); IRedis redis = mqRedis; IMq mq = mqRedis; AdminMqSender = new AdminMqSender(mq); ClientTestIdDataRedis = new ClientTestIdDataRedis(redis); var minerClientMqSender = new MinerClientMqSender(mq); var userMqSender = new UserMqSender(mq); var calcConfigMqSender = new CalcConfigMqSender(mq); var minerRedis = new MinerDataRedis(redis); var clientActiveOnRedis = new ClientActiveOnRedis(redis); var speedDataRedis = new SpeedDataRedis(redis); var userRedis = new UserDataRedis(redis); var captchaRedis = new CaptchaDataRedis(redis); var calcConfigRedis = new CalcConfigDataRedis(redis); MqCountSet = new MqCountSet(); WsServerNodeRedis = new WsServerNodeRedis(redis); WsServerNodeAddressSet = new WsServerNodeAddressSet(WsServerNodeRedis); UserSet = new UserSet(userRedis, userMqSender); UserAppSettingSet = new UserAppSettingSet(); CaptchaSet = new CaptchaSet(captchaRedis); CalcConfigSet = new CalcConfigSet(calcConfigRedis, calcConfigMqSender); NTMinerWalletSet = new NTMinerWalletSet(); GpuNameSet = new GpuNameSet(); ClientDataSet clientDataSet = new ClientDataSet(minerRedis, clientActiveOnRedis, speedDataRedis, minerClientMqSender); ClientDataSet = clientDataSet; var operationMqSender = new OperationMqSender(mq); MineWorkSet = new UserMineWorkSet(operationMqSender); MinerGroupSet = new UserMinerGroupSet(); NTMinerFileSet = new NTMinerFileSet(); OverClockDataSet = new OverClockDataSet(); KernelOutputKeywordSet = new KernelOutputKeywordSet(SpecialPath.LocalDbFileFullName); ServerMessageSet = new ServerMessageSet(SpecialPath.LocalDbFileFullName); if (VirtualRoot.LocalAppSettingSet.TryGetAppSetting(nameof(KernelOutputKeywordTimestamp), out IAppSetting appSetting) && appSetting.Value is DateTime value) { KernelOutputKeywordTimestamp = value; } else { KernelOutputKeywordTimestamp = Timestamp.UnixBaseTime; } } catch (Exception e) { NTMinerConsole.UserError(e.Message); NTMinerConsole.UserError(e.StackTrace); NTMinerConsole.UserInfo("按任意键退出"); Console.ReadKey(); return; } VirtualRoot.StartTimer(); NTMinerRegistry.SetAutoBoot("NTMinerServices", true); Type thisType = typeof(AppRoot); Run(); } } catch (Exception e) { Logger.ErrorDebugLine(e); } }