Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1e6898290 | ||
|
|
8597332b21 | ||
|
|
7cc42ae249 | ||
|
|
e054d4487d | ||
|
|
6ef36f521d | ||
|
|
a02a122dd1 | ||
|
|
701138617c | ||
|
|
d0e2cc9442 | ||
|
|
d561f10edc | ||
|
|
2df412476a | ||
|
|
e6011cfede | ||
|
|
bcf43e2928 |
@@ -1,7 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>7.10.4</Version>
|
<Version>7.10.5</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
<PackageVersion Include="Avalonia.Desktop" Version="11.2.5" />
|
<PackageVersion Include="Avalonia.Desktop" Version="11.2.5" />
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.2.5" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.2.5" />
|
||||||
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.2.5" />
|
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.2.5" />
|
||||||
<PackageVersion Include="CliWrap" Version="3.8.1" />
|
<PackageVersion Include="CliWrap" Version="3.8.2" />
|
||||||
<PackageVersion Include="Downloader" Version="3.3.3" />
|
<PackageVersion Include="Downloader" Version="3.3.4" />
|
||||||
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.0" />
|
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.0" />
|
||||||
<PackageVersion Include="MaterialDesignThemes" Version="5.2.1" />
|
<PackageVersion Include="MaterialDesignThemes" Version="5.2.1" />
|
||||||
<PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" />
|
<PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" />
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.5" />
|
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.5" />
|
||||||
<PackageVersion Include="Splat.NLog" Version="15.3.1" />
|
<PackageVersion Include="Splat.NLog" Version="15.3.1" />
|
||||||
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
|
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
|
||||||
<PackageVersion Include="TaskScheduler" Version="2.12.0" />
|
<PackageVersion Include="TaskScheduler" Version="2.12.1" />
|
||||||
<PackageVersion Include="WebDav.Client" Version="2.8.0" />
|
<PackageVersion Include="WebDav.Client" Version="2.8.0" />
|
||||||
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
|
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
|
||||||
<PackageVersion Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
<PackageVersion Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
||||||
|
|||||||
@@ -224,6 +224,13 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static string GetMd5(string str)
|
public static string GetMd5(string str)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(str))
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var byteOld = Encoding.UTF8.GetBytes(str);
|
var byteOld = Encoding.UTF8.GetBytes(str);
|
||||||
var byteNew = MD5.HashData(byteOld);
|
var byteNew = MD5.HashData(byteOld);
|
||||||
@@ -235,6 +242,38 @@ namespace ServiceLib.Common
|
|||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, ex);
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetFileHash(string filePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(filePath))
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var md5 = MD5.Create();
|
||||||
|
using var stream = File.OpenRead(filePath);
|
||||||
|
var hash = md5.ComputeHash(stream);
|
||||||
|
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, ex);
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// idn to idc
|
/// idn to idc
|
||||||
@@ -564,13 +603,20 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var basePath = GetBaseDirectory();
|
||||||
//When this file exists, it is equivalent to having no permission to read and write
|
//When this file exists, it is equivalent to having no permission to read and write
|
||||||
if (File.Exists(Path.Combine(GetBaseDirectory(), "NotStoreConfigHere.txt")))
|
if (File.Exists(Path.Combine(basePath, "NotStoreConfigHere.txt")))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tempPath = Path.Combine(GetBaseDirectory(), "guiTemps");
|
//Check if it is installed by Windows WinGet
|
||||||
|
if (IsWindows() && basePath.Contains("Users") && basePath.Contains("WinGet"))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempPath = Path.Combine(basePath, "guiTemps");
|
||||||
if (!Directory.Exists(tempPath))
|
if (!Directory.Exists(tempPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(tempPath);
|
Directory.CreateDirectory(tempPath);
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ namespace ServiceLib.Handler
|
|||||||
private Dictionary<string, ProxiesItem>? _proxies;
|
private Dictionary<string, ProxiesItem>? _proxies;
|
||||||
public Dictionary<string, object> ProfileContent { get; set; }
|
public Dictionary<string, object> ProfileContent { get; set; }
|
||||||
|
|
||||||
public async Task<Tuple<ClashProxies, ClashProviders>?> GetClashProxiesAsync(Config config)
|
public async Task<Tuple<ClashProxies, ClashProviders>?> GetClashProxiesAsync()
|
||||||
{
|
{
|
||||||
for (var i = 0; i < 5; i++)
|
for (var i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
var url = $"{GetApiUrl()}/proxies";
|
var url = $"{GetApiUrl()}/proxies";
|
||||||
var result = await HttpClientHelper.Instance.TryGetAsync(url);
|
var result = await HttpClientHelper.Instance.TryGetAsync(url);
|
||||||
@@ -41,34 +41,26 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
if (blAll)
|
if (blAll)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
if (_proxies != null)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
await Task.Delay(5000);
|
|
||||||
}
|
|
||||||
if (_proxies == null)
|
if (_proxies == null)
|
||||||
{
|
{
|
||||||
return;
|
await GetClashProxiesAsync();
|
||||||
}
|
}
|
||||||
lstProxy = new List<ClashProxyModel>();
|
lstProxy = new List<ClashProxyModel>();
|
||||||
foreach (var kv in _proxies)
|
foreach (var kv in _proxies ?? [])
|
||||||
{
|
{
|
||||||
if (Global.notAllowTestType.Contains(kv.Value.type.ToLower()))
|
if (Global.notAllowTestType.Contains(kv.Value.type?.ToLower()))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
lstProxy.Add(new ClashProxyModel()
|
lstProxy.Add(new ClashProxyModel()
|
||||||
{
|
{
|
||||||
Name = kv.Value.name,
|
Name = kv.Value.name,
|
||||||
Type = kv.Value.type.ToLower(),
|
Type = kv.Value.type?.ToLower(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lstProxy == null)
|
if (lstProxy is not { Count: > 0 })
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -157,7 +149,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ClashConnections?> GetClashConnectionsAsync(Config config)
|
public async Task<ClashConnections?> GetClashConnectionsAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -871,13 +871,19 @@ namespace ServiceLib.Handler
|
|||||||
public static async Task<Tuple<int, int>> DedupServerList(Config config, string subId)
|
public static async Task<Tuple<int, int>> DedupServerList(Config config, string subId)
|
||||||
{
|
{
|
||||||
var lstProfile = await AppHandler.Instance.ProfileItems(subId);
|
var lstProfile = await AppHandler.Instance.ProfileItems(subId);
|
||||||
|
if (lstProfile == null)
|
||||||
|
{
|
||||||
|
return new Tuple<int, int>(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
List<ProfileItem> lstKeep = new();
|
List<ProfileItem> lstKeep = new();
|
||||||
List<ProfileItem> lstRemove = new();
|
List<ProfileItem> lstRemove = new();
|
||||||
if (!config.GuiItem.KeepOlderDedupl)
|
if (!config.GuiItem.KeepOlderDedupl)
|
||||||
|
{
|
||||||
lstProfile.Reverse();
|
lstProfile.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (ProfileItem item in lstProfile)
|
foreach (var item in lstProfile)
|
||||||
{
|
{
|
||||||
if (!lstKeep.Exists(i => CompareProfileItem(i, item, false)))
|
if (!lstKeep.Exists(i => CompareProfileItem(i, item, false)))
|
||||||
{
|
{
|
||||||
@@ -944,7 +950,7 @@ namespace ServiceLib.Handler
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool CompareProfileItem(ProfileItem o, ProfileItem n, bool remarks)
|
private static bool CompareProfileItem(ProfileItem? o, ProfileItem? n, bool remarks)
|
||||||
{
|
{
|
||||||
if (o == null || n == null)
|
if (o == null || n == null)
|
||||||
{
|
{
|
||||||
@@ -952,22 +958,27 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
|
|
||||||
return o.ConfigType == n.ConfigType
|
return o.ConfigType == n.ConfigType
|
||||||
&& o.Address == n.Address
|
&& AreEqual(o.Address, n.Address)
|
||||||
&& o.Port == n.Port
|
&& o.Port == n.Port
|
||||||
&& o.Id == n.Id
|
&& AreEqual(o.Id, n.Id)
|
||||||
&& o.Security == n.Security
|
&& AreEqual(o.Security, n.Security)
|
||||||
&& o.Network == n.Network
|
&& AreEqual(o.Network, n.Network)
|
||||||
&& o.HeaderType == n.HeaderType
|
&& AreEqual(o.HeaderType, n.HeaderType)
|
||||||
&& o.RequestHost == n.RequestHost
|
&& AreEqual(o.RequestHost, n.RequestHost)
|
||||||
&& o.Path == n.Path
|
&& AreEqual(o.Path, n.Path)
|
||||||
&& (o.ConfigType == EConfigType.Trojan || o.StreamSecurity == n.StreamSecurity)
|
&& (o.ConfigType == EConfigType.Trojan || o.StreamSecurity == n.StreamSecurity)
|
||||||
&& o.Flow == n.Flow
|
&& AreEqual(o.Flow, n.Flow)
|
||||||
&& o.Sni == n.Sni
|
&& AreEqual(o.Sni, n.Sni)
|
||||||
&& o.Alpn == n.Alpn
|
&& AreEqual(o.Alpn, n.Alpn)
|
||||||
&& o.Fingerprint == n.Fingerprint
|
&& AreEqual(o.Fingerprint, n.Fingerprint)
|
||||||
&& o.PublicKey == n.PublicKey
|
&& AreEqual(o.PublicKey, n.PublicKey)
|
||||||
&& o.ShortId == n.ShortId
|
&& AreEqual(o.ShortId, n.ShortId)
|
||||||
&& (!remarks || o.Remarks == n.Remarks);
|
&& (!remarks || o.Remarks == n.Remarks);
|
||||||
|
|
||||||
|
static bool AreEqual(string? a, string? b)
|
||||||
|
{
|
||||||
|
return string.Equals(a, b) || (string.IsNullOrEmpty(a) && string.IsNullOrEmpty(b));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<int> RemoveProfileItem(Config config, string indexId)
|
private static async Task<int> RemoveProfileItem(Config config, string indexId)
|
||||||
@@ -1005,8 +1016,7 @@ namespace ServiceLib.Handler
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileName = configPath;
|
if (!File.Exists(configPath))
|
||||||
if (!File.Exists(fileName))
|
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,40 +5,35 @@ namespace ServiceLib.Handler.Fmt
|
|||||||
public static List<ProfileItem>? ResolveFullArray(string strData, string? subRemarks)
|
public static List<ProfileItem>? ResolveFullArray(string strData, string? subRemarks)
|
||||||
{
|
{
|
||||||
var configObjects = JsonUtils.Deserialize<object[]>(strData);
|
var configObjects = JsonUtils.Deserialize<object[]>(strData);
|
||||||
if (configObjects != null && configObjects.Length > 0)
|
if (configObjects is not { Length: > 0 })
|
||||||
{
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
List<ProfileItem> lstResult = [];
|
List<ProfileItem> lstResult = [];
|
||||||
foreach (var configObject in configObjects)
|
foreach (var configObject in configObjects)
|
||||||
{
|
{
|
||||||
var objectString = JsonUtils.Serialize(configObject);
|
var objectString = JsonUtils.Serialize(configObject);
|
||||||
var singboxCon = JsonUtils.Deserialize<SingboxConfig>(objectString);
|
var profileIt = ResolveFull(objectString, subRemarks);
|
||||||
if (singboxCon?.inbounds?.Count > 0
|
if (profileIt != null)
|
||||||
&& singboxCon.outbounds?.Count > 0
|
|
||||||
&& singboxCon.route != null)
|
|
||||||
{
|
{
|
||||||
var fileName = WriteAllText(objectString);
|
|
||||||
|
|
||||||
var profileIt = new ProfileItem
|
|
||||||
{
|
|
||||||
CoreType = ECoreType.sing_box,
|
|
||||||
Address = fileName,
|
|
||||||
Remarks = subRemarks ?? "singbox_custom",
|
|
||||||
};
|
|
||||||
lstResult.Add(profileIt);
|
lstResult.Add(profileIt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lstResult;
|
return lstResult;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
|
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
|
||||||
{
|
{
|
||||||
var singboxConfig = JsonUtils.Deserialize<SingboxConfig>(strData);
|
var config = JsonUtils.ParseJson(strData);
|
||||||
if (singboxConfig?.inbounds?.Count > 0
|
if (config?["inbounds"] == null
|
||||||
&& singboxConfig.outbounds?.Count > 0
|
|| config["outbounds"] == null
|
||||||
&& singboxConfig.route != null)
|
|| config["route"] == null
|
||||||
|
|| config["dns"] == null)
|
||||||
{
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var fileName = WriteAllText(strData);
|
var fileName = WriteAllText(strData);
|
||||||
var profileItem = new ProfileItem
|
var profileItem = new ProfileItem
|
||||||
{
|
{
|
||||||
@@ -49,7 +44,5 @@ namespace ServiceLib.Handler.Fmt
|
|||||||
|
|
||||||
return profileItem;
|
return profileItem;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,52 +5,45 @@ namespace ServiceLib.Handler.Fmt
|
|||||||
public static List<ProfileItem>? ResolveFullArray(string strData, string? subRemarks)
|
public static List<ProfileItem>? ResolveFullArray(string strData, string? subRemarks)
|
||||||
{
|
{
|
||||||
var configObjects = JsonUtils.Deserialize<object[]>(strData);
|
var configObjects = JsonUtils.Deserialize<object[]>(strData);
|
||||||
if (configObjects != null && configObjects.Length > 0)
|
if (configObjects is not { Length: > 0 })
|
||||||
{
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
List<ProfileItem> lstResult = [];
|
List<ProfileItem> lstResult = [];
|
||||||
foreach (var configObject in configObjects)
|
foreach (var configObject in configObjects)
|
||||||
{
|
{
|
||||||
var objectString = JsonUtils.Serialize(configObject);
|
var objectString = JsonUtils.Serialize(configObject);
|
||||||
var v2rayCon = JsonUtils.Deserialize<V2rayConfig>(objectString);
|
var profileIt = ResolveFull(objectString, subRemarks);
|
||||||
if (v2rayCon?.inbounds?.Count > 0
|
if (profileIt != null)
|
||||||
&& v2rayCon.outbounds?.Count > 0
|
|
||||||
&& v2rayCon.routing != null)
|
|
||||||
{
|
{
|
||||||
var fileName = WriteAllText(objectString);
|
|
||||||
|
|
||||||
var profileIt = new ProfileItem
|
|
||||||
{
|
|
||||||
CoreType = ECoreType.Xray,
|
|
||||||
Address = fileName,
|
|
||||||
Remarks = v2rayCon.remarks ?? subRemarks ?? "v2ray_custom",
|
|
||||||
};
|
|
||||||
lstResult.Add(profileIt);
|
lstResult.Add(profileIt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lstResult;
|
return lstResult;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
|
public static ProfileItem? ResolveFull(string strData, string? subRemarks)
|
||||||
{
|
{
|
||||||
var v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(strData);
|
var config = JsonUtils.ParseJson(strData);
|
||||||
if (v2rayConfig?.inbounds?.Count > 0
|
if (config?["inbounds"] == null
|
||||||
&& v2rayConfig.outbounds?.Count > 0
|
|| config["outbounds"] == null
|
||||||
&& v2rayConfig.routing != null)
|
|| config["routing"] == null)
|
||||||
{
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var fileName = WriteAllText(strData);
|
var fileName = WriteAllText(strData);
|
||||||
|
|
||||||
var profileItem = new ProfileItem
|
var profileItem = new ProfileItem
|
||||||
{
|
{
|
||||||
CoreType = ECoreType.Xray,
|
CoreType = ECoreType.Xray,
|
||||||
Address = fileName,
|
Address = fileName,
|
||||||
Remarks = v2rayConfig.remarks ?? subRemarks ?? "v2ray_custom"
|
Remarks = config?["remarks"]?.ToString() ?? subRemarks ?? "v2ray_custom"
|
||||||
};
|
};
|
||||||
|
|
||||||
return profileItem;
|
return profileItem;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,13 @@ namespace ServiceLib.Handler
|
|||||||
private static async Task InitText()
|
private static async Task InitText()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_configPath, "pac.txt");
|
var path = Path.Combine(_configPath, "pac.txt");
|
||||||
|
|
||||||
|
// Delete the old pac file
|
||||||
|
if (File.Exists(path) && Utils.GetFileHash(path).Equals("b590c07280f058ef05d5394aa2f927fe"))
|
||||||
|
{
|
||||||
|
File.Delete(path);
|
||||||
|
}
|
||||||
|
|
||||||
if (!File.Exists(path))
|
if (!File.Exists(path))
|
||||||
{
|
{
|
||||||
var pac = EmbedUtils.GetEmbedText(Global.PacFileName);
|
var pac = EmbedUtils.GetEmbedText(Global.PacFileName);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -80,13 +80,19 @@ set_kde_proxy() {
|
|||||||
|
|
||||||
# Detect the current desktop environment
|
# Detect the current desktop environment
|
||||||
detect_desktop_environment() {
|
detect_desktop_environment() {
|
||||||
if [ "$XDG_CURRENT_DESKTOP" == "GNOME" ] || [ "$XDG_CURRENT_DESKTOP" == "ubuntu:GNOME" ] || [ "$XDG_SESSION_DESKTOP" == "GNOME" ] || [ "$XDG_SESSION_DESKTOP" == "ubuntu:GNOME" ]; then
|
if [[ "$XDG_CURRENT_DESKTOP" == *"GNOME"* ]] || [[ "$XDG_SESSION_DESKTOP" == *"GNOME"* ]]; then
|
||||||
echo "gnome"
|
echo "gnome"
|
||||||
elif [ "$XDG_CURRENT_DESKTOP" == "KDE" ] || [ "$XDG_CURRENT_DESKTOP" == "plasma" ] || [ "$XDG_SESSION_DESKTOP" == "KDE" ] || [ "$XDG_SESSION_DESKTOP" == "plasma" ]; then
|
return
|
||||||
echo "kde"
|
|
||||||
else
|
|
||||||
echo "unsupported"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local KDE_ENVIRONMENTS=("KDE" "plasma")
|
||||||
|
for ENV in "${KDE_ENVIRONMENTS[@]}"; do
|
||||||
|
if [ "$XDG_CURRENT_DESKTOP" == "$ENV" ] || [ "$XDG_SESSION_DESKTOP" == "$ENV" ]; then
|
||||||
|
echo "kde"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "unsupported"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main script logic
|
# Main script logic
|
||||||
|
|||||||
@@ -182,12 +182,24 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
rule.balancerTag = balancer.tag;
|
rule.balancerTag = balancer.tag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (v2rayConfig.routing.domainStrategy == "IPIfNonMatch")
|
||||||
|
{
|
||||||
|
v2rayConfig.routing.rules.Add(new()
|
||||||
|
{
|
||||||
|
ip = ["0.0.0.0/0", "::/0"],
|
||||||
|
balancerTag = balancer.tag,
|
||||||
|
type = "field"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
v2rayConfig.routing.rules.Add(new()
|
v2rayConfig.routing.rules.Add(new()
|
||||||
{
|
{
|
||||||
network = "tcp,udp",
|
network = "tcp,udp",
|
||||||
balancerTag = balancer.tag,
|
balancerTag = balancer.tag,
|
||||||
type = "field"
|
type = "field"
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
ret.Data = JsonUtils.Serialize(v2rayConfig);
|
ret.Data = JsonUtils.Serialize(v2rayConfig);
|
||||||
@@ -582,7 +594,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
var it = JsonUtils.DeepCopy(rule);
|
var it = JsonUtils.DeepCopy(rule);
|
||||||
it.ip = null;
|
it.ip = null;
|
||||||
it.type = "field";
|
it.type = "field";
|
||||||
for (int k = it.domain.Count - 1; k >= 0; k--)
|
for (var k = it.domain.Count - 1; k >= 0; k--)
|
||||||
{
|
{
|
||||||
if (it.domain[k].StartsWith("#"))
|
if (it.domain[k].StartsWith("#"))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -74,6 +74,14 @@ namespace ServiceLib.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task CheckUpdate()
|
private async Task CheckUpdate()
|
||||||
|
{
|
||||||
|
await Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await CheckUpdateTask();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task CheckUpdateTask()
|
||||||
{
|
{
|
||||||
_lstUpdated.Clear();
|
_lstUpdated.Clear();
|
||||||
_lstUpdated = _checkUpdateModel.Where(x => x.IsSelected == true)
|
_lstUpdated = _checkUpdateModel.Where(x => x.IsSelected == true)
|
||||||
|
|||||||
@@ -53,12 +53,12 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task Init()
|
private async Task Init()
|
||||||
{
|
{
|
||||||
_ = DelayTestTask();
|
await DelayTestTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task GetClashConnections()
|
private async Task GetClashConnections()
|
||||||
{
|
{
|
||||||
var ret = await ClashApiHandler.Instance.GetClashConnectionsAsync(_config);
|
var ret = await ClashApiHandler.Instance.GetClashConnectionsAsync();
|
||||||
if (ret == null)
|
if (ret == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
private Dictionary<string, ProxiesItem>? _proxies;
|
private Dictionary<string, ProxiesItem>? _proxies;
|
||||||
private Dictionary<string, ProvidersItem>? _providers;
|
private Dictionary<string, ProvidersItem>? _providers;
|
||||||
private int _delayTimeout = 99999999;
|
private readonly int _delayTimeout = 99999999;
|
||||||
|
|
||||||
private IObservableCollection<ClashProxyModel> _proxyGroups = new ObservableCollectionExtended<ClashProxyModel>();
|
private IObservableCollection<ClashProxyModel> _proxyGroups = new ObservableCollectionExtended<ClashProxyModel>();
|
||||||
private IObservableCollection<ClashProxyModel> _proxyDetails = new ObservableCollectionExtended<ClashProxyModel>();
|
private IObservableCollection<ClashProxyModel> _proxyDetails = new ObservableCollectionExtended<ClashProxyModel>();
|
||||||
@@ -28,8 +28,8 @@ namespace ServiceLib.ViewModels
|
|||||||
public ClashProxyModel SelectedDetail { get; set; }
|
public ClashProxyModel SelectedDetail { get; set; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> ProxiesReloadCmd { get; }
|
public ReactiveCommand<Unit, Unit> ProxiesReloadCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ProxiesDelaytestCmd { get; }
|
public ReactiveCommand<Unit, Unit> ProxiesDelayTestCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ProxiesDelaytestPartCmd { get; }
|
public ReactiveCommand<Unit, Unit> ProxiesDelayTestPartCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ProxiesSelectActivityCmd { get; }
|
public ReactiveCommand<Unit, Unit> ProxiesSelectActivityCmd { get; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
@@ -50,12 +50,12 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
await ProxiesReload();
|
await ProxiesReload();
|
||||||
});
|
});
|
||||||
ProxiesDelaytestCmd = ReactiveCommand.CreateFromTask(async () =>
|
ProxiesDelayTestCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
await ProxiesDelayTest(true);
|
await ProxiesDelayTest(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
ProxiesDelaytestPartCmd = ReactiveCommand.CreateFromTask(async () =>
|
ProxiesDelayTestPartCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
await ProxiesDelayTest(false);
|
await ProxiesDelayTest(false);
|
||||||
});
|
});
|
||||||
@@ -78,7 +78,7 @@ namespace ServiceLib.ViewModels
|
|||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.RuleModeSelected,
|
x => x.RuleModeSelected,
|
||||||
y => y >= 0)
|
y => y >= 0)
|
||||||
.Subscribe(async c => await DoRulemodeSelected(c));
|
.Subscribe(async c => await DoRuleModeSelected(c));
|
||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.SortingSelected,
|
x => x.SortingSelected,
|
||||||
@@ -95,10 +95,10 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task Init()
|
private async Task Init()
|
||||||
{
|
{
|
||||||
_ = DelayTestTask();
|
await DelayTestTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DoRulemodeSelected(bool c)
|
private async Task DoRuleModeSelected(bool c)
|
||||||
{
|
{
|
||||||
if (!c)
|
if (!c)
|
||||||
{
|
{
|
||||||
@@ -158,7 +158,7 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task GetClashProxies(bool refreshUI)
|
private async Task GetClashProxies(bool refreshUI)
|
||||||
{
|
{
|
||||||
var ret = await ClashApiHandler.Instance.GetClashProxiesAsync(_config);
|
var ret = await ClashApiHandler.Instance.GetClashProxiesAsync();
|
||||||
if (ret?.Item1 == null || ret.Item2 == null)
|
if (ret?.Item1 == null || ret.Item2 == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -255,29 +255,23 @@ namespace ServiceLib.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
_proxies.TryGetValue(name, out var proxy);
|
_proxies.TryGetValue(name, out var proxy);
|
||||||
if (proxy == null || proxy.all == null)
|
if (proxy?.all == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var lstDetails = new List<ClashProxyModel>();
|
var lstDetails = new List<ClashProxyModel>();
|
||||||
foreach (var item in proxy.all)
|
foreach (var item in proxy.all)
|
||||||
{
|
{
|
||||||
var IsActive = item == proxy.now;
|
|
||||||
|
|
||||||
var proxy2 = TryGetProxy(item);
|
var proxy2 = TryGetProxy(item);
|
||||||
if (proxy2 == null)
|
if (proxy2 == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int delay = -1;
|
var delay = proxy2.history?.Count > 0 ? proxy2.history.Last().delay : -1;
|
||||||
if (proxy2.history.Count > 0)
|
|
||||||
{
|
|
||||||
delay = proxy2.history[proxy2.history.Count - 1].delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
lstDetails.Add(new ClashProxyModel()
|
lstDetails.Add(new ClashProxyModel()
|
||||||
{
|
{
|
||||||
IsActive = IsActive,
|
IsActive = item == proxy.now,
|
||||||
Name = item,
|
Name = item,
|
||||||
Type = proxy2.type,
|
Type = proxy2.type,
|
||||||
Delay = delay <= 0 ? _delayTimeout : delay,
|
Delay = delay <= 0 ? _delayTimeout : delay,
|
||||||
@@ -372,14 +366,9 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task ProxiesDelayTest(bool blAll = true)
|
private async Task ProxiesDelayTest(bool blAll = true)
|
||||||
{
|
{
|
||||||
ClashApiHandler.Instance.ClashProxiesDelayTest(blAll, _proxyDetails.ToList(), async (item, result) =>
|
ClashApiHandler.Instance.ClashProxiesDelayTest(blAll, _proxyDetails.ToList(), (item, result) =>
|
||||||
{
|
{
|
||||||
if (item == null)
|
if (item == null || result.IsNullOrEmpty())
|
||||||
{
|
|
||||||
await GetClashProxies(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (result.IsNullOrEmpty())
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -393,8 +382,11 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
//UpdateHandler(false, $"{item.name}={result}");
|
//UpdateHandler(false, $"{item.name}={result}");
|
||||||
var detail = _proxyDetails.FirstOrDefault(it => it.Name == result.IndexId);
|
var detail = _proxyDetails.FirstOrDefault(it => it.Name == result.IndexId);
|
||||||
if (detail != null)
|
if (detail == null)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var dicResult = JsonUtils.Deserialize<Dictionary<string, object>>(result.Delay);
|
var dicResult = JsonUtils.Deserialize<Dictionary<string, object>>(result.Delay);
|
||||||
if (dicResult != null && dicResult.TryGetValue("delay", out var value))
|
if (dicResult != null && dicResult.TryGetValue("delay", out var value))
|
||||||
{
|
{
|
||||||
@@ -413,7 +405,6 @@ namespace ServiceLib.ViewModels
|
|||||||
}
|
}
|
||||||
_proxyDetails.Replace(detail, JsonUtils.DeepCopy(detail));
|
_proxyDetails.Replace(detail, JsonUtils.DeepCopy(detail));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endregion proxy function
|
#endregion proxy function
|
||||||
|
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task<List<ProfileItem>?> GetProfileItems(bool latest)
|
private async Task<List<ProfileItem>?> GetProfileItems(bool latest)
|
||||||
{
|
{
|
||||||
var lstSelecteds = new List<ProfileItem>();
|
var lstSelected = new List<ProfileItem>();
|
||||||
if (SelectedProfiles == null || SelectedProfiles.Count <= 0)
|
if (SelectedProfiles == null || SelectedProfiles.Count <= 0)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -462,16 +462,16 @@ namespace ServiceLib.ViewModels
|
|||||||
var item = await AppHandler.Instance.GetProfileItem(profile.IndexId);
|
var item = await AppHandler.Instance.GetProfileItem(profile.IndexId);
|
||||||
if (item is not null)
|
if (item is not null)
|
||||||
{
|
{
|
||||||
lstSelecteds.Add(item);
|
lstSelected.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lstSelecteds = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(orderProfiles));
|
lstSelected = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(orderProfiles));
|
||||||
}
|
}
|
||||||
|
|
||||||
return lstSelecteds;
|
return lstSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task EditServerAsync(EConfigType eConfigType)
|
public async Task EditServerAsync(EConfigType eConfigType)
|
||||||
@@ -509,8 +509,8 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
public async Task RemoveServerAsync()
|
public async Task RemoveServerAsync()
|
||||||
{
|
{
|
||||||
var lstSelecteds = await GetProfileItems(true);
|
var lstSelected = await GetProfileItems(true);
|
||||||
if (lstSelecteds == null)
|
if (lstSelected == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -518,11 +518,11 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var exists = lstSelecteds.Exists(t => t.IndexId == _config.IndexId);
|
var exists = lstSelected.Exists(t => t.IndexId == _config.IndexId);
|
||||||
|
|
||||||
await ConfigHandler.RemoveServers(_config, lstSelecteds);
|
await ConfigHandler.RemoveServers(_config, lstSelected);
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
||||||
if (lstSelecteds.Count == _profileItems.Count)
|
if (lstSelected.Count == _profileItems.Count)
|
||||||
{
|
{
|
||||||
_profileItems.Clear();
|
_profileItems.Clear();
|
||||||
}
|
}
|
||||||
@@ -536,19 +536,22 @@ namespace ServiceLib.ViewModels
|
|||||||
private async Task RemoveDuplicateServer()
|
private async Task RemoveDuplicateServer()
|
||||||
{
|
{
|
||||||
var tuple = await ConfigHandler.DedupServerList(_config, _config.SubIndexId);
|
var tuple = await ConfigHandler.DedupServerList(_config, _config.SubIndexId);
|
||||||
|
if (tuple.Item1 > 0 || tuple.Item2 > 0)
|
||||||
|
{
|
||||||
RefreshServers();
|
RefreshServers();
|
||||||
Reload();
|
Reload();
|
||||||
|
}
|
||||||
NoticeHandler.Instance.Enqueue(string.Format(ResUI.RemoveDuplicateServerResult, tuple.Item1, tuple.Item2));
|
NoticeHandler.Instance.Enqueue(string.Format(ResUI.RemoveDuplicateServerResult, tuple.Item1, tuple.Item2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CopyServer()
|
private async Task CopyServer()
|
||||||
{
|
{
|
||||||
var lstSelecteds = await GetProfileItems(false);
|
var lstSelected = await GetProfileItems(false);
|
||||||
if (lstSelecteds == null)
|
if (lstSelected == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (await ConfigHandler.CopyServer(_config, lstSelecteds) == 0)
|
if (await ConfigHandler.CopyServer(_config, lstSelected) == 0)
|
||||||
{
|
{
|
||||||
RefreshServers();
|
RefreshServers();
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
||||||
@@ -564,7 +567,7 @@ namespace ServiceLib.ViewModels
|
|||||||
await SetDefaultServer(SelectedProfile.IndexId);
|
await SetDefaultServer(SelectedProfile.IndexId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SetDefaultServer(string indexId)
|
public async Task SetDefaultServer(string? indexId)
|
||||||
{
|
{
|
||||||
if (indexId.IsNullOrEmpty())
|
if (indexId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
@@ -594,11 +597,7 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (SelectedServer == null)
|
if (SelectedServer == null || SelectedServer.ID.IsNullOrEmpty())
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (SelectedServer.ID.IsNullOrEmpty())
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -624,13 +623,13 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task SetDefaultMultipleServer(ECoreType coreType)
|
private async Task SetDefaultMultipleServer(ECoreType coreType)
|
||||||
{
|
{
|
||||||
var lstSelecteds = await GetProfileItems(true);
|
var lstSelected = await GetProfileItems(true);
|
||||||
if (lstSelecteds == null)
|
if (lstSelected == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelecteds, coreType);
|
var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelected, coreType);
|
||||||
if (ret.Success != true)
|
if (ret.Success != true)
|
||||||
{
|
{
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
|
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
|
||||||
@@ -679,19 +678,18 @@ namespace ServiceLib.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lstSelecteds = await GetProfileItems(true);
|
var lstSelected = await GetProfileItems(true);
|
||||||
if (lstSelecteds == null)
|
if (lstSelected == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ConfigHandler.MoveToGroup(_config, lstSelecteds, SelectedMoveToGroup.Id);
|
await ConfigHandler.MoveToGroup(_config, lstSelected, SelectedMoveToGroup.Id);
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
||||||
|
|
||||||
RefreshServers();
|
RefreshServers();
|
||||||
SelectedMoveToGroup = null;
|
SelectedMoveToGroup = null;
|
||||||
SelectedMoveToGroup = new();
|
SelectedMoveToGroup = new();
|
||||||
//Reload();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task MoveServer(EMove eMove)
|
public async Task MoveServer(EMove eMove)
|
||||||
@@ -703,7 +701,7 @@ namespace ServiceLib.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = _lstProfile.IndexOf(item);
|
var index = _lstProfile.IndexOf(item);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -732,14 +730,14 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
SelectedProfiles = _profileItems;
|
SelectedProfiles = _profileItems;
|
||||||
}
|
}
|
||||||
var lstSelecteds = await GetProfileItems(false);
|
var lstSelected = await GetProfileItems(false);
|
||||||
if (lstSelecteds == null)
|
if (lstSelected == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_speedtestService ??= new SpeedtestService(_config, (SpeedTestResult result) => _updateView?.Invoke(EViewAction.DispatcherSpeedTest, result));
|
_speedtestService ??= new SpeedtestService(_config, (SpeedTestResult result) => _updateView?.Invoke(EViewAction.DispatcherSpeedTest, result));
|
||||||
_speedtestService?.RunLoop(actionType, lstSelecteds);
|
_speedtestService?.RunLoop(actionType, lstSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ServerSpeedtestStop()
|
public void ServerSpeedtestStop()
|
||||||
@@ -793,14 +791,14 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
public async Task Export2ShareUrlAsync(bool blEncode)
|
public async Task Export2ShareUrlAsync(bool blEncode)
|
||||||
{
|
{
|
||||||
var lstSelecteds = await GetProfileItems(true);
|
var lstSelected = await GetProfileItems(true);
|
||||||
if (lstSelecteds == null)
|
if (lstSelected == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
foreach (var it in lstSelecteds)
|
foreach (var it in lstSelected)
|
||||||
{
|
{
|
||||||
var url = FmtHandler.GetShareUri(it);
|
var url = FmtHandler.GetShareUri(it);
|
||||||
if (url.IsNullOrEmpty())
|
if (url.IsNullOrEmpty())
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ namespace v2rayN.Desktop.Views
|
|||||||
this.Bind(ViewModel, vm => vm.SelectedDetail, v => v.lstProxyDetails.SelectedItem).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedDetail, v => v.lstProxyDetails.SelectedItem).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.ProxiesReloadCmd, v => v.menuProxiesReload).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ProxiesReloadCmd, v => v.menuProxiesReload).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.ProxiesDelaytestCmd, v => v.menuProxiesDelaytest).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ProxiesDelayTestCmd, v => v.menuProxiesDelaytest).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.ProxiesDelaytestPartCmd, v => v.menuProxiesDelaytestPart).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ProxiesDelayTestPartCmd, v => v.menuProxiesDelaytestPart).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.ProxiesSelectActivityCmd, v => v.menuProxiesSelectActivity).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ProxiesSelectActivityCmd, v => v.menuProxiesSelectActivity).DisposeWith(disposables);
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.RuleModeSelected, v => v.cmbRulemode.SelectedIndex).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.RuleModeSelected, v => v.cmbRulemode.SelectedIndex).DisposeWith(disposables);
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ namespace v2rayN.Views
|
|||||||
this.Bind(ViewModel, vm => vm.SelectedDetail, v => v.lstProxyDetails.SelectedItem).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedDetail, v => v.lstProxyDetails.SelectedItem).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.ProxiesReloadCmd, v => v.menuProxiesReload).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ProxiesReloadCmd, v => v.menuProxiesReload).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.ProxiesDelaytestCmd, v => v.menuProxiesDelaytest).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ProxiesDelayTestCmd, v => v.menuProxiesDelaytest).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.ProxiesDelaytestPartCmd, v => v.menuProxiesDelaytestPart).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ProxiesDelayTestPartCmd, v => v.menuProxiesDelaytestPart).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.ProxiesSelectActivityCmd, v => v.menuProxiesSelectActivity).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ProxiesSelectActivityCmd, v => v.menuProxiesSelectActivity).DisposeWith(disposables);
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.RuleModeSelected, v => v.cmbRulemode.SelectedIndex).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.RuleModeSelected, v => v.cmbRulemode.SelectedIndex).DisposeWith(disposables);
|
||||||
|
|||||||
Reference in New Issue
Block a user