v2rayN/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs

936 lines
29 KiB
C#
Raw Normal View History

2023-01-01 11:42:01 +00:00
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
2023-04-06 02:44:29 +00:00
using System.Diagnostics;
2023-01-01 11:42:01 +00:00
using System.Reactive;
using System.Reactive.Linq;
using System.Text;
2024-08-20 06:15:29 +00:00
namespace ServiceLib.ViewModels
2023-01-01 11:42:01 +00:00
{
public class MainWindowViewModel : MyReactiveObject
2023-01-01 11:42:01 +00:00
{
#region private prop
private bool _isAdministrator { get; set; }
2023-04-14 12:49:36 +00:00
#endregion private prop
2023-01-01 11:42:01 +00:00
#region ObservableCollection
private IObservableCollection<RoutingItem> _routingItems = new ObservableCollectionExtended<RoutingItem>();
public IObservableCollection<RoutingItem> RoutingItems => _routingItems;
private IObservableCollection<ComboItem> _servers = new ObservableCollectionExtended<ComboItem>();
public IObservableCollection<ComboItem> Servers => _servers;
2023-01-03 08:32:33 +00:00
[Reactive]
2023-01-01 11:42:01 +00:00
public RoutingItem SelectedRouting { get; set; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
[Reactive]
public ComboItem SelectedServer { get; set; }
2023-04-14 12:49:36 +00:00
2023-03-05 11:51:26 +00:00
[Reactive]
public bool BlServers { get; set; }
2023-04-14 12:49:36 +00:00
#endregion ObservableCollection
2023-01-01 11:42:01 +00:00
#region Menu
//servers
public ReactiveCommand<Unit, Unit> AddVmessServerCmd { get; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
public ReactiveCommand<Unit, Unit> AddVlessServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddShadowsocksServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddSocksServerCmd { get; }
2024-04-10 05:32:50 +00:00
public ReactiveCommand<Unit, Unit> AddHttpServerCmd { get; }
2023-01-01 11:42:01 +00:00
public ReactiveCommand<Unit, Unit> AddTrojanServerCmd { get; }
2023-11-28 08:07:53 +00:00
public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; }
2023-12-19 08:03:30 +00:00
public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddWireguardServerCmd { get; }
2023-01-01 11:42:01 +00:00
public ReactiveCommand<Unit, Unit> AddCustomServerCmd { get; }
public ReactiveCommand<Unit, Unit> AddServerViaClipboardCmd { get; }
public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
//Subscription
public ReactiveCommand<Unit, Unit> SubSettingCmd { get; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
public ReactiveCommand<Unit, Unit> SubUpdateCmd { get; }
public ReactiveCommand<Unit, Unit> SubUpdateViaProxyCmd { get; }
2023-01-08 01:24:09 +00:00
public ReactiveCommand<Unit, Unit> SubGroupUpdateCmd { get; }
2023-01-01 11:42:01 +00:00
public ReactiveCommand<Unit, Unit> SubGroupUpdateViaProxyCmd { get; }
//Setting
public ReactiveCommand<Unit, Unit> OptionSettingCmd { get; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
public ReactiveCommand<Unit, Unit> RoutingSettingCmd { get; }
public ReactiveCommand<Unit, Unit> DNSSettingCmd { get; }
2023-01-01 11:42:01 +00:00
public ReactiveCommand<Unit, Unit> GlobalHotkeySettingCmd { get; }
public ReactiveCommand<Unit, Unit> RebootAsAdminCmd { get; }
2023-01-01 11:42:01 +00:00
public ReactiveCommand<Unit, Unit> ClearServerStatisticsCmd { get; }
2024-05-08 03:43:03 +00:00
public ReactiveCommand<Unit, Unit> OpenTheFileLocationCmd { get; }
2023-01-01 11:42:01 +00:00
public ReactiveCommand<Unit, Unit> ReloadCmd { get; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
[Reactive]
public bool BlReloadEnabled { get; set; }
public ReactiveCommand<Unit, Unit> NotifyLeftClickCmd { get; }
2023-04-14 12:49:36 +00:00
#endregion Menu
#region System Proxy
2023-01-01 11:42:01 +00:00
[Reactive]
public bool BlSystemProxyClear { get; set; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
[Reactive]
public bool BlSystemProxySet { get; set; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
[Reactive]
public bool BlSystemProxyNothing { get; set; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
[Reactive]
public bool BlSystemProxyPac { get; set; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
public ReactiveCommand<Unit, Unit> SystemProxyClearCmd { get; }
public ReactiveCommand<Unit, Unit> SystemProxySetCmd { get; }
public ReactiveCommand<Unit, Unit> SystemProxyNothingCmd { get; }
public ReactiveCommand<Unit, Unit> SystemProxyPacCmd { get; }
[Reactive]
public bool BlRouting { get; set; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
[Reactive]
public int SystemProxySelected { get; set; }
2023-04-14 12:49:36 +00:00
#endregion System Proxy
2023-01-01 11:42:01 +00:00
#region UI
[Reactive]
public string InboundDisplay { get; set; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
[Reactive]
public string InboundLanDisplay { get; set; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
[Reactive]
public string RunningServerDisplay { get; set; }
2023-04-14 12:49:36 +00:00
2023-09-17 08:10:05 +00:00
[Reactive]
public string RunningServerToolTipText { get; set; }
2023-04-14 12:49:36 +00:00
2023-02-27 03:30:54 +00:00
[Reactive]
2023-01-01 11:42:01 +00:00
public string RunningInfoDisplay { get; set; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
[Reactive]
public string SpeedProxyDisplay { get; set; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
[Reactive]
public string SpeedDirectDisplay { get; set; }
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
[Reactive]
public bool EnableTun { get; set; }
[Reactive]
2024-07-18 09:39:11 +00:00
public bool ShowClashUI { get; set; }
2024-07-19 02:51:14 +00:00
[Reactive]
public int TabMainSelectedIndex { get; set; }
2023-04-14 12:49:36 +00:00
#endregion UI
2023-01-01 11:42:01 +00:00
#region Init
public MainWindowViewModel(bool isAdministrator, Func<EViewAction, object?, Task<bool>>? updateView)
2023-01-01 11:42:01 +00:00
{
2024-10-07 01:51:41 +00:00
_config = AppHandler.Instance.Config;
2024-10-07 02:59:13 +00:00
2023-01-01 11:42:01 +00:00
_updateView = updateView;
_isAdministrator = isAdministrator;
2024-08-22 11:51:10 +00:00
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(async x => await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
2024-07-18 09:39:11 +00:00
2023-01-01 11:42:01 +00:00
SelectedRouting = new();
SelectedServer = new();
2024-02-01 04:44:47 +00:00
Init();
_config.uiItem.showInTaskbar = true;
if (_config.tunModeItem.enableTun && _isAdministrator)
{
EnableTun = true;
}
else
{
_config.tunModeItem.enableTun = EnableTun = false;
}
2024-02-01 04:44:47 +00:00
#region WhenAnyValue && ReactiveCommand
2023-01-01 11:42:01 +00:00
this.WhenAnyValue(
x => x.SelectedRouting,
y => y != null && !y.remarks.IsNullOrEmpty())
2024-08-22 11:51:10 +00:00
.Subscribe(c => RoutingSelectedChangedAsync(c));
2023-01-01 11:42:01 +00:00
this.WhenAnyValue(
x => x.SelectedServer,
y => y != null && !y.Text.IsNullOrEmpty())
.Subscribe(c => ServerSelectedChanged(c));
2024-07-25 02:26:39 +00:00
SystemProxySelected = (int)_config.systemProxyItem.sysProxyType;
2023-01-01 11:42:01 +00:00
this.WhenAnyValue(
x => x.SystemProxySelected,
2023-02-19 05:34:22 +00:00
y => y >= 0)
2023-01-01 11:42:01 +00:00
.Subscribe(c => DoSystemProxySelected(c));
this.WhenAnyValue(
x => x.EnableTun,
y => y == true)
.Subscribe(c => DoEnableTun(c));
2023-02-04 07:43:49 +00:00
2023-01-01 11:42:01 +00:00
//servers
AddVmessServerCmd = ReactiveCommand.Create(() =>
{
2024-08-22 11:51:10 +00:00
AddServerAsync(true, EConfigType.VMess);
2023-01-01 11:42:01 +00:00
});
AddVlessServerCmd = ReactiveCommand.Create(() =>
{
2024-08-22 11:51:10 +00:00
AddServerAsync(true, EConfigType.VLESS);
2023-01-01 11:42:01 +00:00
});
AddShadowsocksServerCmd = ReactiveCommand.Create(() =>
{
2024-08-22 11:51:10 +00:00
AddServerAsync(true, EConfigType.Shadowsocks);
2023-01-01 11:42:01 +00:00
});
AddSocksServerCmd = ReactiveCommand.Create(() =>
{
2024-09-23 09:17:12 +00:00
AddServerAsync(true, EConfigType.SOCKS);
2023-01-01 11:42:01 +00:00
});
AddHttpServerCmd = ReactiveCommand.Create(() =>
{
2024-09-23 09:17:12 +00:00
AddServerAsync(true, EConfigType.HTTP);
});
2023-01-01 11:42:01 +00:00
AddTrojanServerCmd = ReactiveCommand.Create(() =>
{
2024-08-22 11:51:10 +00:00
AddServerAsync(true, EConfigType.Trojan);
2023-01-01 11:42:01 +00:00
});
AddHysteria2ServerCmd = ReactiveCommand.Create(() =>
{
2024-08-22 11:51:10 +00:00
AddServerAsync(true, EConfigType.Hysteria2);
});
2023-12-19 08:03:30 +00:00
AddTuicServerCmd = ReactiveCommand.Create(() =>
{
2024-09-23 09:17:12 +00:00
AddServerAsync(true, EConfigType.TUIC);
2023-12-19 08:03:30 +00:00
});
AddWireguardServerCmd = ReactiveCommand.Create(() =>
{
2024-09-23 09:17:12 +00:00
AddServerAsync(true, EConfigType.WireGuard);
});
2023-01-01 11:42:01 +00:00
AddCustomServerCmd = ReactiveCommand.Create(() =>
{
2024-08-22 11:51:10 +00:00
AddServerAsync(true, EConfigType.Custom);
2023-01-01 11:42:01 +00:00
});
AddServerViaClipboardCmd = ReactiveCommand.Create(() =>
{
2024-08-22 11:51:10 +00:00
AddServerViaClipboardAsync(null);
2023-01-01 11:42:01 +00:00
});
2024-08-22 11:51:10 +00:00
AddServerViaScanCmd = ReactiveCommand.CreateFromTask(async () =>
2023-01-01 11:42:01 +00:00
{
2024-08-22 11:51:10 +00:00
await _updateView?.Invoke(EViewAction.ScanScreenTask, null);
2023-01-01 11:42:01 +00:00
});
//Subscription
SubSettingCmd = ReactiveCommand.Create(() =>
{
2024-08-22 11:51:10 +00:00
SubSettingAsync();
2023-01-01 11:42:01 +00:00
});
2024-07-18 09:39:11 +00:00
2023-01-01 11:42:01 +00:00
SubUpdateCmd = ReactiveCommand.Create(() =>
{
UpdateSubscriptionProcess("", false);
});
2023-01-08 01:24:09 +00:00
SubUpdateViaProxyCmd = ReactiveCommand.Create(() =>
2023-01-01 11:42:01 +00:00
{
2023-01-08 01:24:09 +00:00
UpdateSubscriptionProcess("", true);
2023-01-01 11:42:01 +00:00
});
2023-01-08 01:24:09 +00:00
SubGroupUpdateCmd = ReactiveCommand.Create(() =>
2023-01-01 11:42:01 +00:00
{
2024-07-18 09:39:11 +00:00
UpdateSubscriptionProcess(_config.subIndexId, false);
2023-01-01 11:42:01 +00:00
});
SubGroupUpdateViaProxyCmd = ReactiveCommand.Create(() =>
{
2024-07-18 09:39:11 +00:00
UpdateSubscriptionProcess(_config.subIndexId, true);
2023-01-01 11:42:01 +00:00
});
//Setting
OptionSettingCmd = ReactiveCommand.Create(() =>
{
2024-08-22 11:51:10 +00:00
OptionSettingAsync();
2023-01-01 11:42:01 +00:00
});
RoutingSettingCmd = ReactiveCommand.Create(() =>
{
2024-08-22 11:51:10 +00:00
RoutingSettingAsync();
2023-01-01 11:42:01 +00:00
});
DNSSettingCmd = ReactiveCommand.Create(() =>
{
2024-08-22 11:51:10 +00:00
DNSSettingAsync();
});
2024-08-22 11:51:10 +00:00
GlobalHotkeySettingCmd = ReactiveCommand.CreateFromTask(async () =>
2023-01-01 11:42:01 +00:00
{
2024-08-22 11:51:10 +00:00
if (await _updateView?.Invoke(EViewAction.GlobalHotkeySettingWindow, null) == true)
2023-01-01 11:42:01 +00:00
{
2024-10-07 02:59:13 +00:00
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
2023-01-01 11:42:01 +00:00
}
});
2023-04-06 02:44:29 +00:00
RebootAsAdminCmd = ReactiveCommand.Create(() =>
{
RebootAsAdmin();
});
2023-01-01 11:42:01 +00:00
ClearServerStatisticsCmd = ReactiveCommand.Create(() =>
{
2024-07-18 09:39:11 +00:00
StatisticsHandler.Instance.ClearAllServerStatistics();
2023-01-01 11:42:01 +00:00
RefreshServers();
});
2024-05-08 03:43:03 +00:00
OpenTheFileLocationCmd = ReactiveCommand.Create(() =>
2023-01-01 11:42:01 +00:00
{
2024-09-28 02:41:30 +00:00
if (Utils.IsWindows())
{
Utils.ProcessStart("Explorer", $"/select,{Utils.GetConfigPath()}");
}
else if (Utils.IsLinux())
{
Utils.ProcessStart("nautilus", Utils.GetConfigPath());
}
2023-01-01 11:42:01 +00:00
});
ReloadCmd = ReactiveCommand.Create(() =>
{
Reload();
});
2024-08-22 11:51:10 +00:00
NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () =>
2023-01-01 11:42:01 +00:00
{
2024-08-22 11:51:10 +00:00
await _updateView?.Invoke(EViewAction.ShowHideWindow, null);
2023-01-01 11:42:01 +00:00
});
//System proxy
SystemProxyClearCmd = ReactiveCommand.Create(() =>
{
SetListenerType(ESysProxyType.ForcedClear);
});
SystemProxySetCmd = ReactiveCommand.Create(() =>
{
SetListenerType(ESysProxyType.ForcedChange);
});
SystemProxyNothingCmd = ReactiveCommand.Create(() =>
{
SetListenerType(ESysProxyType.Unchanged);
});
SystemProxyPacCmd = ReactiveCommand.Create(() =>
{
SetListenerType(ESysProxyType.Pac);
});
2024-02-01 04:44:47 +00:00
#endregion WhenAnyValue && ReactiveCommand
AutoHideStartup();
2023-01-01 11:42:01 +00:00
}
private void Init()
{
2023-12-22 08:03:25 +00:00
ConfigHandler.InitBuiltinRouting(_config);
ConfigHandler.InitBuiltinDNS(_config);
2024-10-07 03:18:24 +00:00
CoreHandler.Instance.Init(_config, UpdateHandler);
2023-01-01 11:42:01 +00:00
2023-02-10 06:36:37 +00:00
if (_config.guiItem.enableStatistics)
2023-01-01 11:42:01 +00:00
{
2024-07-18 09:39:11 +00:00
StatisticsHandler.Instance.Init(_config, UpdateStatisticsHandler);
2023-01-01 11:42:01 +00:00
}
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
2024-02-01 04:44:47 +00:00
RefreshRoutingsMenu();
2024-07-18 09:39:11 +00:00
//RefreshServers();
2024-02-01 04:44:47 +00:00
2023-01-01 11:42:01 +00:00
Reload();
2024-08-22 11:51:10 +00:00
ChangeSystemProxyStatusAsync(_config.systemProxyItem.sysProxyType, true);
2023-01-01 11:42:01 +00:00
}
2023-04-14 12:49:36 +00:00
#endregion Init
2023-01-01 11:42:01 +00:00
#region Actions
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
private void UpdateHandler(bool notify, string msg)
{
2024-10-07 02:59:13 +00:00
NoticeHandler.Instance.SendMessage(msg);
2024-03-07 03:51:45 +00:00
if (notify)
{
2024-10-07 02:59:13 +00:00
NoticeHandler.Instance.Enqueue(msg);
2024-03-07 03:51:45 +00:00
}
2023-01-01 11:42:01 +00:00
}
2023-04-14 12:49:36 +00:00
2023-02-19 04:18:08 +00:00
private void UpdateTaskHandler(bool success, string msg)
2023-01-01 11:42:01 +00:00
{
2024-10-07 02:59:13 +00:00
NoticeHandler.Instance.SendMessageEx(msg);
2023-01-01 11:42:01 +00:00
if (success)
{
2023-02-28 12:23:15 +00:00
var indexIdOld = _config.indexId;
2023-02-04 10:52:17 +00:00
RefreshServers();
2023-02-28 12:23:15 +00:00
if (indexIdOld != _config.indexId)
{
Reload();
}
if (_config.uiItem.enableAutoAdjustMainLvColWidth)
{
2024-08-30 04:59:43 +00:00
_updateView?.Invoke(EViewAction.AdjustMainLvColWidth, null);
}
2023-01-01 11:42:01 +00:00
}
}
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
private void UpdateStatisticsHandler(ServerSpeedItem update)
{
if (!_config.uiItem.showInTaskbar)
{
return;
}
_updateView?.Invoke(EViewAction.DispatcherStatistics, update);
}
public void SetStatisticsResult(ServerSpeedItem update)
2023-01-01 11:42:01 +00:00
{
try
{
SpeedProxyDisplay = string.Format(ResUI.SpeedDisplayText, Global.ProxyTag, Utils.HumanFy(update.proxyUp), Utils.HumanFy(update.proxyDown));
SpeedDirectDisplay = string.Format(ResUI.SpeedDisplayText, Global.DirectTag, Utils.HumanFy(update.directUp), Utils.HumanFy(update.directDown));
if ((update.proxyUp + update.proxyDown) > 0 && DateTime.Now.Second % 3 == 0)
2024-07-18 09:39:11 +00:00
{
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
}
2023-01-01 11:42:01 +00:00
}
catch (Exception ex)
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog(ex.Message, ex);
2023-01-01 11:42:01 +00:00
}
}
2023-04-14 12:49:36 +00:00
2024-08-22 11:51:10 +00:00
public async Task MyAppExitAsync(bool blWindowsShutDown)
2023-01-01 11:42:01 +00:00
{
try
{
2024-01-10 02:43:48 +00:00
Logging.SaveLog("MyAppExit Begin");
2024-08-20 06:15:29 +00:00
//if (blWindowsShutDown)
2024-08-22 11:51:10 +00:00
await _updateView?.Invoke(EViewAction.UpdateSysProxy, true);
2023-01-01 11:42:01 +00:00
2023-12-22 08:03:25 +00:00
ConfigHandler.SaveConfig(_config);
ProfileExHandler.Instance.SaveTo();
2024-07-18 09:39:11 +00:00
StatisticsHandler.Instance.SaveTo();
StatisticsHandler.Instance.Close();
2024-10-07 03:18:24 +00:00
CoreHandler.Instance.CoreStop();
2024-08-20 06:15:29 +00:00
2024-01-10 02:43:48 +00:00
Logging.SaveLog("MyAppExit End");
2023-01-01 11:42:01 +00:00
}
catch { }
finally
{
2024-10-08 06:55:06 +00:00
_updateView?.Invoke(EViewAction.Shutdown, null);
2023-01-01 11:42:01 +00:00
}
}
2024-10-09 12:13:25 +00:00
public async Task UpgradeApp(string fileName)
2024-09-06 10:37:46 +00:00
{
Process process = new()
{
StartInfo = new ProcessStartInfo
{
2024-10-09 12:13:25 +00:00
FileName = "AmazTool",
2024-09-06 10:37:46 +00:00
Arguments = fileName.AppendQuotes(),
WorkingDirectory = Utils.StartupPath()
}
};
process.Start();
if (process.Id > 0)
{
await MyAppExitAsync(false);
}
}
2023-04-14 12:49:36 +00:00
#endregion Actions
2023-01-01 11:42:01 +00:00
#region Servers && Groups
2024-07-18 09:39:11 +00:00
private void RefreshServers()
2023-01-01 11:42:01 +00:00
{
2024-07-18 09:39:11 +00:00
MessageBus.Current.SendMessage("", Global.CommandRefreshProfiles);
2023-01-01 11:42:01 +00:00
}
public void RefreshServersBiz()
2023-01-01 11:42:01 +00:00
{
RefreshServersMenu();
2023-01-01 11:42:01 +00:00
//display running server
var running = ConfigHandler.GetDefaultServer(_config);
if (running != null)
{
RunningServerDisplay =
RunningServerToolTipText = running.GetSummary();
}
else
{
RunningServerDisplay =
RunningServerToolTipText = ResUI.CheckServerSettings;
}
2023-01-01 11:42:01 +00:00
}
private void RefreshServersMenu()
{
2024-10-07 01:51:41 +00:00
var lstModel = AppHandler.Instance.ProfileItems(_config.subIndexId, "");
2024-07-18 09:39:11 +00:00
2023-01-01 11:42:01 +00:00
_servers.Clear();
2024-07-18 09:39:11 +00:00
if (lstModel.Count > _config.guiItem.trayMenuServersLimit)
2023-01-01 11:42:01 +00:00
{
2023-03-05 11:51:26 +00:00
BlServers = false;
2023-01-01 11:42:01 +00:00
return;
}
2023-03-05 11:51:26 +00:00
BlServers = true;
2024-07-18 09:39:11 +00:00
for (int k = 0; k < lstModel.Count; k++)
2023-01-01 11:42:01 +00:00
{
2024-07-18 09:39:11 +00:00
ProfileItem it = lstModel[k];
2023-01-01 11:42:01 +00:00
string name = it.GetSummary();
var item = new ComboItem() { ID = it.indexId, Text = name };
_servers.Add(item);
2023-02-19 11:15:02 +00:00
if (_config.indexId == it.indexId)
2023-01-01 11:42:01 +00:00
{
SelectedServer = item;
}
}
}
2024-07-18 09:39:11 +00:00
private void RefreshSubscriptions()
2023-01-01 11:42:01 +00:00
{
2024-07-18 09:39:11 +00:00
Locator.Current.GetService<ProfilesViewModel>()?.RefreshSubscriptions();
2023-01-01 11:42:01 +00:00
}
2023-04-14 12:49:36 +00:00
#endregion Servers && Groups
2023-01-01 11:42:01 +00:00
#region Add Servers
2023-04-14 12:49:36 +00:00
2024-08-22 11:51:10 +00:00
public async Task AddServerAsync(bool blNew, EConfigType eConfigType)
2023-01-01 11:42:01 +00:00
{
2024-07-18 09:39:11 +00:00
ProfileItem item = new()
2023-01-01 11:42:01 +00:00
{
2024-07-18 09:39:11 +00:00
subid = _config.subIndexId,
configType = eConfigType,
isSub = false,
};
2023-01-01 11:42:01 +00:00
bool? ret = false;
if (eConfigType == EConfigType.Custom)
{
2024-08-22 11:51:10 +00:00
ret = await _updateView?.Invoke(EViewAction.AddServer2Window, item);
2023-01-01 11:42:01 +00:00
}
else
{
2024-08-22 11:51:10 +00:00
ret = await _updateView?.Invoke(EViewAction.AddServerWindow, item);
2023-01-01 11:42:01 +00:00
}
if (ret == true)
{
RefreshServers();
if (item.indexId == _config.indexId)
{
Reload();
}
}
}
2024-08-22 11:51:10 +00:00
public async Task AddServerViaClipboardAsync(string? clipboardData)
2023-01-01 11:42:01 +00:00
{
2024-08-20 06:15:29 +00:00
if (clipboardData == null)
{
2024-08-22 11:51:10 +00:00
await _updateView?.Invoke(EViewAction.AddServerViaClipboard, null);
2024-08-20 06:15:29 +00:00
return;
}
int ret = ConfigHandler.AddBatchServers(_config, clipboardData, _config.subIndexId, false);
2023-01-01 11:42:01 +00:00
if (ret > 0)
{
2024-07-18 09:39:11 +00:00
RefreshSubscriptions();
2023-01-01 11:42:01 +00:00
RefreshServers();
2024-10-07 02:59:13 +00:00
NoticeHandler.Instance.Enqueue(string.Format(ResUI.SuccessfullyImportedServerViaClipboard, ret));
2023-01-01 11:42:01 +00:00
}
}
2023-04-14 12:49:36 +00:00
public void ScanScreenTaskAsync(string result)
2023-01-01 11:42:01 +00:00
{
2024-03-26 06:26:03 +00:00
if (Utils.IsNullOrEmpty(result))
2023-01-01 11:42:01 +00:00
{
2024-10-07 02:59:13 +00:00
NoticeHandler.Instance.Enqueue(ResUI.NoValidQRcodeFound);
2023-01-01 11:42:01 +00:00
}
else
{
2024-07-18 09:39:11 +00:00
int ret = ConfigHandler.AddBatchServers(_config, result, _config.subIndexId, false);
2023-01-01 11:42:01 +00:00
if (ret > 0)
{
2024-07-18 09:39:11 +00:00
RefreshSubscriptions();
2023-01-01 11:42:01 +00:00
RefreshServers();
2024-10-07 02:59:13 +00:00
NoticeHandler.Instance.Enqueue(ResUI.SuccessfullyImportedServerViaScan);
2023-01-01 11:42:01 +00:00
}
}
}
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
private void SetDefaultServer(string indexId)
{
2024-03-26 06:26:03 +00:00
if (Utils.IsNullOrEmpty(indexId))
2023-01-01 11:42:01 +00:00
{
return;
}
if (indexId == _config.indexId)
{
return;
}
2024-10-07 01:51:41 +00:00
var item = AppHandler.Instance.GetProfileItem(indexId);
2023-01-01 11:42:01 +00:00
if (item is null)
{
2024-10-07 02:59:13 +00:00
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer);
2023-01-01 11:42:01 +00:00
return;
}
2023-12-22 08:03:25 +00:00
if (ConfigHandler.SetDefaultServerIndex(_config, indexId) == 0)
2023-01-01 11:42:01 +00:00
{
RefreshServers();
Reload();
}
}
2023-04-14 12:49:36 +00:00
2023-01-01 11:42:01 +00:00
private void ServerSelectedChanged(bool c)
{
if (!c)
{
return;
}
if (SelectedServer == null)
{
return;
}
2024-03-26 06:26:03 +00:00
if (Utils.IsNullOrEmpty(SelectedServer.ID))
2023-01-01 11:42:01 +00:00
{
return;
}
SetDefaultServer(SelectedServer.ID);
}
2024-09-16 03:09:44 +00:00
public async Task TestServerAvailability()
2023-01-01 11:42:01 +00:00
{
2023-12-22 08:03:25 +00:00
var item = ConfigHandler.GetDefaultServer(_config);
if (item == null)
2023-01-01 11:42:01 +00:00
{
return;
}
2024-10-07 02:39:43 +00:00
await (new UpdateService()).RunAvailabilityCheck(async (bool success, string msg) =>
2023-01-01 11:42:01 +00:00
{
2024-10-07 02:59:13 +00:00
NoticeHandler.Instance.SendMessageEx(msg);
2024-10-08 06:55:06 +00:00
_updateView?.Invoke(EViewAction.DispatcherServerAvailability, msg);
2023-01-01 11:42:01 +00:00
});
}
public void TestServerAvailabilityResult(string msg)
{
RunningInfoDisplay = msg;
}
2023-04-14 12:49:36 +00:00
#endregion Add Servers
2023-01-01 11:42:01 +00:00
#region Subscription
2024-08-22 11:51:10 +00:00
private async Task SubSettingAsync()
2023-01-01 11:42:01 +00:00
{
2024-08-22 11:51:10 +00:00
if (await _updateView?.Invoke(EViewAction.SubSettingWindow, null) == true)
2023-01-01 11:42:01 +00:00
{
2024-07-18 09:39:11 +00:00
RefreshSubscriptions();
2023-01-01 11:42:01 +00:00
}
}
2024-08-27 08:09:07 +00:00
public void UpdateSubscriptionProcess(string subId, bool blProxy)
2023-02-08 11:20:44 +00:00
{
2024-10-07 02:39:43 +00:00
(new UpdateService()).UpdateSubscriptionProcess(_config, subId, blProxy, UpdateTaskHandler);
2023-01-01 11:42:01 +00:00
}
2023-04-14 12:49:36 +00:00
#endregion Subscription
2023-01-01 11:42:01 +00:00
#region Setting
2024-08-22 11:51:10 +00:00
private async Task OptionSettingAsync()
2023-01-01 11:42:01 +00:00
{
2024-08-22 11:51:10 +00:00
var ret = await _updateView?.Invoke(EViewAction.OptionSettingWindow, null);
2023-01-01 11:42:01 +00:00
if (ret == true)
{
//RefreshServers();
Reload();
}
}
2023-04-14 12:49:36 +00:00
2024-08-22 11:51:10 +00:00
private async Task RoutingSettingAsync()
2023-01-01 11:42:01 +00:00
{
2024-08-22 11:51:10 +00:00
var ret = await _updateView?.Invoke(EViewAction.RoutingSettingWindow, null);
2023-01-01 11:42:01 +00:00
if (ret == true)
{
2023-12-22 08:03:25 +00:00
ConfigHandler.InitBuiltinRouting(_config);
2023-01-01 11:42:01 +00:00
RefreshRoutingsMenu();
//RefreshServers();
Reload();
}
}
2023-04-27 08:20:13 +00:00
2024-08-22 11:51:10 +00:00
private async Task DNSSettingAsync()
{
2024-08-22 11:51:10 +00:00
var ret = await _updateView?.Invoke(EViewAction.DNSSettingWindow, null);
if (ret == true)
{
Reload();
}
}
2023-01-01 11:42:01 +00:00
2023-04-06 02:44:29 +00:00
private void RebootAsAdmin()
{
ProcessStartInfo startInfo = new()
{
UseShellExecute = true,
Arguments = Global.RebootAs,
2024-03-26 06:26:03 +00:00
WorkingDirectory = Utils.StartupPath(),
FileName = Utils.GetExePath().AppendQuotes(),
2023-04-06 02:44:29 +00:00
Verb = "runas",
};
try
{
Process.Start(startInfo);
2024-08-22 11:51:10 +00:00
MyAppExitAsync(false);
}
catch { }
2023-04-06 02:44:29 +00:00
}
2023-04-14 12:49:36 +00:00
#endregion Setting
2023-01-01 11:42:01 +00:00
2024-03-07 01:06:35 +00:00
#region core job
2023-01-01 11:42:01 +00:00
public void Reload()
{
2024-01-30 09:18:00 +00:00
BlReloadEnabled = false;
2024-08-22 11:51:10 +00:00
LoadCore().ContinueWith(async task =>
2024-01-30 09:18:00 +00:00
{
2024-09-16 03:09:44 +00:00
await TestServerAvailability();
2024-01-30 09:18:00 +00:00
2024-10-08 06:55:06 +00:00
_updateView?.Invoke(EViewAction.DispatcherReload, null);
2024-01-30 09:18:00 +00:00
});
2023-01-01 11:42:01 +00:00
}
public void ReloadResult()
{
2024-08-22 11:51:10 +00:00
ChangeSystemProxyStatusAsync(_config.systemProxyItem.sysProxyType, false);
BlReloadEnabled = true;
2024-10-05 09:51:31 +00:00
ShowClashUI = _config.IsRunningCore(ECoreType.sing_box);
if (ShowClashUI)
{
Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload();
}
else { TabMainSelectedIndex = 0; }
}
2024-03-07 01:06:35 +00:00
private async Task LoadCore()
2023-01-01 11:42:01 +00:00
{
await Task.Run(() =>
{
2024-08-20 06:15:29 +00:00
//if (_config.tunModeItem.enableTun)
//{
// Task.Delay(1000).Wait();
// WindowsUtils.RemoveTunDevice();
//}
var node = ConfigHandler.GetDefaultServer(_config);
2024-10-07 03:18:24 +00:00
CoreHandler.Instance.LoadCore(node);
2024-06-28 02:41:17 +00:00
});
2023-01-01 11:42:01 +00:00
}
2024-09-01 08:39:45 +00:00
public void CloseCore()
2023-01-01 11:42:01 +00:00
{
2023-12-22 08:03:25 +00:00
ConfigHandler.SaveConfig(_config, false);
2023-01-01 11:42:01 +00:00
2024-08-22 11:51:10 +00:00
ChangeSystemProxyStatusAsync(ESysProxyType.ForcedClear, false);
2023-01-01 11:42:01 +00:00
2024-10-07 03:18:24 +00:00
CoreHandler.Instance.CoreStop();
2023-01-01 11:42:01 +00:00
}
2024-03-07 01:06:35 +00:00
#endregion core job
2023-01-01 11:42:01 +00:00
#region System proxy and Routings
public void SetListenerType(ESysProxyType type)
{
2024-07-25 02:26:39 +00:00
if (_config.systemProxyItem.sysProxyType == type)
2023-01-01 11:42:01 +00:00
{
return;
}
2024-07-25 02:26:39 +00:00
_config.systemProxyItem.sysProxyType = type;
2024-08-22 11:51:10 +00:00
ChangeSystemProxyStatusAsync(type, true);
2023-01-01 11:42:01 +00:00
2024-07-25 02:26:39 +00:00
SystemProxySelected = (int)_config.systemProxyItem.sysProxyType;
2023-12-22 08:03:25 +00:00
ConfigHandler.SaveConfig(_config, false);
2023-01-01 11:42:01 +00:00
}
2024-08-22 11:51:10 +00:00
private async Task ChangeSystemProxyStatusAsync(ESysProxyType type, bool blChange)
2023-01-01 11:42:01 +00:00
{
//await _updateView?.Invoke(EViewAction.UpdateSysProxy, _config.tunModeItem.enableTun ? true : false);
2024-10-08 06:55:06 +00:00
_updateView?.Invoke(EViewAction.UpdateSysProxy, false);
2024-10-07 02:59:13 +00:00
NoticeHandler.Instance.SendMessageEx($"{ResUI.TipChangeSystemProxy} - {_config.systemProxyItem.sysProxyType.ToString()}");
2023-01-01 11:42:01 +00:00
BlSystemProxyClear = (type == ESysProxyType.ForcedClear);
BlSystemProxySet = (type == ESysProxyType.ForcedChange);
BlSystemProxyNothing = (type == ESysProxyType.Unchanged);
BlSystemProxyPac = (type == ESysProxyType.Pac);
2023-01-01 11:42:01 +00:00
InboundDisplayStaus();
2023-01-01 11:42:01 +00:00
if (blChange)
{
2024-10-08 06:55:06 +00:00
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
}
2023-01-01 11:42:01 +00:00
}
private void RefreshRoutingsMenu()
{
_routingItems.Clear();
2023-02-10 06:51:00 +00:00
if (!_config.routingBasicItem.enableRoutingAdvanced)
2023-01-01 11:42:01 +00:00
{
BlRouting = false;
return;
}
BlRouting = true;
2024-10-07 01:51:41 +00:00
var routings = AppHandler.Instance.RoutingItems();
2023-01-01 11:42:01 +00:00
foreach (var item in routings)
{
_routingItems.Add(item);
2023-02-19 11:15:02 +00:00
if (item.id == _config.routingBasicItem.routingIndexId)
2023-01-01 11:42:01 +00:00
{
SelectedRouting = item;
}
}
}
2024-08-22 11:51:10 +00:00
private async Task RoutingSelectedChangedAsync(bool c)
2023-01-01 11:42:01 +00:00
{
if (!c)
{
return;
}
if (SelectedRouting == null)
{
return;
}
2024-10-07 01:51:41 +00:00
var item = AppHandler.Instance.GetRoutingItem(SelectedRouting?.id);
2023-01-01 11:42:01 +00:00
if (item is null)
{
return;
}
2023-02-10 06:51:00 +00:00
if (_config.routingBasicItem.routingIndexId == item.id)
2023-01-01 11:42:01 +00:00
{
return;
}
2023-12-22 08:03:25 +00:00
if (ConfigHandler.SetDefaultRouting(_config, item) == 0)
2023-01-01 11:42:01 +00:00
{
2024-10-07 02:59:13 +00:00
NoticeHandler.Instance.SendMessageEx(ResUI.TipChangeRouting);
2023-01-01 11:42:01 +00:00
Reload();
2024-10-08 06:55:06 +00:00
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
2023-01-01 11:42:01 +00:00
}
}
2023-04-14 12:49:36 +00:00
private void DoSystemProxySelected(bool c)
2023-01-01 11:42:01 +00:00
{
if (!c)
{
return;
}
2024-07-25 02:26:39 +00:00
if (_config.systemProxyItem.sysProxyType == (ESysProxyType)SystemProxySelected)
2023-01-01 11:42:01 +00:00
{
return;
}
SetListenerType((ESysProxyType)SystemProxySelected);
}
2023-04-14 12:49:36 +00:00
private void DoEnableTun(bool c)
2023-01-01 11:42:01 +00:00
{
if (_config.tunModeItem.enableTun != EnableTun)
{
_config.tunModeItem.enableTun = EnableTun;
2024-01-14 02:23:46 +00:00
// When running as a non-administrator, reboot to administrator mode
if (EnableTun && !_isAdministrator)
{
2024-01-14 02:23:46 +00:00
_config.tunModeItem.enableTun = false;
RebootAsAdmin();
return;
}
ConfigHandler.SaveConfig(_config);
2023-04-27 08:20:13 +00:00
Reload();
2023-01-01 11:42:01 +00:00
}
}
2023-04-14 12:49:36 +00:00
#endregion System proxy and Routings
2023-01-01 11:42:01 +00:00
#region UI
public void InboundDisplayStaus()
{
2023-02-19 05:34:22 +00:00
StringBuilder sb = new();
2024-10-07 01:51:41 +00:00
sb.Append($"[{EInboundProtocol.socks}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)}]");
2023-01-01 11:42:01 +00:00
sb.Append(" | ");
2024-07-25 02:26:39 +00:00
//if (_config.systemProxyItem.sysProxyType == ESysProxyType.ForcedChange)
2023-01-01 11:42:01 +00:00
//{
// sb.Append($"[{Global.InboundHttp}({ResUI.SystemProxy}):{LazyConfig.Instance.GetLocalPort(Global.InboundHttp)}]");
//}
//else
//{
2024-10-07 01:51:41 +00:00
sb.Append($"[{EInboundProtocol.http}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.http)}]");
2023-01-01 11:42:01 +00:00
//}
2023-02-19 05:34:22 +00:00
InboundDisplay = $"{ResUI.LabLocal}:{sb}";
2023-01-01 11:42:01 +00:00
if (_config.inbound[0].allowLANConn)
{
if (_config.inbound[0].newPort4LAN)
{
2023-02-19 05:34:22 +00:00
StringBuilder sb2 = new();
2024-10-07 01:51:41 +00:00
sb2.Append($"[{EInboundProtocol.socks}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks2)}]");
2023-01-01 11:42:01 +00:00
sb2.Append(" | ");
2024-10-07 01:51:41 +00:00
sb2.Append($"[{EInboundProtocol.http}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.http2)}]");
2023-02-19 05:34:22 +00:00
InboundLanDisplay = $"{ResUI.LabLAN}:{sb2}";
2023-01-01 11:42:01 +00:00
}
else
{
2023-02-19 05:34:22 +00:00
InboundLanDisplay = $"{ResUI.LabLAN}:{sb}";
2023-01-01 11:42:01 +00:00
}
}
else
{
InboundLanDisplay = $"{ResUI.LabLAN}:None";
}
}
private void AutoHideStartup()
{
if (_config.uiItem.autoHideStartup)
2023-01-01 11:42:01 +00:00
{
Observable.Range(1, 1)
2024-02-01 04:44:47 +00:00
.Delay(TimeSpan.FromSeconds(1))
2024-08-22 11:51:10 +00:00
.Subscribe(async x =>
2023-01-01 11:42:01 +00:00
{
2024-08-22 11:51:10 +00:00
await _updateView?.Invoke(EViewAction.ShowHideWindow, false);
2023-01-01 11:42:01 +00:00
});
}
}
2023-04-14 12:49:36 +00:00
#endregion UI
2023-01-01 11:42:01 +00:00
}
2024-07-25 02:26:39 +00:00
}