using Avalonia.Controls; using Shaker.Models; using ShakerApp.Tools; using SukiUI.Toasts; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Input; namespace ShakerApp.ViewModels { public class DeviceMangerViewModel : ViewModelBase { public override bool CanResize => false; public override double Width => 960; public override double Height => 660; private object locker = new object(); private DeviceMangerViewModel() { ButtonVisibily = false; Content = typeof(Views.DeviceMangerView); } static DeviceMangerViewModel() { } public static DeviceMangerViewModel Instance { get; } = new DeviceMangerViewModel(); [AllowNull] private DeviceInfoViewModel? currentDevice; public ObservableCollection> Devices { get; } = new ObservableCollection>(); public ICommand SearchDeviceCommand => new CommunityToolkit.Mvvm.Input.RelayCommand(() => { SearchEnabled = false; Task.Run(() => SearchDevice()); }); public override void InitData() { base.InitData(); Devices.Clear(); CurrentDevice = null; PopupVisibily = false; } public bool SearchEnabled { get => searchEnabled; set => SetProperty(ref searchEnabled, value); } private CancellationTokenSource source = new CancellationTokenSource(); private void WaitMsg(int timeout, CancellationTokenSource source) { Task.Run(async () => { await Task.Delay(timeout, source.Token); source.Cancel(); }); } public string Msg { get => msg; set =>SetProperty(ref msg , value); } private void SearchDevice() { int timeout = 5000; Tools.DispatherInovke.Inovke(() => { Devices.Clear(); CurrentDevice = null; }); Msg = App.Current?.FindResource("DeviceSearching") + ""; PopupVisibily = true; DateTime start = DateTime.Now; LogViewModel.Instance.AddLog(App.Current?.FindResource("DeviceSearch") + ""); System.Net.Sockets.UdpClient udpClient = new System.Net.Sockets.UdpClient(Topic.DISCOVERYPORT - 1); udpClient.JoinMulticastGroup(IPAddress.Parse("239.1.0.2")); source = new CancellationTokenSource(); var tast = Task.Run(() => { System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() .SelectMany(x => x.GetIPProperties().UnicastAddresses.Where(x => x.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)) .ToList() .ForEach(x => { Task.Run(async () => { try { System.Net.Sockets.UdpClient udpClient = new System.Net.Sockets.UdpClient(new IPEndPoint(x.Address, Topic.DISCOVERYPORT - 1)); udpClient.JoinMulticastGroup(IPAddress.Parse("239.1.0.2")); SearchDeviceModel search = new Shaker.Models.SearchDeviceModel(); udpClient.Send(search.GetBytes(), new System.Net.IPEndPoint(IPAddress.Broadcast, Topic.DISCOVERYPORT)); while (!source.IsCancellationRequested) { var result = await udpClient.ReceiveAsync(source.Token); if (!source.IsCancellationRequested && result.Buffer != null && result.Buffer.Length > 0) { try { var deviceinfo = result.Buffer.GetValue(); if (deviceinfo != null && deviceinfo.Success) { Tools.DispatherInovke.Inovke(() => { lock (locker) { if (Devices.Any(x => x.Value.IP == deviceinfo.DeviceInfoModel.IP)) return; Devices.Add(new IndexValueItemViewModel(Devices.Count + 1, new DeviceInfoViewModel(deviceinfo.DeviceInfoModel))); Msg = string.Format(App.Current?.FindResource("DeviceFoundCount") + "", Devices.Count); LogViewModel.Instance.AddLog($"{App.Current?.FindResource("FindedDeviceInfo")}:{deviceinfo.DeviceInfoModel}"); } }); } } catch { } } } udpClient.Close(); } catch { } }); }); }); Task.Delay(timeout, source.Token).Wait(); source?.Cancel(); PopupVisibily = false; udpClient.Close(); Tools.DispatherInovke.Inovke(() => { SearchEnabled = true; if (Devices.Count == 0) { LogViewModel.Instance.AddLog(App.Current?.FindResource("DeviceNoFound") + ""); ShowToast(App.Current?.FindResource("DeviceNoFound") + "", Avalonia.Controls.Notifications.NotificationType.Error); } }); } private bool popupVisibily = false; public bool PopupVisibily { get => popupVisibily; set => SetProperty(ref popupVisibily, value); } [AllowNull] private bool searchEnabled = true; private string msg = string.Empty; public ICommand ConnectDeviceCommand => new CommunityToolkit.Mvvm.Input.RelayCommand(ConnectDevice); private async void ConnectDevice() { if (CurrentDevice == null) return; Msg = App.Current?.FindResource("DeviceConnecting") + ""; PopupVisibily = true; await Task.Run(() => CommunicationViewModel.Instance.Connect(CurrentDevice.IP, CurrentDevice.Port)); if (CommunicationViewModel.Instance.LocalIsConnect) { CloseWindowAction?.Invoke(); ShowToast(App.Current?.FindResource("DeviceConnectSuccess") + "", Avalonia.Controls.Notifications.NotificationType.Error); return; } MainPageViewModel.Instance.ShowToast(App.Current?.FindResource("DeviceNoFound") + "", Avalonia.Controls.Notifications.NotificationType.Success); } public ICommand DisConnectDeviceCommand => new CommunityToolkit.Mvvm.Input.RelayCommand(DisConnectDevice); private void DisConnectDevice() { CommunicationViewModel.Instance.DisConnect(); CurrentDevice = null; } public DeviceInfoViewModel? CurrentDevice { get => currentDevice; set => SetProperty(ref currentDevice, value); } } }