Code clean

This commit is contained in:
2dust 2025-11-02 15:25:41 +08:00
parent b218f0b501
commit ab6a6b879e
45 changed files with 326 additions and 52 deletions

View file

@ -8,7 +8,7 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch> <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow> <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<NoWarn>CA1031;CS1591;NU1507;CA1416;IDE0058</NoWarn> <NoWarn>CA1031;CS1591;NU1507;CA1416;IDE0058;IDE0053;IDE0200</NoWarn>
<Nullable>annotations</Nullable> <Nullable>annotations</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Authors>2dust</Authors> <Authors>2dust</Authors>

View file

@ -306,7 +306,10 @@ public class Utils
public static bool IsBase64String(string? plainText) public static bool IsBase64String(string? plainText)
{ {
if (plainText.IsNullOrEmpty()) if (plainText.IsNullOrEmpty())
{
return false; return false;
}
var buffer = new Span<byte>(new byte[plainText.Length]); var buffer = new Span<byte>(new byte[plainText.Length]);
return Convert.TryFromBase64String(plainText, buffer, out var _); return Convert.TryFromBase64String(plainText, buffer, out var _);
} }
@ -520,40 +523,62 @@ public class Utils
{ {
// Loopback address check (127.0.0.1 for IPv4, ::1 for IPv6) // Loopback address check (127.0.0.1 for IPv4, ::1 for IPv6)
if (IPAddress.IsLoopback(address)) if (IPAddress.IsLoopback(address))
{
return true; return true;
}
var ipBytes = address.GetAddressBytes(); var ipBytes = address.GetAddressBytes();
if (address.AddressFamily == AddressFamily.InterNetwork) if (address.AddressFamily == AddressFamily.InterNetwork)
{ {
// IPv4 private address check // IPv4 private address check
if (ipBytes[0] == 10) if (ipBytes[0] == 10)
{
return true; return true;
}
if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31) if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31)
{
return true; return true;
}
if (ipBytes[0] == 192 && ipBytes[1] == 168) if (ipBytes[0] == 192 && ipBytes[1] == 168)
{
return true; return true;
}
} }
else if (address.AddressFamily == AddressFamily.InterNetworkV6) else if (address.AddressFamily == AddressFamily.InterNetworkV6)
{ {
// IPv6 private address check // IPv6 private address check
// Link-local address fe80::/10 // Link-local address fe80::/10
if (ipBytes[0] == 0xfe && (ipBytes[1] & 0xc0) == 0x80) if (ipBytes[0] == 0xfe && (ipBytes[1] & 0xc0) == 0x80)
{
return true; return true;
}
// Unique local address fc00::/7 (typically fd00::/8) // Unique local address fc00::/7 (typically fd00::/8)
if ((ipBytes[0] & 0xfe) == 0xfc) if ((ipBytes[0] & 0xfe) == 0xfc)
{
return true; return true;
}
// Private portion in IPv4-mapped addresses ::ffff:0:0/96 // Private portion in IPv4-mapped addresses ::ffff:0:0/96
if (address.IsIPv4MappedToIPv6) if (address.IsIPv4MappedToIPv6)
{ {
var ipv4Bytes = ipBytes.Skip(12).ToArray(); var ipv4Bytes = ipBytes.Skip(12).ToArray();
if (ipv4Bytes[0] == 10) if (ipv4Bytes[0] == 10)
{
return true; return true;
}
if (ipv4Bytes[0] == 172 && ipv4Bytes[1] >= 16 && ipv4Bytes[1] <= 31) if (ipv4Bytes[0] == 172 && ipv4Bytes[1] >= 16 && ipv4Bytes[1] <= 31)
{
return true; return true;
}
if (ipv4Bytes[0] == 192 && ipv4Bytes[1] == 168) if (ipv4Bytes[0] == 192 && ipv4Bytes[1] == 168)
{
return true; return true;
}
} }
} }
} }
@ -708,10 +733,16 @@ public class Utils
foreach (var host in hostsList) foreach (var host in hostsList)
{ {
if (host.StartsWith("#")) if (host.StartsWith("#"))
{
continue; continue;
}
var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (hostItem.Length < 2) if (hostItem.Length < 2)
{
continue; continue;
}
systemHosts.Add(hostItem[1], hostItem[0]); systemHosts.Add(hostItem[1], hostItem[0]);
} }
} }

View file

@ -1651,7 +1651,9 @@ public static class ConfigHandler
var uri = Utils.TryUri(url); var uri = Utils.TryUri(url);
if (uri == null) if (uri == null)
{
return -1; return -1;
}
//Do not allow http protocol //Do not allow http protocol
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost)) if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
{ {
@ -2018,11 +2020,15 @@ public static class ConfigHandler
var downloadHandle = new DownloadService(); var downloadHandle = new DownloadService();
var templateContent = await downloadHandle.TryDownloadString(config.ConstItem.RouteRulesTemplateSourceUrl, true, ""); var templateContent = await downloadHandle.TryDownloadString(config.ConstItem.RouteRulesTemplateSourceUrl, true, "");
if (templateContent.IsNullOrEmpty()) if (templateContent.IsNullOrEmpty())
{
return await InitBuiltinRouting(config, blImportAdvancedRules); // fallback return await InitBuiltinRouting(config, blImportAdvancedRules); // fallback
}
var template = JsonUtils.Deserialize<RoutingTemplate>(templateContent); var template = JsonUtils.Deserialize<RoutingTemplate>(templateContent);
if (template == null) if (template == null)
{
return await InitBuiltinRouting(config, blImportAdvancedRules); // fallback return await InitBuiltinRouting(config, blImportAdvancedRules); // fallback
}
var items = await AppManager.Instance.RoutingItems(); var items = await AppManager.Instance.RoutingItems();
var maxSort = items.Count; var maxSort = items.Count;
@ -2035,14 +2041,18 @@ public static class ConfigHandler
var item = template.RoutingItems[i]; var item = template.RoutingItems[i];
if (item.Url.IsNullOrEmpty() && item.RuleSet.IsNullOrEmpty()) if (item.Url.IsNullOrEmpty() && item.RuleSet.IsNullOrEmpty())
{
continue; continue;
}
var ruleSetsString = !item.RuleSet.IsNullOrEmpty() var ruleSetsString = !item.RuleSet.IsNullOrEmpty()
? item.RuleSet ? item.RuleSet
: await downloadHandle.TryDownloadString(item.Url, true, ""); : await downloadHandle.TryDownloadString(item.Url, true, "");
if (ruleSetsString.IsNullOrEmpty()) if (ruleSetsString.IsNullOrEmpty())
{
continue; continue;
}
item.Remarks = $"{template.Version}-{item.Remarks}"; item.Remarks = $"{template.Version}-{item.Remarks}";
item.Enabled = true; item.Enabled = true;
@ -2238,17 +2248,25 @@ public static class ConfigHandler
var downloadHandle = new DownloadService(); var downloadHandle = new DownloadService();
var templateContent = await downloadHandle.TryDownloadString(url, true, ""); var templateContent = await downloadHandle.TryDownloadString(url, true, "");
if (templateContent.IsNullOrEmpty()) if (templateContent.IsNullOrEmpty())
{
return currentItem; return currentItem;
}
var template = JsonUtils.Deserialize<DNSItem>(templateContent); var template = JsonUtils.Deserialize<DNSItem>(templateContent);
if (template == null) if (template == null)
{
return currentItem; return currentItem;
}
if (!template.NormalDNS.IsNullOrEmpty()) if (!template.NormalDNS.IsNullOrEmpty())
{
template.NormalDNS = await downloadHandle.TryDownloadString(template.NormalDNS, true, ""); template.NormalDNS = await downloadHandle.TryDownloadString(template.NormalDNS, true, "");
}
if (!template.TunDNS.IsNullOrEmpty()) if (!template.TunDNS.IsNullOrEmpty())
{
template.TunDNS = await downloadHandle.TryDownloadString(template.TunDNS, true, ""); template.TunDNS = await downloadHandle.TryDownloadString(template.TunDNS, true, "");
}
template.Id = currentItem.Id; template.Id = currentItem.Id;
template.Enabled = currentItem.Enabled; template.Enabled = currentItem.Enabled;
@ -2282,10 +2300,16 @@ public static class ConfigHandler
var downloadHandle = new DownloadService(); var downloadHandle = new DownloadService();
var templateContent = await downloadHandle.TryDownloadString(url, true, ""); var templateContent = await downloadHandle.TryDownloadString(url, true, "");
if (templateContent.IsNullOrEmpty()) if (templateContent.IsNullOrEmpty())
{
return null; return null;
}
var template = JsonUtils.Deserialize<SimpleDNSItem>(templateContent); var template = JsonUtils.Deserialize<SimpleDNSItem>(templateContent);
if (template == null) if (template == null)
{
return null; return null;
}
return template; return template;
} }

