public MinerClientMessagesViewModel() { if (_called) { throw new InvalidProgramException("只能调用一次"); } _called = true; if (WpfUtil.IsInDesignMode) { return; } VirtualRoot.AddEventPath <MinerClientSelectionChangedEvent>("矿机列表页选中了和上次选中的不同的矿机时刷新矿机消息列表", LogEnum.DevConsole, action: message => { bool isChanged = true; if (message.MinerClientVm != null && this._minerClientVm != null && this._minerClientVm.ClientId == message.MinerClientVm.ClientId) { isChanged = false; } if (isChanged) { lock (_locker) { _vms.Clear(); this._minerClientVm = message.MinerClientVm; OnPropertyChanged(nameof(IsNoRecord)); } SendGetLocalMessagesMqMessage(); } }, this.GetType()); VirtualRoot.AddEventPath <ClientLocalMessagesEvent>("收到了挖矿端本地消息", LogEnum.DevConsole, action: message => { if (this._minerClientVm == null || this._minerClientVm.ClientId != message.ClientId) { return; } if (message.Data == null || message.Data.Count == 0) { return; } UIThread.Execute(() => { foreach (var item in message.Data) { _vms.Insert(0, new LocalMessageDtoViewModel(item)); } OnPropertyChanged(nameof(IsNoRecord)); }); }, location: this.GetType()); VirtualRoot.AddEventPath <Per5SecondEvent>("周期获取当前选中的那台矿机的本地消息", LogEnum.DevConsole, action: message => { SendGetLocalMessagesMqMessage(); }, this.GetType()); }
public MainMenuViewModel() { if (WpfUtil.IsInDesignMode) { return; } VirtualRoot.AddEventPath <MinerStudioServiceSwitchedEvent>("群控后台客户端服务类型切换后刷新菜单的展示状态", LogEnum.DevConsole, action: message => { this.OnPropertyChanged(nameof(LoginName)); this.OnPropertyChanged(nameof(IsMinerStudioLocalOrOuterAdminVisible)); this.OnPropertyChanged(nameof(IsMinerStudioOuterAdmin)); this.OnPropertyChanged(nameof(IsMinerStudioOuterAdminVisible)); this.OnPropertyChanged(nameof(IsMinerStudioOuterVisible)); this.OnPropertyChanged(nameof(IsMinerStudioLocalVisible)); }, this.GetType()); }
public WsServerNodeSet(IWsServerNodeMqSender mqSender) { _mqSender = mqSender; VirtualRoot.AddEventPath <Per20SecondEvent>("周期将不活跃的节点移除", LogEnum.DevConsole, action: message => { DateTime activeOn = DateTime.Now.AddSeconds(-message.Seconds); var toRemoves = _dicByIp.Values.Where(a => a.ActiveOn < activeOn).ToArray(); foreach (var item in toRemoves) { this.RemoveNode(item.Address); } if (toRemoves.Length != 0) { Write.UserInfo($"移除了 {toRemoves.Length.ToString()} 个节点"); } }, this.GetType()); }
public MainWindowViewModel() { this.Start = new DelegateCommand(() => { if (IsScanning) { IsScanning = false; } else { if (_fromIpAddressVm.IsAnyEmpty || _toIpAddressVm.IsAnyEmpty) { throw new ValidationException("IP地址不能为空"); } if (!IPAddress.TryParse(_fromIpAddressVm.AddressText, out _) || !IPAddress.TryParse(_toIpAddressVm.AddressText, out _)) { throw new ValidationException("IP地址格式不正确"); } if (Results.Count != 0) { Results.Clear(); } List <string> ipList = Net.IpUtil.CreateIpRange(_fromIpAddressVm.AddressText, _toIpAddressVm.AddressText); Task.Factory.StartNew(() => { Scan(ipList.ToArray()); }); } }); VirtualRoot.AddEventPath <LocalIpSetInitedEvent>("本机IP集刷新后刷新状态栏", LogEnum.DevConsole, action: message => { LocalIps = GetLocalIps(); }, location: this.GetType()); Task.Factory.StartNew(() => { var localIp = VirtualRoot.LocalIpSet.AsEnumerable().FirstOrDefault(); if (localIp != null) { if (!string.IsNullOrEmpty(localIp.DefaultIPGateway)) { string[] parts = localIp.DefaultIPGateway.Split('.'); parts[parts.Length - 1] = "1"; this.FromIpAddressVm = new IpAddressViewModel(string.Join(".", parts)); parts[parts.Length - 1] = "254"; this.ToIpAddressVm = new IpAddressViewModel(string.Join(".", parts)); } } LocalIps = GetLocalIps(); }); }
public LocalMessageSet() { if (ClientAppType.IsMinerClient) { LocalMessageDtoSet = new LocalMessageDtoSet(); } VirtualRoot.AddCmdPath <AddLocalMessageCommand>(action: message => { InitOnece(); var data = LocalMessageData.Create(message.Input); List <ILocalMessage> removeds = new List <ILocalMessage>(); lock (_locker) { _records.AddFirst(data); _dbToInserts.Add(data); while (_records.Count > NTKeyword.LocalMessageSetCapacity) { var toRemove = _records.Last.Value; removeds.Add(toRemove); _records.RemoveLast(); } _dbToRemoveIds.AddRange(removeds.Select(a => a.Id)); } LocalMessageDtoSet.Add(data.ToDto()); VirtualRoot.RaiseEvent(new LocalMessageAddedEvent(message.MessageId, data, removeds)); }, location: this.GetType()); VirtualRoot.AddCmdPath <ClearLocalMessageSetCommand>(action: message => { lock (_locker) { _records.Clear(); _dbToRemoveIds.Clear(); _dbToInserts.Clear(); } try { using (LiteDatabase db = new LiteDatabase(ConnString)) { db.DropCollection(nameof(LocalMessageData)); } } catch (Exception e) { Logger.ErrorDebugLine(e); } VirtualRoot.RaiseEvent(new LocalMessageSetClearedEvent()); }, location: this.GetType()); VirtualRoot.AddEventPath <Per1MinuteEvent>("周期保存LocalMessage到数据库", LogEnum.DevConsole, action: message => { SaveToDb(); }, this.GetType()); VirtualRoot.AddEventPath <AppExitEvent>("程序退出时保存LocalMessage到数据库", LogEnum.DevConsole, action: message => { SaveToDb(); }, this.GetType()); }
internal CoinSnapshotSet(IHostRoot root) { _root = root; VirtualRoot.AddEventPath <Per10SecondEvent>("周期性拍摄快照", LogEnum.DevConsole, action: message => { Snapshot(message.BornOn); }, location: this.GetType()); VirtualRoot.AddEventPath <Per2MinuteEvent>("周期性拍摄快照", LogEnum.DevConsole, action: message => { DateTime time = DateTime.Now.AddMinutes(-20); List <CoinSnapshotData> toRemoves = _dataList.Where(a => a.Timestamp < time).ToList(); foreach (var item in toRemoves) { _dataList.Remove(item); } }, location: this.GetType()); }
public GpuNameSet(IGpuNameRedis gpuNameRedis) { _gpuNameRedis = gpuNameRedis; gpuNameRedis.GetAllAsync().ContinueWith(t => { foreach (var item in t.Result) { _gpuNameSet.Add(item); } IsReadied = true; }); VirtualRoot.AddEventPath <ClientSetInitedEvent>("矿机列表初始化后计算显卡名称集合", LogEnum.DevConsole, action: message => { Init(); }, this.GetType()); VirtualRoot.AddEventPath <Per10MinuteEvent>("周期刷新显卡名称集合", LogEnum.DevConsole, action: message => { Init(); }, this.GetType()); }
internal ClientSet() { GetSpeed(); VirtualRoot.AddEventPath <Per20SecondEvent>("周期性将内存中3分钟内活跃的ClientData列表刷入磁盘", LogEnum.DevConsole, action: message => { InitOnece(); List <MinerData> minerDatas = new List <MinerData>(); lock (_locker) { DateTime time = message.BornOn.AddMinutes(-3); foreach (var clientData in _dicByObjectId.Values) { if (clientData.ModifiedOn > time) { minerDatas.Add(new MinerData { CreatedOn = clientData.CreatedOn, GroupId = clientData.GroupId, Id = clientData.Id, ClientId = clientData.ClientId, ClientName = clientData.ClientName, MinerIp = clientData.MinerIp, MACAddress = clientData.MACAddress, MinerName = clientData.MinerName, WindowsLoginName = clientData.WindowsLoginName, WindowsPassword = clientData.WindowsPassword, WorkId = clientData.WorkId }); } else { clientData.IsMining = false; clientData.MainCoinSpeed = 0; clientData.DualCoinSpeed = 0; foreach (var item in clientData.GpuTable) { item.MainCoinSpeed = 0; item.DualCoinSpeed = 0; } } } } using (LiteDatabase db = HostRoot.CreateLocalDb()) { var col = db.GetCollection <MinerData>(); col.Upsert(minerDatas); } }, location: this.GetType()); }
public MineWorkSet() { VirtualRoot.AddEventPath <MinerStudioServiceSwitchedEvent>("切换了群口后台服务类型后刷新内存", LogEnum.DevConsole, action: message => { _dicById.Clear(); _isInited = false; // 初始化以触发MineWorkSetInitedEvent事件 InitOnece(); }, this.GetType()); VirtualRoot.AddCmdPath <AddMineWorkCommand>(action: message => { InitOnece(); if (!_dicById.ContainsKey(message.Input.Id)) { var repository = VirtualRoot.CreateLocalRepository <MineWorkData>(); var data = new MineWorkData().Update(message.Input); data.CreatedOn = DateTime.Now; _dicById.Add(data.Id, data); repository.Add(data); VirtualRoot.RaiseEvent(new MineWorkAddedEvent(message.MessageId, data)); } }, this.GetType()); VirtualRoot.AddCmdPath <UpdateMineWorkCommand>(action: message => { InitOnece(); if (_dicById.TryGetValue(message.Input.Id, out MineWorkData data)) { var repository = VirtualRoot.CreateLocalRepository <MineWorkData>(); data.Update(message.Input); data.ModifiedOn = DateTime.Now; repository.Update(data); VirtualRoot.RaiseEvent(new MineWorkUpdatedEvent(message.MessageId, data)); } }, this.GetType()); VirtualRoot.AddCmdPath <RemoveMineWorkCommand>(action: message => { InitOnece(); if (_dicById.TryGetValue(message.EntityId, out MineWorkData entity)) { _dicById.Remove(message.EntityId); var repository = VirtualRoot.CreateLocalRepository <MineWorkData>(); repository.Remove(message.EntityId); MinerStudioPath.DeleteMineWorkFiles(message.EntityId); VirtualRoot.RaiseEvent(new MineWorkRemovedEvent(message.MessageId, entity)); } }, this.GetType()); }
public AbstractWsClient(NTMinerAppType appType) { _appType = appType; VirtualRoot.AddEventPath <Per1SecondEvent>("重试Ws连接的秒表倒计时", LogEnum.None, action: message => { if (NextTrySecondsDelay > 0) { NextTrySecondsDelay--; } }, typeof(VirtualRoot)); VirtualRoot.AddEventPath <Per10SecondEvent>("周期检查Ws连接", LogEnum.None, action: message => { if (_continueCount >= _failConnCount) { _continueCount = 0; OpenOrCloseWs(); } else { _continueCount++; } }, typeof(VirtualRoot)); VirtualRoot.AddEventPath <Per20SecondEvent>("周期Ws Ping", LogEnum.None, action: message => { try { if (_ws != null && _ws.ReadyState == WebSocketState.Open) { // 或者_ws.IsAlive,因为_ws.IsAlive内部也是一个Ping,所以用Ping从而显式化这里有个网络请求 Task.Factory.StartNew(() => { if (!_ws.Ping()) { _ws.CloseAsync(CloseStatusCode.Away); } }); } } catch (Exception e) { Logger.ErrorDebugLine(e); } }, typeof(VirtualRoot)); VirtualRoot.AddEventPath <AppExitEvent>("退出程序时关闭Ws连接", LogEnum.DevConsole, action: message => { _ws?.CloseAsync(CloseStatusCode.Normal, "客户端程序退出"); }, this.GetType()); OpenOrCloseWs(); }
public WsServerNodeAddressSet(IWsServerNodeRedis wsServerNodeRedis, IWsServerNodeMqSender wsServerNodeMqSender) : base(wsServerNodeRedis) { _wsServerNodeRedis = wsServerNodeRedis; _wsServerNodeMqSender = wsServerNodeMqSender; VirtualRoot.AddOnecePath <WebSocketServerStatedEvent>("WebSocket服务启动后上报节点信息,获取节点列表", LogEnum.UserConsole, action: _ => { ReportNodeAsync(callback: () => { base.Init(callback: () => { NTMinerConsole.UserOk("Ws服务器节点地址集初始化完成"); VirtualRoot.RaiseEvent(new WsServerNodeAddressSetInitedEvent()); }); _wsServerNodeMqSender.SendWsServerNodeAdded(ServerRoot.HostConfig.ThisServerAddress); }); VirtualRoot.AddEventPath <Per10SecondEvent>("节点呼吸", LogEnum.UserConsole, action: message => { ReportNodeAsync(); }, this.GetType()); VirtualRoot.AddEventPath <Per1MinuteEvent>("打扫", LogEnum.DevConsole, action: message => { VirtualRoot.RaiseEvent(new CleanTimeArrivedEvent(AsEnumerable().ToArray())); }, this.GetType()); }, PathId.Empty, this.GetType()); }
public AbstractSessionSet(WebSocketSessionManager wsSessionManager) { this.WsSessionManager = wsSessionManager; VirtualRoot.AddEventPath <CleanTimeArrivedEvent>("打扫时间到,保持清洁", LogEnum.UserConsole, action: message => { ClearDeath(); SendReGetServerAddressMessage(message.NodeAddresses); }, this.GetType()); VirtualRoot.AddEventPath <UserDisabledMqMessage>("收到了UserDisabledMq消息后断开该用户的连接", LogEnum.UserConsole, action: message => { if (!string.IsNullOrEmpty(message.LoginName)) { TSession[] toCloses; lock (_locker) { toCloses = _dicByWsSessionId.Values.Where(a => a.LoginName == message.LoginName).ToArray(); } foreach (var item in toCloses) { item.CloseAsync(CloseStatusCode.Normal, "用户已被禁用"); } } }, this.GetType()); }
public GpusSpeed(INTMinerContext root) { _root = root; VirtualRoot.AddEventPath <Per10MinuteEvent>("周期清除过期的历史算力", LogEnum.DevConsole, action: message => { ClearOutOfDateHistory(); }, location: this.GetType()); VirtualRoot.AddEventPath <MineStopedEvent>("停止挖矿后产生一次0算力", LogEnum.DevConsole, action: message => { var now = DateTime.Now; foreach (var gpu in _root.GpuSet.AsEnumerable()) { SetCurrentSpeed(gpuIndex: gpu.Index, speed: 0.0, isDual: false, now: now); if (message.MineContext is IDualMineContext dualMineContext) { SetCurrentSpeed(gpuIndex: gpu.Index, speed: 0.0, isDual: true, now: now); } } }, location: this.GetType()); VirtualRoot.AddEventPath <MineStartedEvent>("挖矿开始时产生一次0算力0份额", LogEnum.DevConsole, action: message => { var now = DateTime.Now; _root.CoinShareSet.UpdateShare(message.MineContext.MainCoin.GetId(), 0, 0, now); _root.GpusSpeed.ResetShare(); foreach (var gpu in _root.GpuSet.AsEnumerable()) { SetCurrentSpeed(gpuIndex: gpu.Index, speed: 0.0, isDual: false, now: now); } if (message.MineContext is IDualMineContext dualMineContext) { _root.CoinShareSet.UpdateShare(dualMineContext.DualCoin.GetId(), 0, 0, now); foreach (var gpu in _root.GpuSet.AsEnumerable()) { SetCurrentSpeed(gpuIndex: gpu.Index, speed: 0.0, isDual: true, now: now); } } }, location: this.GetType()); }
public AbstractSessionSet(string wsServiceHostPath) { _wsServiceHostPath = wsServiceHostPath; VirtualRoot.AddEventPath <CleanTimeArrivedEvent>("打扫时间到,保持清洁", LogEnum.UserConsole, action: message => { ClearDeath(); SendReGetServerAddressMessage(message.NodeAddresses); }, this.GetType()); VirtualRoot.AddEventPath <UserDisabledMqMessage>("收到了UserDisabledMq消息后断开该用户的连接", LogEnum.UserConsole, action: message => { if (!string.IsNullOrEmpty(message.LoginName)) { if (TryGetWsSessions(out WebSocketSessionManager wsSessionManager)) { var toCloses = _dicByWsSessionId.Values.Where(a => a.LoginName == message.LoginName).ToArray(); foreach (var item in toCloses) { if (wsSessionManager.TryGetSession(item.WsSessionId, out IWebSocketSession session)) { session.Context.WebSocket.CloseAsync(CloseStatusCode.Normal, "用户已被禁用"); } } } }
public OperationResultSet() { VirtualRoot.AddEventPath <Per24HourEvent>("检查一下记录的操作记录是否多于容量,如果多了清理一下", LogEnum.DevConsole, action: message => { using (var db = VirtualRoot.CreateLocalDb()) { var col = db.GetCollection <OperationResultData>(); int count = col.Count(); if (count <= _capacityCount) { return; } var all = col.FindAll().OrderBy(a => a.Timestamp).ToList(); int toDeleteCount = all.Count - _capacityCount; if (toDeleteCount <= 0) { return; } for (int i = 0; i < toDeleteCount; i++) { col.Delete(all[i].Id); } } }, this.GetType()); }
public WsServerNodeAddressSetBase(IReadOnlyWsServerNodeRedis wsServerNodeRedis) { _wsServerNodeRedis = wsServerNodeRedis; VirtualRoot.AddEventPath <Per20SecondEvent>("周期从redis中刷新", LogEnum.DevConsole, action: message => { Init(); }, this.GetType()); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在WsServerNodeAddressSetInitedEvent事件之后才会创建 VirtualRoot.AddEventPath <WsServerNodeRemovedMqMessage>("收到移除了服务器节点Mq消息后敲响打扫时间到的铃声", LogEnum.UserConsole, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } Init(); }, this.GetType()); VirtualRoot.AddEventPath <WsServerNodeAddedMqMessage>("收到添加了服务器节点Mq消息后敲响打扫时间到的铃声", LogEnum.UserConsole, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } Init(); }, this.GetType()); Init(); }
public CoinSnapshotSetBase(bool isPull, IClientDataSetBase clientSet) { _isPull = isPull; _clientSet = clientSet; VirtualRoot.AddEventPath <Per10SecondEvent>("周期性拍摄快照", LogEnum.UserConsole, action: message => { Snapshot(message.BornOn); }, location: this.GetType()); VirtualRoot.AddEventPath <Per2MinuteEvent>("周期性移除20分钟前的快照", LogEnum.UserConsole, action: message => { DateTime time = message.BornOn.AddMinutes(-20); var toRemoves = _dataList.Where(a => a.Timestamp < time).ToArray(); foreach (var item in toRemoves) { _dataList.Remove(item); } }, location: this.GetType()); VirtualRoot.AddEventPath <HasBoot1MinuteEvent>("启动一会儿后清理一下很长时间之前的算力报告数据库文件", LogEnum.UserConsole, action: message => { ClearReportDbFiles(message.BornOn); }, this.GetType()); VirtualRoot.AddEventPath <Per24HourEvent>("每24小时清理一下很长时间之前的算力报告数据库文件", LogEnum.UserConsole, action: message => { ClearReportDbFiles(message.BornOn); }, this.GetType()); }
public MinerProfileViewModel() { if (WpfUtil.IsInDesignMode) { return; } if (Instance != null) { throw new InvalidProgramException(); } if (this.IsCreateShortcut) { CreateShortcut(); } this.Up = new DelegateCommand <string>(propertyName => { WpfUtil.Up(this, propertyName); }); this.Down = new DelegateCommand <string>(propertyName => { WpfUtil.Down(this, propertyName); }); this.WsRetry = new DelegateCommand(() => { RpcRoot.Client.NTMinerDaemonService.StartOrStopWsAsync(isResetFailCount: true); IsConnecting = true; }); if (ClientAppType.IsMinerClient) { VirtualRoot.AddCmdPath <SetAutoStartCommand>(message => { this.IsAutoStart = message.IsAutoStart; this.IsAutoBoot = message.IsAutoBoot; }, this.GetType(), LogEnum.None); VirtualRoot.AddEventPath <StartingMineFailedEvent>("开始挖矿失败", LogEnum.DevConsole, action: message => { IsMining = false; NTMinerConsole.UserError(message.Message); }, location: this.GetType()); // 群控客户端已经有一个执行RefreshWsStateCommand命令的路径了 VirtualRoot.AddCmdPath <RefreshWsStateCommand>(message => { #region if (message.WsClientState != null) { this.IsWsOnline = message.WsClientState.Status == WsClientStatus.Open; if (message.WsClientState.ToOut) { VirtualRoot.Out.ShowWarn(message.WsClientState.Description, autoHideSeconds: 3); } if (!message.WsClientState.ToOut || !this.IsWsOnline) { this.WsDescription = message.WsClientState.Description; } if (!this.IsWsOnline) { if (message.WsClientState.LastTryOn != DateTime.MinValue) { this.WsLastTryOn = message.WsClientState.LastTryOn; } if (message.WsClientState.NextTrySecondsDelay > 0) { WsNextTrySecondsDelay = message.WsClientState.NextTrySecondsDelay; } } } #endregion }, this.GetType(), LogEnum.DevConsole); VirtualRoot.AddEventPath <Per1SecondEvent>("外网群控重试秒表倒计时", LogEnum.None, action: message => { if (IsOuterUserEnabled && !IsWsOnline) { if (WsNextTrySecondsDelay > 0) { WsNextTrySecondsDelay--; } else if (WsLastTryOn == DateTime.MinValue) { this.RefreshWsDaemonState(); } OnPropertyChanged(nameof(WsLastTryOnText)); } }, this.GetType()); VirtualRoot.AddEventPath <WsServerOkEvent>("服务器Ws服务已可用", LogEnum.DevConsole, action: message => { if (IsOuterUserEnabled && !IsWsOnline) { StartOrStopWs(); } }, this.GetType()); } NTMinerContext.SetRefreshArgsAssembly((reason) => { NTMinerConsole.DevDebug(() => $"RefreshArgsAssembly" + reason, ConsoleColor.Cyan); #region 确保双挖权重在合法的范围内 if (CoinVm != null && CoinVm.CoinKernel != null && CoinVm.CoinKernel.Kernel != null) { var coinKernelProfile = CoinVm.CoinKernel.CoinKernelProfile; var kernelInput = CoinVm.CoinKernel.Kernel.KernelInputVm; if (coinKernelProfile != null && kernelInput != null) { if (coinKernelProfile.IsDualCoinEnabled && !kernelInput.IsAutoDualWeight) { if (coinKernelProfile.DualCoinWeight > kernelInput.DualWeightMax) { coinKernelProfile.DualCoinWeight = kernelInput.DualWeightMax; } else if (coinKernelProfile.DualCoinWeight < kernelInput.DualWeightMin) { coinKernelProfile.DualCoinWeight = kernelInput.DualWeightMin; } NTMinerContext.Instance.MinerProfile.SetCoinKernelProfileProperty(coinKernelProfile.CoinKernelId, nameof(coinKernelProfile.DualCoinWeight), coinKernelProfile.DualCoinWeight); } } } #endregion NTMinerContext.Instance.CurrentMineContext = NTMinerContext.Instance.CreateMineContext(); if (NTMinerContext.Instance.CurrentMineContext != null) { this.ArgsAssembly = NTMinerContext.Instance.CurrentMineContext.CommandLine; } else { this.ArgsAssembly = string.Empty; } }); AppRoot.AddCmdPath <RefreshAutoBootStartCommand>("刷新开机启动和自动挖矿的展示", LogEnum.DevConsole, action: message => { this.OnPropertyChanged(nameof(IsAutoBoot)); this.OnPropertyChanged(nameof(IsAutoStart)); }, location: this.GetType()); AppRoot.AddEventPath <MinerProfilePropertyChangedEvent>("MinerProfile设置变更后刷新VM内存", LogEnum.DevConsole, action: message => { OnPropertyChanged(message.PropertyName); }, location: this.GetType()); VirtualRoot.AddEventPath <LocalContextReInitedEventHandledEvent>("本地上下文视图模型集刷新后刷新界面", LogEnum.DevConsole, action: message => { AllPropertyChanged(); if (CoinVm != null) { CoinVm.OnPropertyChanged(nameof(CoinVm.Wallets)); CoinVm.CoinKernel?.CoinKernelProfile.SelectedDualCoin?.OnPropertyChanged(nameof(CoinVm.Wallets)); CoinVm.CoinProfile?.OnPropertyChanged(nameof(CoinVm.CoinProfile.SelectedWallet)); CoinVm.CoinKernel?.CoinKernelProfile.SelectedDualCoin?.CoinProfile?.OnPropertyChanged(nameof(CoinVm.CoinProfile.SelectedDualCoinWallet)); } }, location: this.GetType()); VirtualRoot.AddEventPath <CoinVmAddedEvent>("Vm集添加了新币种后刷新MinerProfileVm内存", LogEnum.DevConsole, action: message => { OnPropertyChanged(nameof(CoinVm)); }, this.GetType()); VirtualRoot.AddEventPath <CoinVmRemovedEvent>("Vm集删除了新币种后刷新MinerProfileVm内存", LogEnum.DevConsole, action: message => { OnPropertyChanged(nameof(CoinVm)); }, this.GetType()); }
public MinerProfileViewModel() { #if DEBUG NTStopwatch.Start(); #endif if (WpfUtil.IsInDesignMode) { return; } if (Instance != null) { throw new InvalidProgramException(); } if (this.IsCreateShortcut) { CreateShortcut(); } this.Up = new DelegateCommand <string>(propertyName => { PropertyInfo propertyInfo = this.GetType().GetProperty(propertyName); if (propertyInfo != null) { if (propertyInfo.PropertyType == typeof(int)) { propertyInfo.SetValue(this, (int)propertyInfo.GetValue(this, null) + 1, null); } else if (propertyInfo.PropertyType == typeof(double)) { propertyInfo.SetValue(this, Math.Round((double)propertyInfo.GetValue(this, null) + 0.1, 2), null); } } else { Write.DevError($"类型{this.GetType().FullName}不具有名称为{propertyName}的属性"); } }); this.Down = new DelegateCommand <string>(propertyName => { PropertyInfo propertyInfo = this.GetType().GetProperty(propertyName); if (propertyInfo != null) { if (propertyInfo.PropertyType == typeof(int)) { int value = (int)propertyInfo.GetValue(this, null); if (value > 0) { propertyInfo.SetValue(this, value - 1, null); } } else if (propertyInfo.PropertyType == typeof(double)) { double value = (double)propertyInfo.GetValue(this, null); if (value > 0.1) { propertyInfo.SetValue(this, Math.Round(value - 0.1, 2), null); } } } else { Write.DevError($"类型{this.GetType().FullName}不具有名称为{propertyName}的属性"); } }); NTMinerRoot.SetRefreshArgsAssembly(() => { #if DEBUG NTStopwatch.Start(); #endif if (CoinVm != null && CoinVm.CoinKernel != null && CoinVm.CoinKernel.Kernel != null) { var coinKernelProfile = CoinVm.CoinKernel.CoinKernelProfile; var kernelInput = CoinVm.CoinKernel.Kernel.KernelInputVm; if (coinKernelProfile != null && kernelInput != null) { if (coinKernelProfile.IsDualCoinEnabled && !kernelInput.IsAutoDualWeight) { if (coinKernelProfile.DualCoinWeight > kernelInput.DualWeightMax) { coinKernelProfile.DualCoinWeight = kernelInput.DualWeightMax; } else if (coinKernelProfile.DualCoinWeight < kernelInput.DualWeightMin) { coinKernelProfile.DualCoinWeight = kernelInput.DualWeightMin; } NTMinerRoot.Instance.MinerProfile.SetCoinKernelProfileProperty(coinKernelProfile.CoinKernelId, nameof(coinKernelProfile.DualCoinWeight), coinKernelProfile.DualCoinWeight); } } } NTMinerRoot.Instance.CurrentMineContext = NTMinerRoot.Instance.CreateMineContext(); if (NTMinerRoot.Instance.CurrentMineContext != null) { this.ArgsAssembly = NTMinerRoot.Instance.CurrentMineContext.CommandLine; } else { this.ArgsAssembly = string.Empty; } #if DEBUG var milliseconds = NTStopwatch.Stop(); if (milliseconds.ElapsedMilliseconds > NTStopwatch.ElapsedMilliseconds) { Write.DevTimeSpan($"耗时{milliseconds} {this.GetType().Name}.SetRefreshArgsAssembly"); } #endif }); VirtualRoot.AddEventPath <ServerContextVmsReInitedEvent>("ServerContext的VM集刷新后刷新视图界面", LogEnum.DevConsole, action: message => { OnPropertyChanged(nameof(CoinVm)); }, location: this.GetType()); AppContext.AddCmdPath <RefreshAutoBootStartCommand>("刷新开机启动和自动挖矿的展示", LogEnum.DevConsole, action: message => { MinerProfileData data = NTMinerRoot.CreateLocalRepository <MinerProfileData>().GetByKey(this.Id); if (data != null) { this.IsAutoBoot = data.IsAutoBoot; this.IsAutoStart = data.IsAutoStart; } }, location: this.GetType()); AppContext.AddEventPath <MinerProfilePropertyChangedEvent>("MinerProfile设置变更后刷新VM内存", LogEnum.DevConsole, action: message => { OnPropertyChanged(message.PropertyName); }, location: this.GetType()); VirtualRoot.AddEventPath <LocalContextVmsReInitedEvent>("本地上下文视图模型集刷新后刷新界面", LogEnum.DevConsole, action: message => { AllPropertyChanged(); if (CoinVm != null) { CoinVm.OnPropertyChanged(nameof(CoinVm.Wallets)); CoinVm.CoinKernel?.CoinKernelProfile.SelectedDualCoin?.OnPropertyChanged(nameof(CoinVm.Wallets)); CoinVm.CoinProfile.OnPropertyChanged(nameof(CoinVm.CoinProfile.SelectedWallet)); CoinVm.CoinKernel?.CoinKernelProfile.SelectedDualCoin?.CoinProfile.OnPropertyChanged(nameof(CoinVm.CoinProfile.SelectedDualCoinWallet)); } }, location: this.GetType()); #if DEBUG var elapsedMilliseconds = NTStopwatch.Stop(); if (elapsedMilliseconds.ElapsedMilliseconds > NTStopwatch.ElapsedMilliseconds) { Write.DevTimeSpan($"耗时{elapsedMilliseconds} {this.GetType().Name}.ctor"); } #endif }
public LocalMessagesViewModel() { if (WpfUtil.IsInDesignMode) { return; } foreach (var messageChannel in LocalMessageChannelEnumItems) { var values = new Dictionary <LocalMessageType, MessageTypeItem <LocalMessageType> >(); foreach (var messageType in NTMinerContext.LocalMessageTypeEnumItems) { values.Add(messageType.Value, new MessageTypeItem <LocalMessageType>(messageType, LocalMessageViewModel.GetIcon, LocalMessageViewModel.GetIconFill, RefreshQueryResults)); } _count.Add(messageChannel, values); } _selectedChannel = LocalMessageChannelEnumItems.FirstOrDefault(); Init(); this.ClearKeyword = new DelegateCommand(() => { this.Keyword = string.Empty; }); this.Clear = new DelegateCommand(() => { this.ShowSoftDialog(new DialogWindowViewModel(message: "确定清空吗?", title: "确认", onYes: () => { VirtualRoot.Execute(new ClearLocalMessageSetCommand()); })); }); VirtualRoot.AddEventPath <LocalMessageSetClearedEvent>("清空本地消息集后刷新VM内存", LogEnum.DevConsole, action: message => { Init(); }, location: this.GetType()); VirtualRoot.AddEventPath <LocalMessageAddedEvent>("发生了本地消息后刷新Vm内存", LogEnum.DevConsole, action: message => { UIThread.Execute(() => () => { var vm = new LocalMessageViewModel(message.Source); _localMessageVms.Insert(0, vm); if (IsSatisfyQuery(vm)) { _queyResults.Insert(0, vm); } foreach (var item in message.Removes) { var toRemove = _localMessageVms.FirstOrDefault(a => a.Id == item.Id); if (toRemove != null) { _localMessageVms.Remove(toRemove); if (IsSatisfyQuery(toRemove)) { _queyResults.Remove(toRemove); } } } int removedCount = message.Removes.Count(a => a.MessageType == vm.MessageTypeEnum.GetName()); if (removedCount != 1) { _count[vm.ChannelEnum.GetEnumItem()][vm.MessageTypeEnum].Count += 1 - removedCount; UpdateChannelAll(); } OnPropertyChanged(nameof(IsNoRecord)); }); }, location: this.GetType()); VirtualRoot.AddEventPath <NewDayEvent>("新的一天到来时刷新消息集中的可读性时间戳展示", LogEnum.DevConsole, action: message => { if (QueryResults == null) { return; } foreach (var item in QueryResults) { if (item.Timestamp.Date.AddDays(3) >= message.BornOn.Date) { item.OnPropertyChanged(nameof(item.TimestampText)); } else { // 因为是按照时间倒叙排列的,所以可以break break; } } }, location: this.GetType()); }
public void Init(INTMinerRoot root) { if (_isInited) { return; } _isInited = true; VirtualRoot.AddEventPath <GpuStateChangedEvent>("当显卡温度变更时守卫温度防线", LogEnum.None, action: message => { IGpu gpu = message.Target; if (gpu.Index == NTMinerRoot.GpuAllId || root.MinerProfile.CoinId == Guid.Empty) { return; } IGpuProfile gpuProfile; if (NTMinerRoot.Instance.GpuProfileSet.IsOverClockGpuAll(root.MinerProfile.CoinId)) { gpuProfile = NTMinerRoot.Instance.GpuProfileSet.GetGpuProfile(root.MinerProfile.CoinId, NTMinerRoot.GpuAllId); } else { gpuProfile = NTMinerRoot.Instance.GpuProfileSet.GetGpuProfile(root.MinerProfile.CoinId, gpu.Index); } if (!gpuProfile.IsAutoFanSpeed) { return; } // 显卡温度抵达防御温度的时间 if (!_fightedOnDic.TryGetValue(gpu.Index, out DateTime fightedOn)) { fightedOn = DateTime.Now; _fightedOnDic.Add(gpu.Index, fightedOn); } if (gpu.FanSpeed == 100 && gpu.Temperature > _guardTemp) { Write.DevDebug($"GPU{gpu.Index.ToString()} 温度{gpu.Temperature.ToString()}大于防线温度{_guardTemp.ToString()},但风扇转速已达100%"); } else if (gpu.Temperature < _guardTemp) { if (!_preTempDic.ContainsKey(gpu.Index)) { _preTempDic.Add(gpu.Index, 0); } // 如果当前温度比上次的温度大 if (gpu.Temperature > _preTempDic[gpu.Index]) { fightedOn = DateTime.Now; _fightedOnDic[gpu.Index] = fightedOn; } _preTempDic[gpu.Index] = gpu.Temperature; // 如果距离抵达防御温度的时间已经很久了则降速风扇 if (fightedOn.AddSeconds(_fanSpeedDownSeconds) < DateTime.Now) { int cool = (int)(gpu.FanSpeed - _fanSpeedDownStep); // 如果温度低于50度则直接将风扇设为驱动默认的最小转速 if (gpu.Temperature < 50) { cool = gpu.CoolMin; } if (cool >= gpu.CoolMin) { _fightedOnDic[gpu.Index] = DateTime.Now; root.GpuSet.OverClock.SetFanSpeed(gpu.Index, cool); Write.DevDebug($"GPU{gpu.Index.ToString()} 风扇转速由{gpu.FanSpeed.ToString()}%调低至{cool.ToString()}%"); } } } else if (gpu.Temperature > _guardTemp) { uint cool; uint len; // 防线突破可能是由于小量降低风扇转速造成的 if (fightedOn.AddSeconds(_fanSpeedDownSeconds) < DateTime.Now) { _fightedOnDic[gpu.Index] = DateTime.Now; len = 100 - gpu.FanSpeed; } else { len = _fanSpeedDownStep; } cool = gpu.FanSpeed + (uint)Math.Ceiling(len / 2.0); if (cool > 100) { cool = 100; } if (cool <= 100) { root.GpuSet.OverClock.SetFanSpeed(gpu.Index, (int)cool); Write.DevDebug($"GPU{gpu.Index.ToString()} 风扇转速由{gpu.FanSpeed.ToString()}%调高至{cool.ToString()}%"); } } }, location: this.GetType()); }
public MinerClientSessionSet(WebSocketSessionManager wsSessionManager) : base(wsSessionManager) { VirtualRoot.AddEventPath <GetConsoleOutLinesMqMessage>("收到GetConsoleOutLines Mq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.GetConsoleOutLines) { Data = message.Data }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <GetLocalMessagesMqMessage>("收到GetLocalMessages Mq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.GetLocalMessages) { Data = message.Data }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <GetDrivesMqMessage>("收到GetDrives Mq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.GetDrives)); #endregion }, this.GetType()); VirtualRoot.AddEventPath <GetLocalIpsMqMessage>("收到GetLocalIps Mq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.GetLocalIps)); #endregion }, this.GetType()); VirtualRoot.AddEventPath <GetOperationResultsMqMessage>("收到GetOperationResults Mq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.GetOperationResults) { Data = message.Data }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <GetSpeedMqMessage>("收到GetSpeedMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (message.ClientIds == null || message.ClientIds.Count == 0) { return; } if (IsTooOld(message.Timestamp)) { return; } IUser user = WsRoot.ReadOnlyUserSet.GetUser(UserId.CreateLoginNameUserId(message.LoginName)); if (user == null) { return; } foreach (var clientId in message.ClientIds) { if (clientId == null || clientId == Guid.Empty) { continue; } if (!WsRoot.MinerSignSet.TryGetByClientId(clientId, out MinerSign minerSign) || !minerSign.IsOwnerBy(user)) { continue; } SendToMinerClientAsync(clientId, new WsMessage(message.MessageId, WsMessage.GetSpeed)); } #endregion }, this.GetType()); VirtualRoot.AddEventPath <EnableRemoteDesktopMqMessage>("收到EnableRemoteDesktopMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.EnableRemoteDesktop)); #endregion }, this.GetType()); VirtualRoot.AddEventPath <BlockWAUMqMessage>("收到BlockWAUMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.BlockWAU)); #endregion }, this.GetType()); VirtualRoot.AddEventPath <SetVirtualMemoryMqMessage>("收到SetVirtualMemoryMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.SetVirtualMemory) { Data = message.Data }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <SetLocalIpsMqMessage>("收到SetLocalIpsMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.SetLocalIps) { Data = message.Data }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <SwitchRadeonGpuMqMessage>("收到SwitchRadeonGpuMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.SwitchRadeonGpu) { Data = message.On }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <GetSelfWorkLocalJsonMqMessage>("收到GetSelfWorkLocalJsonMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.GetSelfWorkLocalJson)); #endregion }, this.GetType()); VirtualRoot.AddEventPath <SaveSelfWorkLocalJsonMqMessage>("收到SaveSelfWorkLocalJsonMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.SaveSelfWorkLocalJson) { Data = message.Data }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <GetGpuProfilesJsonMqMessage>("收到GetGpuProfilesJsonMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.GetGpuProfilesJson)); #endregion }, this.GetType()); VirtualRoot.AddEventPath <SaveGpuProfilesJsonMqMessage>("收到SaveGpuProfilesJsonMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.SaveGpuProfilesJson) { Data = message.Data }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <SetAutoBootStartMqMessage>("收到SetAutoBootStartMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.SetAutoBootStart) { Data = message.Data }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <RestartWindowsMqMessage>("收到RestartWindowsMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.RestartWindows)); #endregion }, this.GetType()); VirtualRoot.AddEventPath <ShutdownWindowsMqMessage>("收到ShutdownWindowsMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.ShutdownWindows)); #endregion }, this.GetType()); VirtualRoot.AddEventPath <UpgradeNTMinerMqMessage>("收到UpgradeNTMinerMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.UpgradeNTMiner) { Data = message.Data }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <StartMineMqMessage>("收到StartMineMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } if (message.Data != Guid.Empty) { RpcRoot.OfficialServer.UserMineWorkService.GetWorkJsonAsync(message.Data, message.ClientId, (response, e) => { if (response.IsSuccess()) { SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.StartMine) { Data = new WorkRequest { WorkId = message.Data, WorkerName = response.WorkerName, LocalJson = response.LocalJson, ServerJson = response.ServerJson } }); } }); } else { SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.StartMine) { Data = new WorkRequest { WorkId = message.Data, WorkerName = string.Empty, LocalJson = string.Empty, ServerJson = string.Empty } }); } #endregion }, this.GetType()); VirtualRoot.AddEventPath <StopMineMqMessage>("收到StopMineMq消息后检查是否是应由本节点处理的消息,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerClientAsync(message.ClientId, new WsMessage(message.MessageId, WsMessage.StopMine)); #endregion }, this.GetType()); }
public MinerProfileViewModel() { #if DEBUG NTStopwatch.Start(); #endif if (WpfUtil.IsInDesignMode) { return; } if (Instance != null) { throw new InvalidProgramException(); } if (this.IsCreateShortcut) { CreateShortcut(); } this.AutoStartDelaySecondsUp = new DelegateCommand(() => { this.AutoStartDelaySeconds++; }); this.AutoStartDelaySecondsDown = new DelegateCommand(() => { if (this.AutoStartDelaySeconds > 0) { this.AutoStartDelaySeconds--; } }); this.AutoRestartKernelTimesUp = new DelegateCommand(() => { this.AutoRestartKernelTimes++; }); this.AutoRestartKernelTimesDown = new DelegateCommand(() => { if (this.AutoRestartKernelTimes > 0) { this.AutoRestartKernelTimes--; } }); this.NoShareRestartKernelMinutesUp = new DelegateCommand(() => { this.NoShareRestartKernelMinutes++; }); this.NoShareRestartKernelMinutesDown = new DelegateCommand(() => { if (this.NoShareRestartKernelMinutes > 0) { this.NoShareRestartKernelMinutes--; } }); this.NoShareRestartComputerMinutesUp = new DelegateCommand(() => { this.NoShareRestartComputerMinutes++; }); this.NoShareRestartComputerMinutesDown = new DelegateCommand(() => { if (this.NoShareRestartComputerMinutes > 0) { this.NoShareRestartComputerMinutes--; } }); this.PeriodicRestartKernelHoursUp = new DelegateCommand(() => { this.PeriodicRestartKernelHours++; }); this.PeriodicRestartKernelHoursDown = new DelegateCommand(() => { if (this.PeriodicRestartKernelHours > 0) { this.PeriodicRestartKernelHours--; } }); this.PeriodicRestartKernelMinutesUp = new DelegateCommand(() => { this.PeriodicRestartKernelMinutes++; }); this.PeriodicRestartKernelMinutesDown = new DelegateCommand(() => { if (this.PeriodicRestartKernelMinutes > 0) { this.PeriodicRestartKernelMinutes--; } }); this.PeriodicRestartComputerHoursUp = new DelegateCommand(() => { this.PeriodicRestartComputerHours++; }); this.PeriodicRestartComputerHoursDown = new DelegateCommand(() => { if (this.PeriodicRestartComputerHours > 0) { this.PeriodicRestartComputerHours--; } }); this.PeriodicRestartComputerMinutesUp = new DelegateCommand(() => { this.PeriodicRestartComputerMinutes++; }); this.PeriodicRestartComputerMinutesDown = new DelegateCommand(() => { if (this.PeriodicRestartComputerMinutes > 0) { this.PeriodicRestartComputerMinutes--; } }); this.CpuGETemperatureSecondsUp = new DelegateCommand(() => { this.CpuGETemperatureSeconds++; }); this.CpuGETemperatureSecondsDown = new DelegateCommand(() => { this.CpuGETemperatureSeconds--; }); this.CpuStopTemperatureUp = new DelegateCommand(() => { this.CpuStopTemperature++; }); this.CpuStopTemperatureDown = new DelegateCommand(() => { this.CpuStopTemperature--; }); this.CpuLETemperatureSecondsUp = new DelegateCommand(() => { this.CpuLETemperatureSeconds++; }); this.CpuLETemperatureSecondsDown = new DelegateCommand(() => { this.CpuLETemperatureSeconds--; }); this.CpuStartTemperatureUp = new DelegateCommand(() => { this.CpuStartTemperature++; }); this.CpuStartTemperatureDown = new DelegateCommand(() => { this.CpuStartTemperature--; }); this.EPriceUp = new DelegateCommand(() => { this.EPrice = Math.Round(this.EPrice + 0.1, 2); }); this.EPriceDown = new DelegateCommand(() => { if (this.EPrice > 0.1) { this.EPrice = Math.Round(this.EPrice - 0.1, 2); } }); this.PowerAppendUp = new DelegateCommand(() => { this.PowerAppend++; }); this.PowerAppendDown = new DelegateCommand(() => { if (this.PowerAppend > 0) { this.PowerAppend--; } }); this.MaxTempUp = new DelegateCommand(() => { this.MaxTemp++; }); this.MaxTempDown = new DelegateCommand(() => { if (this.MaxTemp > 0) { this.MaxTemp--; } }); this.AutoNoUiMinutesUp = new DelegateCommand(() => { this.AutoNoUiMinutes++; }); this.AutoNoUiMinutesDown = new DelegateCommand(() => { if (this.AutoNoUiMinutes > 0) { this.AutoNoUiMinutes--; } }); this.HighCpuBaselineUp = new DelegateCommand(() => { this.HighCpuBaseline++; }); this.HighCpuBaselineDown = new DelegateCommand(() => { if (this.HighCpuBaseline > 0) { this.HighCpuBaseline--; } }); this.HighCpuSecondsUp = new DelegateCommand(() => { this.HighCpuSeconds++; }); this.HighCpuSecondsDown = new DelegateCommand(() => { if (this.HighCpuSeconds > 0) { this.HighCpuSeconds--; } }); NTMinerRoot.SetRefreshArgsAssembly(() => { #if DEBUG NTStopwatch.Start(); #endif if (CoinVm != null && CoinVm.CoinKernel != null && CoinVm.CoinKernel.Kernel != null) { var coinKernelProfile = CoinVm.CoinKernel.CoinKernelProfile; var kernelInput = CoinVm.CoinKernel.Kernel.KernelInputVm; if (coinKernelProfile != null && kernelInput != null) { if (coinKernelProfile.IsDualCoinEnabled && !kernelInput.IsAutoDualWeight) { if (coinKernelProfile.DualCoinWeight > kernelInput.DualWeightMax) { coinKernelProfile.DualCoinWeight = kernelInput.DualWeightMax; } else if (coinKernelProfile.DualCoinWeight < kernelInput.DualWeightMin) { coinKernelProfile.DualCoinWeight = kernelInput.DualWeightMin; } NTMinerRoot.Instance.MinerProfile.SetCoinKernelProfileProperty(coinKernelProfile.CoinKernelId, nameof(coinKernelProfile.DualCoinWeight), coinKernelProfile.DualCoinWeight); } } } NTMinerRoot.Instance.CurrentMineContext = NTMinerRoot.Instance.CreateMineContext(); if (NTMinerRoot.Instance.CurrentMineContext != null) { this.ArgsAssembly = NTMinerRoot.Instance.CurrentMineContext.CommandLine; } else { this.ArgsAssembly = string.Empty; } #if DEBUG var milliseconds = NTStopwatch.Stop(); if (milliseconds.ElapsedMilliseconds > NTStopwatch.ElapsedMilliseconds) { Write.DevTimeSpan($"耗时{milliseconds} {this.GetType().Name}.SetRefreshArgsAssembly"); } #endif }); VirtualRoot.AddEventPath <ServerContextVmsReInitedEvent>("ServerContext的VM集刷新后刷新视图界面", LogEnum.DevConsole, action: message => { OnPropertyChanged(nameof(CoinVm)); }, location: this.GetType()); AppContext.AddCmdPath <RefreshAutoBootStartCommand>("刷新开机启动和自动挖矿的展示", LogEnum.DevConsole, action: message => { MinerProfileData data = NTMinerRoot.CreateLocalRepository <MinerProfileData>().GetByKey(this.Id); if (data != null) { this.IsAutoBoot = data.IsAutoBoot; this.IsAutoStart = data.IsAutoStart; } }, location: this.GetType()); AppContext.AddEventPath <MinerProfilePropertyChangedEvent>("MinerProfile设置变更后刷新VM内存", LogEnum.DevConsole, action: message => { OnPropertyChanged(message.PropertyName); }, location: this.GetType()); VirtualRoot.AddEventPath <LocalContextVmsReInitedEvent>("本地上下文视图模型集刷新后刷新界面", LogEnum.DevConsole, action: message => { AllPropertyChanged(); if (CoinVm != null) { CoinVm.OnPropertyChanged(nameof(CoinVm.Wallets)); CoinVm.CoinKernel?.CoinKernelProfile.SelectedDualCoin?.OnPropertyChanged(nameof(CoinVm.Wallets)); CoinVm.CoinProfile.OnPropertyChanged(nameof(CoinVm.CoinProfile.SelectedWallet)); CoinVm.CoinKernel?.CoinKernelProfile.SelectedDualCoin?.CoinProfile.OnPropertyChanged(nameof(CoinVm.CoinProfile.SelectedDualCoinWallet)); } }, location: this.GetType()); #if DEBUG var elapsedMilliseconds = NTStopwatch.Stop(); if (elapsedMilliseconds.ElapsedMilliseconds > NTStopwatch.ElapsedMilliseconds) { Write.DevTimeSpan($"耗时{elapsedMilliseconds} {this.GetType().Name}.ctor"); } #endif }
public AMDGpuSet() { #if DEBUG NTStopwatch.Start(); #endif this.Properties = new List <GpuSetProperty>(); this.OverClock = new GpuOverClock(adlHelper); VirtualRoot.AddEventPath <AppExitEvent>("程序退出时调用adlHelper.Close", LogEnum.None, message => { adlHelper.Close(); }, this.GetType()); int deviceCount = 0; deviceCount = adlHelper.GpuCount; for (int i = 0; i < deviceCount; i++) { var atiGpu = adlHelper.GetAtiGPU(i); string name = atiGpu.AdapterName; // short gpu name if (!string.IsNullOrEmpty(name)) { name = name.Replace("Radeon (TM) RX ", string.Empty); name = name.Replace("Radeon RX ", string.Empty); } var gpu = Gpu.Create(GpuType.AMD, i, atiGpu.BusNumber.ToString(), name); gpu.TotalMemory = adlHelper.GetTotalMemory(i); _gpus.Add(i, gpu); } if (deviceCount > 0) { this.DriverVersion = adlHelper.GetDriverVersion(); this.Properties.Add(new GpuSetProperty(GpuSetProperty.DRIVER_VERSION, "驱动版本", DriverVersion)); const ulong minG = 5 * NTKeyword.ULongG; bool has470 = _gpus.Any(a => a.Key != NTMinerContext.GpuAllId && a.Value.TotalMemory < minG); if (has470) { Dictionary <string, string> kvs = new Dictionary <string, string> { ["GPU_MAX_ALLOC_PERCENT"] = "100", ["GPU_MAX_HEAP_SIZE"] = "100", ["GPU_SINGLE_ALLOC_PERCENT"] = "100" }; foreach (var kv in kvs) { var property = new GpuSetProperty(kv.Key, kv.Key, kv.Value); this.Properties.Add(property); } Task.Factory.StartNew(() => { OverClock.RefreshGpuState(NTMinerContext.GpuAllId); foreach (var kv in kvs) { Environment.SetEnvironmentVariable(kv.Key, kv.Value); } }); } else { Task.Factory.StartNew(() => { OverClock.RefreshGpuState(NTMinerContext.GpuAllId); }); } } #if DEBUG var elapsedMilliseconds = NTStopwatch.Stop(); if (elapsedMilliseconds.ElapsedMilliseconds > NTStopwatch.ElapsedMilliseconds) { NTMinerConsole.DevTimeSpan($"耗时{elapsedMilliseconds} {this.GetType().Name}.ctor"); } #endif }
public ReadOnlyUserSet(IReadOnlyUserRedis userRedis) { userRedis.GetAllAsync().ContinueWith(t => { _initedOn = DateTime.Now; foreach (var item in t.Result) { _dicByLoginName.Add(item.LoginName, item); } IsReadied = true; NTMinerConsole.UserOk("用户集就绪"); VirtualRoot.RaiseEvent(new UserSetInitedEvent()); }); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在UserSetInitedEvent事件之后才会创建 VirtualRoot.AddEventPath <UserAddedMqMessage>("收到UserAddedMq消息后从Redis加载新用户到内存", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); }, this.GetType()); VirtualRoot.AddEventPath <UserUpdatedMqMessage>("收到UserUpdatedMq消息后从Redis加载用户到内存", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); }, this.GetType()); VirtualRoot.AddEventPath <UserRemovedMqMessage>("收到UserRemovedMq消息后移除内存中对应的记录", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } _dicByLoginName.Remove(message.LoginName); }, this.GetType()); VirtualRoot.AddEventPath <UserEnabledMqMessage>("收到UserEnabledMq消息后启用内存中对应记录的状态", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } if (_dicByLoginName.TryGetValue(message.LoginName, out UserData userData)) { userData.IsEnabled = true; } }, this.GetType()); VirtualRoot.AddEventPath <UserDisabledMqMessage>("收到UserDisabledMq消息后禁用内存中对应记录的状态", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } if (_dicByLoginName.TryGetValue(message.LoginName, out UserData userData)) { userData.IsEnabled = false; } }, this.GetType()); VirtualRoot.AddEventPath <UserPasswordChangedMqMessage>("收到UserPasswordChangedMq消息后从Redis刷新内存中对应的记录", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); }, this.GetType()); VirtualRoot.AddEventPath <UserRSAKeyUpdatedMqMessage>("收到了UserRSAKeyUpdated Mq消息后更新内存中对应的记录", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.LoginName)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } if (_dicByLoginName.TryGetValue(message.LoginName, out UserData userData)) { userRedis.GetByLoginNameAsync(message.LoginName).ContinueWith(t => { if (t.Result != null) { _dicByLoginName[message.LoginName] = t.Result; } }); } }, this.GetType()); }
public MinerStudioSessionSet() : base(MinerStudioBehavior.WsServiceHostPath) { VirtualRoot.AddEventPath <UserPasswordChangedMqMessage>("群控用户密码变更后通知群控客户端重新登录", LogEnum.None, action: message => { SendToMinerStudioAsync(message.LoginName, new WsMessage(message.MessageId, WsMessage.ReLogin)); }, this.GetType()); VirtualRoot.AddEventPath <ConsoleOutLinesMqMessage>("收到ConsoleOutLinesMq消息后检查对应的用户是否登录着本节点,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerStudioAsync(message.LoginName, new WsMessage(message.MessageId, WsMessage.ConsoleOutLines) { Data = new WrapperClientIdData { ClientId = message.ClientId, Data = message.Data } }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <LocalMessagesMqMessage>("收到LocalMessagesMq消息后检查对应的用户是否登录着本节点,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerStudioAsync(message.LoginName, new WsMessage(message.MessageId, WsMessage.LocalMessages) { Data = new WrapperClientIdData { ClientId = message.ClientId, Data = message.Data } }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <DrivesMqMessage>("收到DrivesMq消息后检查对应的用户是否登录着本节点,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerStudioAsync(message.LoginName, new WsMessage(message.MessageId, WsMessage.Drives) { Data = new WrapperClientIdData { ClientId = message.ClientId, Data = message.Data } }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <LocalIpsMqMessage>("收到LocalIpsMq消息后检查对应的用户是否登录着本节点,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerStudioAsync(message.LoginName, new WsMessage(message.MessageId, WsMessage.LocalIps) { Data = new WrapperClientIdData { ClientId = message.ClientId, Data = message.Data } }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <OperationResultsMqMessage>("收到OperationResultsMq消息后检查对应的用户是否登录着本节点,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerStudioAsync(message.LoginName, new WsMessage(message.MessageId, WsMessage.OperationResults) { Data = new WrapperClientIdData { ClientId = message.ClientId, Data = message.Data } }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <OperationReceivedMqMessage>("收到OperationReceivedMq消息后检查对应的用户是否登录着本节点,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerStudioAsync(message.LoginName, new WsMessage(message.MessageId, WsMessage.OperationReceived) { Data = new WrapperClientId { ClientId = message.ClientId } }); #endregion }, this.GetType()); VirtualRoot.AddEventPath <GpuProfilesJsonMqMessage>("收到GpuProfilesJsonMq消息后检查对应的用户是否登录着本节点,如果是则处理,否则忽略", LogEnum.None, action: message => { #region if (!IsValid(message.ClientId, message.Timestamp, message.LoginName)) { return; } SendToMinerStudioAsync(message.LoginName, new WsMessage(message.MessageId, WsMessage.GpuProfilesJson) { Data = new WrapperClientIdData { ClientId = message.ClientId, Data = message.Data } }); #endregion }, this.GetType()); }
public MinerSignSet(IReadOnlyMinerRedis redis) { redis.GetAllAsync().ContinueWith(t => { _initedOn = DateTime.Now; foreach (var item in t.Result) { Add(MinerSign.Create(item)); } IsReadied = true; NTMinerConsole.UserOk("矿机签名集就绪"); VirtualRoot.RaiseEvent(new MinerSignSetInitedEvent()); }); // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在MinerSignSetInitedEvent事件之后才会创建 VirtualRoot.AddEventPath <MinerDataRemovedMqMessage>("收到MinerClientRemovedMq消息后移除内存中对应的记录", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.MinerId)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } if (_dicByMinerId.TryGetValue(message.MinerId, out MinerSign minerSign)) { if (WsRoot.MinerClientSessionSet.TryGetByClientId(minerSign.ClientId, out IMinerClientSession ntminerSession)) { ntminerSession.CloseAsync(WebSocketSharp.CloseStatusCode.Normal, "服务端移除了该矿机"); } _dicByMinerId.Remove(message.MinerId); _dicByClientId.Remove(minerSign.ClientId); } }, this.GetType()); VirtualRoot.AddEventPath <MinerDataAddedMqMessage>("收到MinerDataAddedMq消息后更新内存中对应的记录", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.MinerId)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } redis.GetByIdAsync(message.MinerId).ContinueWith(t => { if (t.Result != null) { if (_dicByMinerId.TryGetValue(message.MinerId, out MinerSign minerSign)) { minerSign.Update(t.Result); } else { Add(MinerSign.Create(t.Result)); } } }); }, this.GetType()); VirtualRoot.AddEventPath <MinerSignChangedMqMessage>("收到MinerSignChangedMq消息后更新内存中对应的记录", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (string.IsNullOrEmpty(message.MinerId)) { return; } if (IsOldMqMessage(message.Timestamp)) { NTMinerConsole.UserOk(_safeIgnoreMessage); return; } redis.GetByIdAsync(message.MinerId).ContinueWith(t => { if (t.Result != null) { if (_dicByMinerId.TryGetValue(message.MinerId, out MinerSign minerSign)) { minerSign.Update(t.Result); } else { Add(MinerSign.Create(t.Result)); } } }); }, this.GetType()); }
public ClientDataSet(IMinerRedis minerRedis, ISpeedDataRedis speedDataRedis, IMinerClientMqSender mqSender) : base(isPull: false, getDatas: callback => { var getMinersTask = minerRedis.GetAllAsync(); var getSpeedsTask = speedDataRedis.GetAllAsync(); Task.WhenAll(getMinersTask, getSpeedsTask).ContinueWith(t => { var speedDatas = getSpeedsTask.Result; List <ClientData> clientDatas = new List <ClientData>(); foreach (var minerData in getMinersTask.Result) { var clientData = ClientData.Create(minerData); clientDatas.Add(clientData); var speedData = speedDatas.FirstOrDefault(a => a.ClientId == minerData.ClientId); if (speedData != null) { clientData.Update(speedData); } } callback?.Invoke(clientDatas); }); }) { _minerRedis = minerRedis; _speedDataRedis = speedDataRedis; _mqSender = mqSender; // 收到Mq消息之前一定已经初始化完成,因为Mq消费者在ClientSetInitedEvent事件之后才会创建 VirtualRoot.AddEventPath <SpeedDataMqMessage>("收到SpeedDataMq消息后更新ClientData内存", LogEnum.None, action: message => { if (message.AppId == ServerRoot.HostConfig.ThisServerAddress) { return; } if (message.ClientId == Guid.Empty) { return; } if (IsOldMqMessage(message.Timestamp)) { Write.UserOk(_safeIgnoreMessage); return; } speedDataRedis.GetByClientIdAsync(message.ClientId).ContinueWith(t => { ReportSpeed(t.Result, message.MinerIp, isFromWsServerNode: true); }); }, this.GetType()); VirtualRoot.AddEventPath <MinerClientWsOpenedMqMessage>("收到MinerClientWsOpenedMq消息后更新NetActiveOn和IsOnline", LogEnum.None, action: message => { if (IsOldMqMessage(message.Timestamp)) { Write.UserOk(_safeIgnoreMessage); return; } if (_dicByClientId.TryGetValue(message.ClientId, out ClientData clientData)) { clientData.NetActiveOn = message.Timestamp; clientData.IsOnline = true; } }, this.GetType()); VirtualRoot.AddEventPath <MinerClientWsClosedMqMessage>("收到MinerClientWsClosedMq消息后更新NetActiveOn和IsOnline", LogEnum.None, action: message => { if (IsOldMqMessage(message.Timestamp)) { Write.UserOk(_safeIgnoreMessage); return; } if (_dicByClientId.TryGetValue(message.ClientId, out ClientData clientData)) { clientData.NetActiveOn = message.Timestamp; clientData.IsOnline = false; } }, this.GetType()); VirtualRoot.AddEventPath <MinerClientWsBreathedMqMessage>("收到MinerClientWsBreathedMq消息后更新NetActiveOn", LogEnum.None, action: message => { if (IsOldMqMessage(message.Timestamp)) { Write.UserOk(_safeIgnoreMessage); return; } if (_dicByClientId.TryGetValue(message.ClientId, out ClientData clientData)) { clientData.NetActiveOn = message.Timestamp; clientData.IsOnline = true; } }, this.GetType()); VirtualRoot.AddCmdPath <ChangeMinerSignMqMessage>(action: message => { if (_dicByObjectId.TryGetValue(message.Data.Id, out ClientData clientData)) { clientData.Update(message.Data, out bool isChanged); if (isChanged) { var minerData = MinerData.Create(clientData); _minerRedis.SetAsync(minerData).ContinueWith(t => { _mqSender.SendMinerSignChanged(minerData.Id); }); } } else { Add(ClientData.Create(MinerData.Create(message.Data))); } }, this.GetType(), LogEnum.DevConsole); }
public ServerMessagesViewModel() { if (WpfUtil.IsInDesignMode) { return; } foreach (var messageType in NTMinerContext.ServerMessageTypeEnumItems) { _count.Add(messageType.Value, new MessageTypeItem <ServerMessageType>(messageType, ServerMessageViewModel.GetIcon, ServerMessageViewModel.GetIconFill, RefreshQueryResults)); } Init(); this.Add = new DelegateCommand(() => { new ServerMessageViewModel(new ServerMessageData { Id = Guid.NewGuid(), MessageType = ServerMessageType.Info.GetName(), Provider = "admin", Content = string.Empty, Timestamp = DateTime.MinValue }).Edit.Execute(FormType.Add); }); this.ClearKeyword = new DelegateCommand(() => { this.Keyword = string.Empty; }); this.Clear = new DelegateCommand(() => { this.ShowSoftDialog(new DialogWindowViewModel(message: "确定清空吗?", title: "确认", onYes: () => { VirtualRoot.Execute(new ClearServerMessages()); })); }); VirtualRoot.AddEventPath <ServerMessagesClearedEvent>("清空了本地存储的服务器消息后刷新Vm内存", LogEnum.DevConsole, action: message => { Init(); }, location: this.GetType()); VirtualRoot.AddEventPath <NewServerMessageLoadedEvent>("从服务器加载了新消息后刷新Vm内存", LogEnum.DevConsole, action: message => { UIThread.Execute(() => { foreach (var item in message.Data) { var vm = new ServerMessageViewModel(item); var exist = _serverMessageVms.FirstOrDefault(a => a.Id == item.Id); if (exist != null) { _serverMessageVms.Remove(exist); if (item.IsDeleted) { _count[exist.MessageTypeEnum].Count--; } else { _serverMessageVms.Insert(0, vm); if (exist.MessageType != item.MessageType) { _count[exist.MessageTypeEnum].Count--; _count[vm.MessageTypeEnum].Count++; } } } else if (!vm.IsDeleted) { _serverMessageVms.Insert(0, vm); _count[vm.MessageTypeEnum].Count++; } if (IsSatisfyQuery(vm)) { exist = _queyResults.FirstOrDefault(a => a.Id == item.Id); if (exist != null) { _queyResults.Remove(exist); } if (!vm.IsDeleted) { _queyResults.Insert(0, vm); } } } OnPropertyChanged(nameof(IsNoRecord)); }); }, location: this.GetType()); VirtualRoot.AddEventPath <NewDayEvent>("新的一天到来时刷新消息集中的可读性时间戳展示", LogEnum.DevConsole, action: message => { if (QueryResults == null) { return; } foreach (var item in QueryResults) { if (item.Timestamp.Date.AddDays(3) >= message.BornOn.Date) { item.OnPropertyChanged(nameof(item.TimestampText)); } else { // 因为是按照时间倒叙排列的,所以可以break break; } } }, location: this.GetType()); }
internal void Init() { if (ClientAppType.IsMinerClient) { Task.Factory.StartNew(() => { // 注意:第一次GetTemperature请求约需要160毫秒,所以提前在非UI线程做第一次请求。 GetTemperature(); VirtualRoot.AddEventPath <Per2SecondEvent>("周期更新CpuAll的状态", LogEnum.None, action: message => { Task.Factory.StartNew(() => { // 因为获取cpu温度的操作耗时100毫秒 Update(); #region CPU温度过高时自动停止挖矿和温度降低时自动开始挖矿 if (_minerProfile.IsAutoStopByCpu) { if (NTMinerContext.Instance.IsMining) { /* 挖矿中时周期更新最后一次温度低于挖矿停止温度的时刻,然后检查最后一次低于 * 挖矿停止温度的时刻距离现在是否已经超过了设定的时常,如果超过了则自动停止挖矿*/ HighTemperatureOn = message.BornOn; // 如果当前温度低于挖矿停止温度则更新记录的低温时刻 if (this.Temperature < _minerProfile.CpuStopTemperature) { LowTemperatureOn = message.BornOn; } if ((message.BornOn - LowTemperatureOn).TotalSeconds >= _minerProfile.CpuGETemperatureSeconds) { LowTemperatureOn = message.BornOn; VirtualRoot.ThisLocalWarn(nameof(CpuPackage), $"自动停止挖矿,因为 CPU 温度连续{_minerProfile.CpuGETemperatureSeconds.ToString()}秒不低于{_minerProfile.CpuStopTemperature.ToString()}℃", toConsole: true); NTMinerContext.Instance.StopMineAsync(StopMineReason.HighCpuTemperature); } } else { /* 高温停止挖矿后周期更新最后一次温度高于挖矿停止温度的时刻,然后检查最后一次高于 * 挖矿停止温度的时刻距离现在是否已经超过了设定的时常,如果超过了则自动开始挖矿*/ LowTemperatureOn = message.BornOn; if (_minerProfile.IsAutoStartByCpu && NTMinerContext.Instance.StopReason == StopMineReason.HighCpuTemperature) { // 当前温度高于挖矿停止温度则更新记录的高温时刻 if (this.Temperature > _minerProfile.CpuStartTemperature) { HighTemperatureOn = message.BornOn; } if ((message.BornOn - HighTemperatureOn).TotalSeconds >= _minerProfile.CpuLETemperatureSeconds) { HighTemperatureOn = message.BornOn; VirtualRoot.ThisLocalWarn(nameof(CpuPackage), $"自动开始挖矿,因为 CPU 温度连续{_minerProfile.CpuLETemperatureSeconds.ToString()}秒不高于{_minerProfile.CpuStartTemperature.ToString()}℃", toConsole: true); NTMinerContext.Instance.StartMine(); } } } } #endregion if (_minerProfile.IsRaiseHighCpuEvent) { if (this.Performance < _minerProfile.HighCpuBaseline) { LowPerformanceOn = message.BornOn; } if ((message.BornOn - LowPerformanceOn).TotalSeconds >= _minerProfile.HighCpuSeconds) { LowPerformanceOn = message.BornOn; VirtualRoot.ThisLocalWarn(nameof(CpuPackage), $"CPU使用率过高:连续{_minerProfile.HighCpuSeconds.ToString()}秒不低于{_minerProfile.HighCpuBaseline.ToString()}%"); } } }); }, location: this.GetType()); }); } }