View file

@ -12,7 +12,9 @@ public class Hysteria2Fmt : BaseFmt
var url = Utils.TryUri(str); var url = Utils.TryUri(str);
if (url == null) if (url == null)
{
return null; return null;
}
item.Address = url.IdnHost; item.Address = url.IdnHost;
item.Port = url.Port; item.Port = url.Port;
@ -32,7 +34,10 @@ public class Hysteria2Fmt : BaseFmt
public static string? ToUri(ProfileItem? item) public static string? ToUri(ProfileItem? item)
{ {
if (item == null) if (item == null)
{
return null; return null;
}
var url = string.Empty; var url = string.Empty;
var remark = string.Empty; var remark = string.Empty;

View file

@ -81,21 +81,36 @@ public class ActionPrecheckManager(Config config)
{ {
case EConfigType.VMess: case EConfigType.VMess:
if (item.Id.IsNullOrEmpty() || !Utils.IsGuidByParse(item.Id)) if (item.Id.IsNullOrEmpty() || !Utils.IsGuidByParse(item.Id))
{
errors.Add(string.Format(ResUI.InvalidProperty, "Id")); errors.Add(string.Format(ResUI.InvalidProperty, "Id"));
}
break; break;
case EConfigType.VLESS: case EConfigType.VLESS:
if (item.Id.IsNullOrEmpty() || (!Utils.IsGuidByParse(item.Id) && item.Id.Length > 30)) if (item.Id.IsNullOrEmpty() || (!Utils.IsGuidByParse(item.Id) && item.Id.Length > 30))
{
errors.Add(string.Format(ResUI.InvalidProperty, "Id")); errors.Add(string.Format(ResUI.InvalidProperty, "Id"));
}
if (!Global.Flows.Contains(item.Flow)) if (!Global.Flows.Contains(item.Flow))
{
errors.Add(string.Format(ResUI.InvalidProperty, "Flow")); errors.Add(string.Format(ResUI.InvalidProperty, "Flow"));
}
break; break;
case EConfigType.Shadowsocks: case EConfigType.Shadowsocks:
if (item.Id.IsNullOrEmpty()) if (item.Id.IsNullOrEmpty())
{
errors.Add(string.Format(ResUI.InvalidProperty, "Id")); errors.Add(string.Format(ResUI.InvalidProperty, "Id"));
}
if (string.IsNullOrEmpty(item.Security) || !Global.SsSecuritiesInSingbox.Contains(item.Security)) if (string.IsNullOrEmpty(item.Security) || !Global.SsSecuritiesInSingbox.Contains(item.Security))
{
errors.Add(string.Format(ResUI.InvalidProperty, "Security")); errors.Add(string.Format(ResUI.InvalidProperty, "Security"));
}
break; break;
} }

View file

@ -173,13 +173,19 @@ public class ProfileGroupItemManager
public static bool HasCycle(string? indexId, HashSet<string> visited, HashSet<string> stack) public static bool HasCycle(string? indexId, HashSet<string> visited, HashSet<string> stack)
{ {
if (indexId.IsNullOrEmpty()) if (indexId.IsNullOrEmpty())
{
return false; return false;
}
if (stack.Contains(indexId)) if (stack.Contains(indexId))
{
return true; return true;
}
if (visited.Contains(indexId)) if (visited.Contains(indexId))
{
return false; return false;
}
visited.Add(indexId); visited.Add(indexId);
stack.Add(indexId); stack.Add(indexId);
@ -289,7 +295,9 @@ public class ProfileGroupItemManager
{ {
var childNode = await AppManager.Instance.GetProfileItem(childId); var childNode = await AppManager.Instance.GetProfileItem(childId);
if (childNode == null) if (childNode == null)
{
continue; continue;
}
if (!childNode.IsComplex()) if (!childNode.IsComplex())
{ {

View file

@ -69,30 +69,49 @@ public class ProfileItem : ReactiveObject
public bool IsValid() public bool IsValid()
{ {
if (IsComplex()) if (IsComplex())
{
return true; return true;
}
if (Address.IsNullOrEmpty() || Port is <= 0 or >= 65536) if (Address.IsNullOrEmpty() || Port is <= 0 or >= 65536)
{
return false; return false;
}
switch (ConfigType) switch (ConfigType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
if (Id.IsNullOrEmpty() || !Utils.IsGuidByParse(Id)) if (Id.IsNullOrEmpty() || !Utils.IsGuidByParse(Id))
{
return false; return false;
}
break; break;
case EConfigType.VLESS: case EConfigType.VLESS:
if (Id.IsNullOrEmpty() || (!Utils.IsGuidByParse(Id) && Id.Length > 30)) if (Id.IsNullOrEmpty() || (!Utils.IsGuidByParse(Id) && Id.Length > 30))
{
return false; return false;
}
if (!Global.Flows.Contains(Flow)) if (!Global.Flows.Contains(Flow))
{
return false; return false;
}
break; break;
case EConfigType.Shadowsocks: case EConfigType.Shadowsocks:
if (Id.IsNullOrEmpty()) if (Id.IsNullOrEmpty())
{
return false; return false;
}
if (string.IsNullOrEmpty(Security) || !Global.SsSecuritiesInSingbox.Contains(Security)) if (string.IsNullOrEmpty(Security) || !Global.SsSecuritiesInSingbox.Contains(Security))
{
return false; return false;
}
break; break;
} }

View file

@ -202,7 +202,9 @@ public partial class CoreConfigSingboxService
var routing = await ConfigHandler.GetDefaultRouting(_config); var routing = await ConfigHandler.GetDefaultRouting(_config);
if (routing == null) if (routing == null)
{
return 0; return 0;
}
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? []; var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? [];
var expectedIPCidr = new List<string>(); var expectedIPCidr = new List<string>();

View file

@ -679,7 +679,10 @@ public partial class CoreConfigSingboxService
{ {
var node = nodes[i]; var node = nodes[i];
if (node == null) if (node == null)
{
continue; continue;
}
if (node.ConfigType.IsGroupType()) if (node.ConfigType.IsGroupType())
{ {
var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId); var (childProfiles, profileGroupItem) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);

View file

@ -250,7 +250,9 @@ public partial class CoreConfigSingboxService
foreach (var it in item.Domain) foreach (var it in item.Domain)
{ {
if (ParseV2Domain(it, rule1)) if (ParseV2Domain(it, rule1))
{
countDomain++; countDomain++;
}
} }
if (countDomain > 0) if (countDomain > 0)
{ {
@ -265,7 +267,9 @@ public partial class CoreConfigSingboxService
foreach (var it in item.Ip) foreach (var it in item.Ip)
{ {
if (ParseV2Address(it, rule2)) if (ParseV2Address(it, rule2))
{
countIp++; countIp++;
}
} }
if (countIp > 0) if (countIp > 0)
{ {

View file

@ -7,7 +7,9 @@ public partial class CoreConfigSingboxService
static void AddRuleSets(List<string> ruleSets, List<string>? rule_set) static void AddRuleSets(List<string> ruleSets, List<string>? rule_set)
{ {
if (rule_set != null) if (rule_set != null)
{
ruleSets.AddRange(rule_set); ruleSets.AddRange(rule_set);
}
} }
var geosite = "geosite"; var geosite = "geosite";
var geoip = "geoip"; var geoip = "geoip";

View file

@ -137,7 +137,9 @@ public partial class CoreConfigV2rayService(Config config)
foreach (var rule in rules) foreach (var rule in rules)
{ {
if (rule.outboundTag == null) if (rule.outboundTag == null)
{
continue; continue;
}
if (balancerTagSet.Contains(rule.outboundTag)) if (balancerTagSet.Contains(rule.outboundTag))
{ {

View file

@ -11,7 +11,9 @@ public partial class CoreConfigV2rayService
// Case 1: exact match already exists -> nothing to do // Case 1: exact match already exists -> nothing to do
if (subjectSelectors.Any(baseTagName.StartsWith)) if (subjectSelectors.Any(baseTagName.StartsWith))
{
return await Task.FromResult(0); return await Task.FromResult(0);
}
// Case 2: prefix match exists -> reuse it and move to the first position // Case 2: prefix match exists -> reuse it and move to the first position
var matched = subjectSelectors.FirstOrDefault(s => s.StartsWith(baseTagName)); var matched = subjectSelectors.FirstOrDefault(s => s.StartsWith(baseTagName));

View file

@ -189,7 +189,10 @@ public partial class CoreConfigV2rayService
foreach (var domain in item.Domain) foreach (var domain in item.Domain)
{ {
if (domain.StartsWith('#')) if (domain.StartsWith('#'))
{
continue; continue;
}
var normalizedDomain = domain.Replace(Global.RoutingRuleComma, ","); var normalizedDomain = domain.Replace(Global.RoutingRuleComma, ",");
if (item.OutboundTag == Global.DirectTag) if (item.OutboundTag == Global.DirectTag)
@ -368,7 +371,10 @@ public partial class CoreConfigV2rayService
foreach (var host in systemHosts) foreach (var host in systemHosts)
{ {
if (normalHost1[host.Key] != null) if (normalHost1[host.Key] != null)
{
continue; continue;
}
normalHost1[host.Key] = host.Value; normalHost1[host.Key] = host.Value;
} }
} }

View file

@ -803,7 +803,10 @@ public partial class CoreConfigV2rayService
{ {
var node = nodes[i]; var node = nodes[i];
if (node == null) if (node == null)
{
continue; continue;
}
if (node.ConfigType.IsGroupType()) if (node.ConfigType.IsGroupType())
{ {
var (childProfiles, _) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId); var (childProfiles, _) = await ProfileGroupItemManager.GetChildProfileItems(node.IndexId);

View file

@ -21,7 +21,7 @@ public class SpeedtestService(Config config, Func<SpeedTestResult, Task> updateF
{ {
if (_lstExitLoop.Count > 0) if (_lstExitLoop.Count > 0)
{ {
UpdateFunc("", ResUI.SpeedtestingStop); _ = UpdateFunc("", ResUI.SpeedtestingStop);
_lstExitLoop.Clear(); _lstExitLoop.Clear();
} }

View file

@ -209,6 +209,7 @@ public class CheckUpdateViewModel : MyReactiveObject
_ = UpdateFinishedResult(blReload); _ = UpdateFinishedResult(blReload);
return Disposable.Empty; return Disposable.Empty;
}); });
await Task.CompletedTask;
} }
public async Task UpdateFinishedResult(bool blReload) public async Task UpdateFinishedResult(bool blReload)
@ -321,6 +322,7 @@ public class CheckUpdateViewModel : MyReactiveObject
_ = UpdateViewResult(model); _ = UpdateViewResult(model);
return Disposable.Empty; return Disposable.Empty;
}); });
await Task.CompletedTask;
} }
public async Task UpdateViewResult(CheckUpdateModel model) public async Task UpdateViewResult(CheckUpdateModel model)
@ -331,5 +333,6 @@ public class CheckUpdateViewModel : MyReactiveObject
return; return;
} }
found.Remarks = model.Remarks; found.Remarks = model.Remarks;
await Task.CompletedTask;
} }
} }

View file

@ -96,6 +96,7 @@ public class ClashConnectionsViewModel : MyReactiveObject
} }
ConnectionItems.AddRange(lstModel); ConnectionItems.AddRange(lstModel);
await Task.CompletedTask;
} }
public async Task ClashConnectionClose(bool all) public async Task ClashConnectionClose(bool all)

View file

@ -245,6 +245,7 @@ public class ClashProxiesViewModel : MyReactiveObject
{ {
SelectedGroup = new(); SelectedGroup = new();
} }
await Task.CompletedTask;
} }
private void RefreshProxyDetails(bool c) private void RefreshProxyDetails(bool c)
@ -391,6 +392,7 @@ public class ClashProxiesViewModel : MyReactiveObject
_ = ProxiesDelayTestResult(model); _ = ProxiesDelayTestResult(model);
return Disposable.Empty; return Disposable.Empty;
}); });
await Task.CompletedTask;
}); });
await Task.CompletedTask; await Task.CompletedTask;
} }
@ -419,6 +421,7 @@ public class ClashProxiesViewModel : MyReactiveObject
detail.Delay = _delayTimeout; detail.Delay = _delayTimeout;
detail.DelayName = string.Empty; detail.DelayName = string.Empty;
} }
await Task.CompletedTask;
} }
#endregion proxy function #endregion proxy function

View file

@ -66,10 +66,14 @@ public class FullConfigTemplateViewModel : MyReactiveObject
private async Task SaveSettingAsync() private async Task SaveSettingAsync()
{ {
if (!await SaveXrayConfigAsync()) if (!await SaveXrayConfigAsync())
{
return; return;
}
if (!await SaveSingboxConfigAsync()) if (!await SaveSingboxConfigAsync())
{
return; return;
}
NoticeManager.Instance.Enqueue(ResUI.OperationSuccess); NoticeManager.Instance.Enqueue(ResUI.OperationSuccess);
_ = _updateView?.Invoke(EViewAction.CloseWindow, null); _ = _updateView?.Invoke(EViewAction.CloseWindow, null);

View file

@ -78,55 +78,55 @@ public class MainWindowViewModel : MyReactiveObject
//servers //servers
AddVmessServerCmd = ReactiveCommand.CreateFromTask(async () => AddVmessServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.VMess); await AddServerAsync(EConfigType.VMess);
}); });
AddVlessServerCmd = ReactiveCommand.CreateFromTask(async () => AddVlessServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.VLESS); await AddServerAsync(EConfigType.VLESS);
}); });
AddShadowsocksServerCmd = ReactiveCommand.CreateFromTask(async () => AddShadowsocksServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.Shadowsocks); await AddServerAsync(EConfigType.Shadowsocks);
}); });
AddSocksServerCmd = ReactiveCommand.CreateFromTask(async () => AddSocksServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.SOCKS); await AddServerAsync(EConfigType.SOCKS);
}); });
AddHttpServerCmd = ReactiveCommand.CreateFromTask(async () => AddHttpServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.HTTP); await AddServerAsync(EConfigType.HTTP);
}); });
AddTrojanServerCmd = ReactiveCommand.CreateFromTask(async () => AddTrojanServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.Trojan); await AddServerAsync(EConfigType.Trojan);
}); });
AddHysteria2ServerCmd = ReactiveCommand.CreateFromTask(async () => AddHysteria2ServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.Hysteria2); await AddServerAsync(EConfigType.Hysteria2);
}); });
AddTuicServerCmd = ReactiveCommand.CreateFromTask(async () => AddTuicServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.TUIC); await AddServerAsync(EConfigType.TUIC);
}); });
AddWireguardServerCmd = ReactiveCommand.CreateFromTask(async () => AddWireguardServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.WireGuard); await AddServerAsync(EConfigType.WireGuard);
}); });
AddAnytlsServerCmd = ReactiveCommand.CreateFromTask(async () => AddAnytlsServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.Anytls); await AddServerAsync(EConfigType.Anytls);
}); });
AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () => AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.Custom); await AddServerAsync(EConfigType.Custom);
}); });
AddPolicyGroupServerCmd = ReactiveCommand.CreateFromTask(async () => AddPolicyGroupServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.PolicyGroup); await AddServerAsync(EConfigType.PolicyGroup);
}); });
AddProxyChainServerCmd = ReactiveCommand.CreateFromTask(async () => AddProxyChainServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await AddServerAsync(true, EConfigType.ProxyChain); await AddServerAsync(EConfigType.ProxyChain);
}); });
AddServerViaClipboardCmd = ReactiveCommand.CreateFromTask(async () => AddServerViaClipboardCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
@ -283,6 +283,7 @@ public class MainWindowViewModel : MyReactiveObject
{ {
NoticeManager.Instance.Enqueue(msg); NoticeManager.Instance.Enqueue(msg);
} }
await Task.CompletedTask;
} }
private async Task UpdateTaskHandler(bool success, string msg) private async Task UpdateTaskHandler(bool success, string msg)
@ -310,6 +311,7 @@ public class MainWindowViewModel : MyReactiveObject
return; return;
} }
AppEvents.DispatcherStatisticsRequested.Publish(update); AppEvents.DispatcherStatisticsRequested.Publish(update);
await Task.CompletedTask;
} }
#endregion Actions #endregion Actions
@ -332,7 +334,7 @@ public class MainWindowViewModel : MyReactiveObject
#region Add Servers #region Add Servers
public async Task AddServerAsync(bool blNew, EConfigType eConfigType) public async Task AddServerAsync(EConfigType eConfigType)
{ {
ProfileItem item = new() ProfileItem item = new()
{ {

View file

@ -110,7 +110,7 @@ public class ProfilesViewModel : MyReactiveObject
//servers delete //servers delete
EditServerCmd = ReactiveCommand.CreateFromTask(async () => EditServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await EditServerAsync(EConfigType.Custom); await EditServerAsync();
}, canEditRemove); }, canEditRemove);
RemoveServerCmd = ReactiveCommand.CreateFromTask(async () => RemoveServerCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
@ -300,14 +300,14 @@ public class ProfilesViewModel : MyReactiveObject
if (result.Delay.IsNotEmpty()) if (result.Delay.IsNotEmpty())
{ {
int.TryParse(result.Delay, out var temp); item.Delay = result.Delay.ToInt();
item.Delay = temp;
item.DelayVal = result.Delay ?? string.Empty; item.DelayVal = result.Delay ?? string.Empty;
} }
if (result.Speed.IsNotEmpty()) if (result.Speed.IsNotEmpty())
{ {
item.SpeedVal = result.Speed ?? string.Empty; item.SpeedVal = result.Speed ?? string.Empty;
} }
await Task.CompletedTask;
} }
public async Task UpdateStatistics(ServerSpeedItem update) public async Task UpdateStatistics(ServerSpeedItem update)
@ -333,6 +333,7 @@ public class ProfilesViewModel : MyReactiveObject
catch catch
{ {
} }
await Task.CompletedTask;
} }
#endregion Actions #endregion Actions
@ -487,7 +488,7 @@ public class ProfilesViewModel : MyReactiveObject
return lstSelected; return lstSelected;
} }
public async Task EditServerAsync(EConfigType eConfigType) public async Task EditServerAsync()
{ {
if (string.IsNullOrEmpty(SelectedProfile?.IndexId)) if (string.IsNullOrEmpty(SelectedProfile?.IndexId))
{ {
@ -499,7 +500,7 @@ public class ProfilesViewModel : MyReactiveObject
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectServer); NoticeManager.Instance.Enqueue(ResUI.PleaseSelectServer);
return; return;
} }
eConfigType = item.ConfigType; var eConfigType = item.ConfigType;
bool? ret = false; bool? ret = false;
if (eConfigType == EConfigType.Custom) if (eConfigType == EConfigType.Custom)
@ -753,6 +754,7 @@ public class ProfilesViewModel : MyReactiveObject
_ = SetSpeedTestResult(result); _ = SetSpeedTestResult(result);
return Disposable.Empty; return Disposable.Empty;
}); });
await Task.CompletedTask;
}); });
_speedtestService?.RunLoop(actionType, lstSelected); _speedtestService?.RunLoop(actionType, lstSelected);
} }

View file

@ -120,7 +120,7 @@ public class StatusBarViewModel : MyReactiveObject
this.WhenAnyValue( this.WhenAnyValue(
x => x.SelectedServer, x => x.SelectedServer,
y => y != null && !y.Text.IsNullOrEmpty()) y => y != null && !y.Text.IsNullOrEmpty())
.Subscribe(c => ServerSelectedChanged(c)); .Subscribe(ServerSelectedChanged);
SystemProxySelected = (int)_config.SystemProxyItem.SysProxyType; SystemProxySelected = (int)_config.SystemProxyItem.SysProxyType;
this.WhenAnyValue( this.WhenAnyValue(
@ -367,11 +367,13 @@ public class StatusBarViewModel : MyReactiveObject
_ = TestServerAvailabilityResult(msg); _ = TestServerAvailabilityResult(msg);
return Disposable.Empty; return Disposable.Empty;
}); });
await Task.CompletedTask;
} }
public async Task TestServerAvailabilityResult(string msg) public async Task TestServerAvailabilityResult(string msg)
{ {
RunningInfoDisplay = msg; RunningInfoDisplay = msg;
await Task.CompletedTask;
} }
#region System proxy and Routings #region System proxy and Routings
@ -384,7 +386,7 @@ public class StatusBarViewModel : MyReactiveObject
} }
_config.SystemProxyItem.SysProxyType = type; _config.SystemProxyItem.SysProxyType = type;
await ChangeSystemProxyAsync(type, true); await ChangeSystemProxyAsync(type, true);
NoticeManager.Instance.SendMessageEx($"{ResUI.TipChangeSystemProxy} - {_config.SystemProxyItem.SysProxyType.ToString()}"); NoticeManager.Instance.SendMessageEx($"{ResUI.TipChangeSystemProxy} - {_config.SystemProxyItem.SysProxyType}");
SystemProxySelected = (int)_config.SystemProxyItem.SysProxyType; SystemProxySelected = (int)_config.SystemProxyItem.SysProxyType;
await ConfigHandler.SaveConfig(_config); await ConfigHandler.SaveConfig(_config);
@ -561,6 +563,7 @@ public class StatusBarViewModel : MyReactiveObject
catch catch
{ {
} }
await Task.CompletedTask;
} }
#endregion UI #endregion UI

View file

@ -28,7 +28,10 @@ internal class AvaUtils
{ {
var clipboard = TopLevel.GetTopLevel(visual)?.Clipboard; var clipboard = TopLevel.GetTopLevel(visual)?.Clipboard;
if (clipboard == null) if (clipboard == null)
{
return; return;
}
await clipboard.SetTextAsync(strData); await clipboard.SetTextAsync(strData);
} }
catch catch

View file

@ -6,7 +6,7 @@ public class DelayColorConverter : IValueConverter
{ {
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{ {
_ = int.TryParse(value?.ToString(), out var delay); var delay = value.ToString().ToInt();
return delay switch return delay switch
{ {

View file

@ -95,7 +95,9 @@ public class ThemeSettingViewModel : MyReactiveObject
{ {
double size = CurrentFontSize; double size = CurrentFontSize;
if (size < Global.MinFontSize) if (size < Global.MinFontSize)
{
return; return;
}
Style style = new(x => Selectors.Or( Style style = new(x => Selectors.Or(
x.OfType<Button>(), x.OfType<Button>(),

View file

@ -95,7 +95,9 @@ public partial class AddGroupServerWindow : WindowBase<AddGroupServerViewModel>
private void AddGroupServerWindow_KeyDown(object? sender, KeyEventArgs e) private void AddGroupServerWindow_KeyDown(object? sender, KeyEventArgs e)
{ {
if (!lstChild.IsKeyboardFocusWithin) if (!lstChild.IsKeyboardFocusWithin)
{
return; return;
}
if ((e.KeyModifiers & (KeyModifiers.Control | KeyModifiers.Meta)) != 0) if ((e.KeyModifiers & (KeyModifiers.Control | KeyModifiers.Meta)) != 0)
{ {

View file

@ -22,8 +22,8 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
_manager = new WindowNotificationManager(TopLevel.GetTopLevel(this)) { MaxItems = 3, Position = NotificationPosition.TopRight }; _manager = new WindowNotificationManager(TopLevel.GetTopLevel(this)) { MaxItems = 3, Position = NotificationPosition.TopRight };
KeyDown += MainWindow_KeyDown; KeyDown += MainWindow_KeyDown;
menuSettingsSetUWP.Click += menuSettingsSetUWP_Click; menuSettingsSetUWP.Click += MenuSettingsSetUWP_Click;
menuPromotion.Click += menuPromotion_Click; menuPromotion.Click += MenuPromotion_Click;
menuCheckUpdate.Click += MenuCheckUpdate_Click; menuCheckUpdate.Click += MenuCheckUpdate_Click;
menuBackupAndRestore.Click += MenuBackupAndRestore_Click; menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
menuClose.Click += MenuClose_Click; menuClose.Click += MenuClose_Click;
@ -188,6 +188,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
private async Task DelegateSnackMsg(string content) private async Task DelegateSnackMsg(string content)
{ {
_manager?.Show(new Notification(null, content, NotificationType.Information)); _manager?.Show(new Notification(null, content, NotificationType.Information));
await Task.CompletedTask;
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
@ -196,17 +197,26 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
{ {
case EViewAction.AddServerWindow: case EViewAction.AddServerWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return await new AddServerWindow((ProfileItem)obj).ShowDialog<bool>(this); return await new AddServerWindow((ProfileItem)obj).ShowDialog<bool>(this);
case EViewAction.AddServer2Window: case EViewAction.AddServer2Window:
if (obj is null) if (obj is null)
{
return false; return false;
}
return await new AddServer2Window((ProfileItem)obj).ShowDialog<bool>(this); return await new AddServer2Window((ProfileItem)obj).ShowDialog<bool>(this);
case EViewAction.AddGroupServerWindow: case EViewAction.AddGroupServerWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return await new AddGroupServerWindow((ProfileItem)obj).ShowDialog<bool>(this); return await new AddGroupServerWindow((ProfileItem)obj).ShowDialog<bool>(this);
case EViewAction.DNSSettingWindow: case EViewAction.DNSSettingWindow:
@ -308,12 +318,12 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
} }
} }
private void menuPromotion_Click(object? sender, RoutedEventArgs e) private void MenuPromotion_Click(object? sender, RoutedEventArgs e)
{ {
ProcUtils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}"); ProcUtils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
} }
private void menuSettingsSetUWP_Click(object? sender, RoutedEventArgs e) private void MenuSettingsSetUWP_Click(object? sender, RoutedEventArgs e)
{ {
ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe")); ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
} }
@ -478,8 +488,8 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
{ {
var coreInfo = CoreInfoManager.Instance.GetCoreInfo(); var coreInfo = CoreInfoManager.Instance.GetCoreInfo();
foreach (var it in coreInfo foreach (var it in coreInfo
.Where(t => t.CoreType != ECoreType.v2fly .Where(t => t.CoreType is not ECoreType.v2fly
&& t.CoreType != ECoreType.hysteria)) and not ECoreType.hysteria))
{ {
var item = new MenuItem() var item = new MenuItem()
{ {

View file

@ -30,7 +30,9 @@ public partial class MsgView : ReactiveUserControl<MsgViewModel>
{ {
case EViewAction.DispatcherShowMsg: case EViewAction.DispatcherShowMsg:
if (obj is null) if (obj is null)
{
return false; return false;
}
Dispatcher.UIThread.Post(() => ShowMsg(obj), Dispatcher.UIThread.Post(() => ShowMsg(obj),
DispatcherPriority.ApplicationIdle); DispatcherPriority.ApplicationIdle);

View file

@ -124,7 +124,10 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
{ {
case EViewAction.SetClipboardData: case EViewAction.SetClipboardData:
if (obj is null) if (obj is null)
{
return false; return false;
}
await AvaUtils.SetClipboardData(this, (string)obj); await AvaUtils.SetClipboardData(this, (string)obj);
break; break;
@ -141,7 +144,10 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
case EViewAction.SaveFileDialog: case EViewAction.SaveFileDialog:
if (obj is null) if (obj is null)
{
return false; return false;
}
var fileName = await UI.SaveFileDialog(_window, ""); var fileName = await UI.SaveFileDialog(_window, "");
if (fileName.IsNullOrEmpty()) if (fileName.IsNullOrEmpty())
{ {
@ -152,28 +158,43 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
case EViewAction.AddServerWindow: case EViewAction.AddServerWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return await new AddServerWindow((ProfileItem)obj).ShowDialog<bool>(_window); return await new AddServerWindow((ProfileItem)obj).ShowDialog<bool>(_window);
case EViewAction.AddServer2Window: case EViewAction.AddServer2Window:
if (obj is null) if (obj is null)
{
return false; return false;
}
return await new AddServer2Window((ProfileItem)obj).ShowDialog<bool>(_window); return await new AddServer2Window((ProfileItem)obj).ShowDialog<bool>(_window);
case EViewAction.AddGroupServerWindow: case EViewAction.AddGroupServerWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return await new AddGroupServerWindow((ProfileItem)obj).ShowDialog<bool>(_window); return await new AddGroupServerWindow((ProfileItem)obj).ShowDialog<bool>(_window);
case EViewAction.ShareServer: case EViewAction.ShareServer:
if (obj is null) if (obj is null)
{
return false; return false;
}
await ShareServer((string)obj); await ShareServer((string)obj);
break; break;
case EViewAction.SubEditWindow: case EViewAction.SubEditWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return await new SubEditWindow((SubItem)obj).ShowDialog<bool>(_window); return await new SubEditWindow((SubItem)obj).ShowDialog<bool>(_window);
case EViewAction.DispatcherRefreshServersBiz: case EViewAction.DispatcherRefreshServersBiz:
@ -215,14 +236,17 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
{ {
var source = e.Source as Border; var source = e.Source as Border;
if (source?.Name == "HeaderBackground") if (source?.Name == "HeaderBackground")
{
return; return;
}
if (_config.UiItem.DoubleClick2Activate) if (_config.UiItem.DoubleClick2Activate)
{ {
ViewModel?.SetDefaultServer(); ViewModel?.SetDefaultServer();
} }
else else
{ {
ViewModel?.EditServerAsync(EConfigType.Custom); ViewModel?.EditServerAsync();
} }
} }
@ -263,7 +287,7 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
break; break;
case Key.D: case Key.D:
ViewModel?.EditServerAsync(EConfigType.Custom); ViewModel?.EditServerAsync();
break; break;
case Key.F: case Key.F:

View file

@ -83,7 +83,10 @@ public partial class RoutingRuleSettingWindow : WindowBase<RoutingRuleSettingVie
case EViewAction.RoutingRuleDetailsWindow: case EViewAction.RoutingRuleDetailsWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return await new RoutingRuleDetailsWindow((RulesItem)obj).ShowDialog<bool>(this); return await new RoutingRuleDetailsWindow((RulesItem)obj).ShowDialog<bool>(this);
case EViewAction.ImportRulesFromFile: case EViewAction.ImportRulesFromFile:

View file

@ -60,7 +60,10 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
case EViewAction.RoutingRuleSettingWindow: case EViewAction.RoutingRuleSettingWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return await new RoutingRuleSettingWindow((RoutingItem)obj).ShowDialog<bool>(this); return await new RoutingRuleSettingWindow((RoutingItem)obj).ShowDialog<bool>(this);
} }
return await Task.FromResult(true); return await Task.FromResult(true);

View file

@ -56,7 +56,10 @@ public partial class StatusBarView : ReactiveUserControl<StatusBarViewModel>
case EViewAction.SetClipboardData: case EViewAction.SetClipboardData:
if (obj is null) if (obj is null)
{
return false; return false;
}
await AvaUtils.SetClipboardData(this, (string)obj); await AvaUtils.SetClipboardData(this, (string)obj);
break; break;

View file

@ -49,14 +49,20 @@ public partial class SubSettingWindow : WindowBase<SubSettingViewModel>
case EViewAction.SubEditWindow: case EViewAction.SubEditWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
var window = new SubEditWindow((SubItem)obj); var window = new SubEditWindow((SubItem)obj);
await window.ShowDialog(this); await window.ShowDialog(this);
break; break;
case EViewAction.ShareSub: case EViewAction.ShareSub:
if (obj is null) if (obj is null)
{
return false; return false;
}
await ShareSub((string)obj); await ShareSub((string)obj);
break; break;
} }

View file

@ -76,7 +76,7 @@ internal static class WindowsUtils
{ {
using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"); using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
var obj = key?.GetValue("AppsUseLightTheme"); var obj = key?.GetValue("AppsUseLightTheme");
int.TryParse(obj?.ToString(), out var value); var value = obj?.ToString().ToInt();
return value == 0; return value == 0;
} }

View file

@ -6,14 +6,14 @@ public class DelayColorConverter : IValueConverter
{ {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{ {
int.TryParse(value.ToString(), out var delay); var delay = value.ToString().ToInt();
if (delay <= 0) return delay switch
return new SolidColorBrush(Colors.Red); {
if (delay <= 500) <= 0 => new SolidColorBrush(Colors.Red),
return new SolidColorBrush(Colors.Green); <= 500 => new SolidColorBrush(Colors.Green),
else _ => new SolidColorBrush(Colors.IndianRed)
return new SolidColorBrush(Colors.IndianRed); };
} }
public object? ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) public object? ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

View file

@ -138,7 +138,9 @@ public class ThemeSettingViewModel : MyReactiveObject
{ {
double size = (long)CurrentFontSize; double size = (long)CurrentFontSize;
if (size < Global.MinFontSize) if (size < Global.MinFontSize)
{
return; return;
}
Application.Current.Resources["StdFontSize"] = size; Application.Current.Resources["StdFontSize"] = size;
Application.Current.Resources["StdFontSize1"] = size + 1; Application.Current.Resources["StdFontSize1"] = size + 1;

View file

@ -78,7 +78,10 @@ public partial class AddGroupServerWindow
private void AddGroupServerWindow_PreviewKeyDown(object sender, KeyEventArgs e) private void AddGroupServerWindow_PreviewKeyDown(object sender, KeyEventArgs e)
{ {
if (!lstChild.IsKeyboardFocusWithin) if (!lstChild.IsKeyboardFocusWithin)
{
return; return;
}
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{ {
if (e.Key == Key.A) if (e.Key == Key.A)

View file

@ -21,9 +21,9 @@ public partial class MainWindow
App.Current.SessionEnding += Current_SessionEnding; App.Current.SessionEnding += Current_SessionEnding;
Closing += MainWindow_Closing; Closing += MainWindow_Closing;
PreviewKeyDown += MainWindow_PreviewKeyDown; PreviewKeyDown += MainWindow_PreviewKeyDown;
menuSettingsSetUWP.Click += menuSettingsSetUWP_Click; menuSettingsSetUWP.Click += MenuSettingsSetUWP_Click;
menuPromotion.Click += menuPromotion_Click; menuPromotion.Click += MenuPromotion_Click;
menuClose.Click += menuClose_Click; menuClose.Click += MenuClose_Click;
menuCheckUpdate.Click += MenuCheckUpdate_Click; menuCheckUpdate.Click += MenuCheckUpdate_Click;
menuBackupAndRestore.Click += MenuBackupAndRestore_Click; menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
@ -178,6 +178,7 @@ public partial class MainWindow
private async Task DelegateSnackMsg(string content) private async Task DelegateSnackMsg(string content)
{ {
MainSnackbar.MessageQueue?.Enqueue(content); MainSnackbar.MessageQueue?.Enqueue(content);
await Task.CompletedTask;
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
@ -186,17 +187,26 @@ public partial class MainWindow
{ {
case EViewAction.AddServerWindow: case EViewAction.AddServerWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return new AddServerWindow((ProfileItem)obj).ShowDialog() ?? false; return new AddServerWindow((ProfileItem)obj).ShowDialog() ?? false;
case EViewAction.AddServer2Window: case EViewAction.AddServer2Window:
if (obj is null) if (obj is null)
{
return false; return false;
}
return new AddServer2Window((ProfileItem)obj).ShowDialog() ?? false; return new AddServer2Window((ProfileItem)obj).ShowDialog() ?? false;
case EViewAction.AddGroupServerWindow: case EViewAction.AddGroupServerWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return new AddGroupServerWindow((ProfileItem)obj).ShowDialog() ?? false; return new AddGroupServerWindow((ProfileItem)obj).ShowDialog() ?? false;
case EViewAction.DNSSettingWindow: case EViewAction.DNSSettingWindow:
@ -297,18 +307,18 @@ public partial class MainWindow
} }
} }
private void menuClose_Click(object sender, RoutedEventArgs e) private void MenuClose_Click(object sender, RoutedEventArgs e)
{ {
StorageUI(); StorageUI();
ShowHideWindow(false); ShowHideWindow(false);
} }
private void menuPromotion_Click(object sender, RoutedEventArgs e) private void MenuPromotion_Click(object sender, RoutedEventArgs e)
{ {
ProcUtils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}"); ProcUtils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
} }
private void menuSettingsSetUWP_Click(object sender, RoutedEventArgs e) private void MenuSettingsSetUWP_Click(object sender, RoutedEventArgs e)
{ {
ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe")); ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
} }
@ -429,8 +439,8 @@ public partial class MainWindow
{ {
var coreInfo = CoreInfoManager.Instance.GetCoreInfo(); var coreInfo = CoreInfoManager.Instance.GetCoreInfo();
foreach (var it in coreInfo foreach (var it in coreInfo
.Where(t => t.CoreType != ECoreType.v2fly .Where(t => t.CoreType is not ECoreType.v2fly
&& t.CoreType != ECoreType.hysteria)) and not ECoreType.hysteria))
{ {
var item = new MenuItem() var item = new MenuItem()
{ {

View file

@ -30,7 +30,10 @@ public partial class MsgView
{ {
case EViewAction.DispatcherShowMsg: case EViewAction.DispatcherShowMsg:
if (obj is null) if (obj is null)
{
return false; return false;
}
Application.Current?.Dispatcher.Invoke(() => Application.Current?.Dispatcher.Invoke(() =>
{ {
ShowMsg(obj); ShowMsg(obj);

View file

@ -109,7 +109,10 @@ public partial class ProfilesView
{ {
case EViewAction.SetClipboardData: case EViewAction.SetClipboardData:
if (obj is null) if (obj is null)
{
return false; return false;
}
WindowsUtils.SetClipboardData((string)obj); WindowsUtils.SetClipboardData((string)obj);
break; break;
@ -126,7 +129,10 @@ public partial class ProfilesView
case EViewAction.SaveFileDialog: case EViewAction.SaveFileDialog:
if (obj is null) if (obj is null)
{
return false; return false;
}
if (UI.SaveFileDialog(out var fileName, "Config|*.json") != true) if (UI.SaveFileDialog(out var fileName, "Config|*.json") != true)
{ {
return false; return false;
@ -136,28 +142,43 @@ public partial class ProfilesView
case EViewAction.AddServerWindow: case EViewAction.AddServerWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return new AddServerWindow((ProfileItem)obj).ShowDialog() ?? false; return new AddServerWindow((ProfileItem)obj).ShowDialog() ?? false;
case EViewAction.AddServer2Window: case EViewAction.AddServer2Window:
if (obj is null) if (obj is null)
{
return false; return false;
}
return new AddServer2Window((ProfileItem)obj).ShowDialog() ?? false; return new AddServer2Window((ProfileItem)obj).ShowDialog() ?? false;
case EViewAction.AddGroupServerWindow: case EViewAction.AddGroupServerWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return new AddGroupServerWindow((ProfileItem)obj).ShowDialog() ?? false; return new AddGroupServerWindow((ProfileItem)obj).ShowDialog() ?? false;
case EViewAction.ShareServer: case EViewAction.ShareServer:
if (obj is null) if (obj is null)
{
return false; return false;
}
ShareServer((string)obj); ShareServer((string)obj);
break; break;
case EViewAction.SubEditWindow: case EViewAction.SubEditWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return new SubEditWindow((SubItem)obj).ShowDialog() ?? false; return new SubEditWindow((SubItem)obj).ShowDialog() ?? false;
case EViewAction.DispatcherRefreshServersBiz: case EViewAction.DispatcherRefreshServersBiz:
@ -209,7 +230,7 @@ public partial class ProfilesView
} }
else else
{ {
ViewModel?.EditServerAsync(EConfigType.Custom); ViewModel?.EditServerAsync();
} }
} }
@ -245,7 +266,7 @@ public partial class ProfilesView
break; break;
case Key.D: case Key.D:
ViewModel?.EditServerAsync(EConfigType.Custom); ViewModel?.EditServerAsync();
break; break;
case Key.F: case Key.F:
@ -424,15 +445,22 @@ public partial class ProfilesView
{ {
// Get the dragged Item // Get the dragged Item
if (sender is not DataGrid listView) if (sender is not DataGrid listView)
{
return; return;
}
var listViewItem = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource); var listViewItem = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource);
if (listViewItem == null) if (listViewItem == null)
{
return; // Abort return; // Abort
// Find the data behind the ListViewItem }
// Find the data behind the ListViewItem
var item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem); var item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
if (item == null) if (item == null)
{
return; // Abort return; // Abort
// Initialize the drag & drop operation }
// Initialize the drag & drop operation
startIndex = lstProfiles.SelectedIndex; startIndex = lstProfiles.SelectedIndex;
DataObject dragData = new(formatData, item); DataObject dragData = new(formatData, item);
DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Copy | DragDropEffects.Move); DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Copy | DragDropEffects.Move);
@ -453,7 +481,10 @@ public partial class ProfilesView
{ {
// Get the drop Item destination // Get the drop Item destination
if (sender is not DataGrid listView) if (sender is not DataGrid listView)
{
return; return;
}
var listViewItem = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource); var listViewItem = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource);
if (listViewItem == null) if (listViewItem == null)
{ {
@ -464,7 +495,9 @@ public partial class ProfilesView
// Find the data behind the Item // Find the data behind the Item
var item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem); var item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
if (item == null) if (item == null)
{
return; return;
}
// Move item into observable collection // Move item into observable collection
// (this will be automatically reflected to lstView.ItemsSource) // (this will be automatically reflected to lstView.ItemsSource)
e.Effects = DragDropEffects.Move; e.Effects = DragDropEffects.Move;

View file

@ -79,7 +79,10 @@ public partial class RoutingRuleSettingWindow
case EViewAction.RoutingRuleDetailsWindow: case EViewAction.RoutingRuleDetailsWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return new RoutingRuleDetailsWindow((RulesItem)obj).ShowDialog() ?? false; return new RoutingRuleDetailsWindow((RulesItem)obj).ShowDialog() ?? false;
case EViewAction.ImportRulesFromFile: case EViewAction.ImportRulesFromFile:
@ -93,7 +96,10 @@ public partial class RoutingRuleSettingWindow
case EViewAction.SetClipboardData: case EViewAction.SetClipboardData:
if (obj is null) if (obj is null)
{
return false; return false;
}
WindowsUtils.SetClipboardData((string)obj); WindowsUtils.SetClipboardData((string)obj);
break; break;
@ -117,7 +123,10 @@ public partial class RoutingRuleSettingWindow
private void RoutingRuleSettingWindow_PreviewKeyDown(object sender, KeyEventArgs e) private void RoutingRuleSettingWindow_PreviewKeyDown(object sender, KeyEventArgs e)
{ {
if (!lstRules.IsKeyboardFocusWithin) if (!lstRules.IsKeyboardFocusWithin)
{
return; return;
}
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{ {
if (e.Key == Key.A) if (e.Key == Key.A)

View file

@ -57,7 +57,10 @@ public partial class RoutingSettingWindow
case EViewAction.RoutingRuleSettingWindow: case EViewAction.RoutingRuleSettingWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return new RoutingRuleSettingWindow((RoutingItem)obj).ShowDialog() ?? false; return new RoutingRuleSettingWindow((RoutingItem)obj).ShowDialog() ?? false;
} }
return await Task.FromResult(true); return await Task.FromResult(true);

View file

@ -80,7 +80,10 @@ public partial class StatusBarView
case EViewAction.SetClipboardData: case EViewAction.SetClipboardData:
if (obj is null) if (obj is null)
{
return false; return false;
}
WindowsUtils.SetClipboardData((string)obj); WindowsUtils.SetClipboardData((string)obj);
break; break;
} }

View file

@ -46,12 +46,18 @@ public partial class SubSettingWindow
case EViewAction.SubEditWindow: case EViewAction.SubEditWindow:
if (obj is null) if (obj is null)
{
return false; return false;
}
return new SubEditWindow((SubItem)obj).ShowDialog() ?? false; return new SubEditWindow((SubItem)obj).ShowDialog() ?? false;
case EViewAction.ShareSub: case EViewAction.ShareSub:
if (obj is null) if (obj is null)
{
return false; return false;
}
ShareSub((string)obj); ShareSub((string)obj);
break; break;
} }