Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
838bd2c794 | ||
|
|
b2bbe432e0 | ||
|
|
b3d8042452 | ||
|
|
0c758a7fdc | ||
|
|
85cb1d1c92 | ||
|
|
2cd2e8894d | ||
|
|
abb58379b3 | ||
|
|
4f48e8b190 | ||
|
|
2b5cbb5e74 | ||
|
|
23dd140921 | ||
|
|
8c8d7bda64 | ||
|
|
a6e246948a | ||
|
|
c49ba735a0 | ||
|
|
1a33c598e8 | ||
|
|
a4bbdb49de | ||
|
|
cf3846fbfd | ||
|
|
d46943eedf | ||
|
|
3bc17bd50a | ||
|
|
48a159f4c8 | ||
|
|
3d1bcffdc5 | ||
|
|
45fa0f94d2 | ||
|
|
ed16b7de4a | ||
|
|
f2ec03c7ec | ||
|
|
11db87f1e6 | ||
|
|
a1feaf33e0 | ||
|
|
53a99e3f79 | ||
|
|
e7f04f55c2 | ||
|
|
6653ea12b7 | ||
|
|
a28cef5b98 |
@@ -13,7 +13,7 @@ Check [Release files introduction](https://github.com/2dust/v2rayN/wiki/Release-
|
|||||||
### Windows
|
### Windows
|
||||||
- Run `v2rayN.exe`
|
- Run `v2rayN.exe`
|
||||||
### Linux
|
### Linux
|
||||||
- `chmod +x v2rayN` Run `./v2rayN`
|
- `chmod +x v2rayN` Run `./v2rayN` under user permissions
|
||||||
```
|
```
|
||||||
Debian 9+
|
Debian 9+
|
||||||
Ubuntu 16.04+
|
Ubuntu 16.04+
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
using System.Linq.Expressions;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace ServiceLib.Common
|
|
||||||
{
|
|
||||||
public static class QueryableExtension
|
|
||||||
{
|
|
||||||
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName)
|
|
||||||
{
|
|
||||||
return _OrderBy<T>(query, propertyName, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName)
|
|
||||||
{
|
|
||||||
return _OrderBy<T>(query, propertyName, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IOrderedQueryable<T> _OrderBy<T>(IQueryable<T> query, string propertyName, bool isDesc)
|
|
||||||
{
|
|
||||||
var methodname = (isDesc) ? "OrderByDescendingInternal" : "OrderByInternal";
|
|
||||||
|
|
||||||
var memberProp = typeof(T).GetProperty(propertyName);
|
|
||||||
|
|
||||||
var method = typeof(QueryableExtension).GetMethod(methodname)
|
|
||||||
.MakeGenericMethod(typeof(T), memberProp.PropertyType);
|
|
||||||
|
|
||||||
return (IOrderedQueryable<T>)method.Invoke(null, new object[] { query, memberProp });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IOrderedQueryable<T> OrderByInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
|
|
||||||
{//public
|
|
||||||
return query.OrderBy(_GetLambda<T, TProp>(memberProperty));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IOrderedQueryable<T> OrderByDescendingInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
|
|
||||||
{//public
|
|
||||||
return query.OrderByDescending(_GetLambda<T, TProp>(memberProperty));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Expression<Func<T, TProp>> _GetLambda<T, TProp>(PropertyInfo memberProperty)
|
|
||||||
{
|
|
||||||
if (memberProperty.PropertyType != typeof(TProp)) throw new Exception();
|
|
||||||
|
|
||||||
var thisArg = Expression.Parameter(typeof(T));
|
|
||||||
var lambda = Expression.Lambda<Func<T, TProp>>(Expression.Property(thisArg, memberProperty), thisArg);
|
|
||||||
|
|
||||||
return lambda;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -529,15 +529,9 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (blFull)
|
return blFull
|
||||||
{
|
? $"{Global.AppName} - V{GetVersionInfo()} - {RuntimeInformation.ProcessArchitecture} - {StartupPath()}"
|
||||||
return
|
: $"{Global.AppName}/{GetVersionInfo()}";
|
||||||
$"{Global.AppName} - V{GetVersionInfo()} - {RuntimeInformation.ProcessArchitecture} - {File.GetLastWriteTime(GetExePath()):yyyy/MM/dd}";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $"{Global.AppName}/{GetVersionInfo()}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -677,6 +671,27 @@ namespace ServiceLib.Common
|
|||||||
|
|
||||||
#region TempPath
|
#region TempPath
|
||||||
|
|
||||||
|
public static bool HasWritePermission()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var tempPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "guiTemps");
|
||||||
|
if (!Directory.Exists(tempPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(tempPath);
|
||||||
|
}
|
||||||
|
var fileName = Path.Combine(tempPath, GetGuid());
|
||||||
|
File.Create(fileName).Close();
|
||||||
|
File.Delete(fileName);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static string GetPath(string fileName)
|
public static string GetPath(string fileName)
|
||||||
{
|
{
|
||||||
var startupPath = StartupPath();
|
var startupPath = StartupPath();
|
||||||
@@ -695,6 +710,11 @@ namespace ServiceLib.Common
|
|||||||
|
|
||||||
public static string StartupPath()
|
public static string StartupPath()
|
||||||
{
|
{
|
||||||
|
if (Utils.IsNonWindows() && Environment.GetEnvironmentVariable("V2RAYN_LOCAL_APPLICATION_DATA") == "1")
|
||||||
|
{
|
||||||
|
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "v2rayN");
|
||||||
|
}
|
||||||
|
|
||||||
return AppDomain.CurrentDomain.BaseDirectory;
|
return AppDomain.CurrentDomain.BaseDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -818,6 +838,8 @@ namespace ServiceLib.Common
|
|||||||
|
|
||||||
public static bool IsOSX() => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
|
public static bool IsOSX() => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
|
||||||
|
|
||||||
|
public static bool IsNonWindows() => !RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||||
|
|
||||||
public static string GetExeName(string name)
|
public static string GetExeName(string name)
|
||||||
{
|
{
|
||||||
return IsWindows() ? $"{name}.exe" : name;
|
return IsWindows() ? $"{name}.exe" : name;
|
||||||
@@ -852,6 +874,7 @@ namespace ServiceLib.Common
|
|||||||
public static async Task<string?> SetLinuxChmod(string? fileName)
|
public static async Task<string?> SetLinuxChmod(string? fileName)
|
||||||
{
|
{
|
||||||
if (fileName.IsNullOrEmpty()) return null;
|
if (fileName.IsNullOrEmpty()) return null;
|
||||||
|
//File.SetUnixFileMode(fileName, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
|
||||||
var arg = new List<string>() { "-c", $"chmod +x {fileName}" };
|
var arg = new List<string>() { "-c", $"chmod +x {fileName}" };
|
||||||
return await GetCliWrapOutput("/bin/bash", arg);
|
return await GetCliWrapOutput("/bin/bash", arg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
SendMsgView,
|
SendMsgView,
|
||||||
SendSnackMsg,
|
SendSnackMsg,
|
||||||
RefreshProfiles,
|
RefreshProfiles,
|
||||||
StopSpeedtest
|
StopSpeedtest,
|
||||||
|
AppExit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,8 +76,9 @@
|
|||||||
public const int MaxPort = 65536;
|
public const int MaxPort = 65536;
|
||||||
public const string DelayUnit = "";
|
public const string DelayUnit = "";
|
||||||
public const string SpeedUnit = "";
|
public const string SpeedUnit = "";
|
||||||
public const int MinFontSize = 10;
|
public const int MinFontSize = 8;
|
||||||
public const string RebootAs = "rebootas";
|
public const string RebootAs = "rebootas";
|
||||||
|
public const string AvaAssets = "avares://v2rayN/Assets/";
|
||||||
|
|
||||||
public static readonly List<string> IEProxyProtocols = new() {
|
public static readonly List<string> IEProxyProtocols = new() {
|
||||||
"{ip}:{http_port}",
|
"{ip}:{http_port}",
|
||||||
@@ -196,7 +197,7 @@
|
|||||||
public static readonly List<string> SingboxDomainStrategy4Out = new() { "ipv4_only", "prefer_ipv4", "prefer_ipv6", "ipv6_only", "" };
|
public static readonly List<string> SingboxDomainStrategy4Out = new() { "ipv4_only", "prefer_ipv4", "prefer_ipv6", "ipv6_only", "" };
|
||||||
public static readonly List<string> DomainDNSAddress = ["223.5.5.5", "223.6.6.6", "localhost"];
|
public static readonly List<string> DomainDNSAddress = ["223.5.5.5", "223.6.6.6", "localhost"];
|
||||||
public static readonly List<string> SingboxDomainDNSAddress = ["223.5.5.5", "223.6.6.6", "dhcp://auto"];
|
public static readonly List<string> SingboxDomainDNSAddress = ["223.5.5.5", "223.6.6.6", "dhcp://auto"];
|
||||||
public static readonly List<string> Languages = new() { "zh-Hans", "zh-Hant", "en", "fa-Ir", "ru" };
|
public static readonly List<string> Languages = new() { "zh-Hans", "zh-Hant", "en", "fa-Ir", "ru", "hu" };
|
||||||
public static readonly List<string> Alpns = new() { "h3", "h2", "http/1.1", "h3,h2", "h2,http/1.1", "h3,h2,http/1.1", "" };
|
public static readonly List<string> Alpns = new() { "h3", "h2", "http/1.1", "h3,h2", "h2,http/1.1", "h3,h2,http/1.1", "" };
|
||||||
public static readonly List<string> LogLevels = new() { "debug", "info", "warning", "error", "none" };
|
public static readonly List<string> LogLevels = new() { "debug", "info", "warning", "error", "none" };
|
||||||
public static readonly List<string> InboundTags = new() { "socks", "socks2" };
|
public static readonly List<string> InboundTags = new() { "socks", "socks2" };
|
||||||
|
|||||||
@@ -46,6 +46,11 @@
|
|||||||
|
|
||||||
public bool InitApp()
|
public bool InitApp()
|
||||||
{
|
{
|
||||||
|
if (Utils.IsNonWindows() && Utils.HasWritePermission() == false)
|
||||||
|
{
|
||||||
|
Environment.SetEnvironmentVariable("V2RAYN_LOCAL_APPLICATION_DATA", "1", EnvironmentVariableTarget.Process);
|
||||||
|
}
|
||||||
|
|
||||||
Logging.Setup();
|
Logging.Setup();
|
||||||
var config = ConfigHandler.LoadConfig();
|
var config = ConfigHandler.LoadConfig();
|
||||||
if (config == null)
|
if (config == null)
|
||||||
|
|||||||
@@ -766,69 +766,66 @@ namespace ServiceLib.Handler
|
|||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
Enum.TryParse(colName, true, out EServerColName name);
|
Enum.TryParse(colName, true, out EServerColName name);
|
||||||
var propertyName = string.Empty;
|
|
||||||
switch (name)
|
|
||||||
{
|
|
||||||
case EServerColName.ConfigType:
|
|
||||||
case EServerColName.Remarks:
|
|
||||||
case EServerColName.Address:
|
|
||||||
case EServerColName.Port:
|
|
||||||
case EServerColName.Network:
|
|
||||||
case EServerColName.StreamSecurity:
|
|
||||||
propertyName = name.ToString();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EServerColName.DelayVal:
|
|
||||||
propertyName = "Delay";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EServerColName.SpeedVal:
|
|
||||||
propertyName = "Speed";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EServerColName.SubRemarks:
|
|
||||||
propertyName = "Subid";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var items = lstProfile.AsQueryable();
|
|
||||||
|
|
||||||
if (asc)
|
if (asc)
|
||||||
{
|
{
|
||||||
lstProfile = items.OrderBy(propertyName).ToList();
|
lstProfile = name switch
|
||||||
|
{
|
||||||
|
EServerColName.ConfigType => lstProfile.OrderBy(t => t.ConfigType).ToList(),
|
||||||
|
EServerColName.Remarks => lstProfile.OrderBy(t => t.Remarks).ToList(),
|
||||||
|
EServerColName.Address => lstProfile.OrderBy(t => t.Address).ToList(),
|
||||||
|
EServerColName.Port => lstProfile.OrderBy(t => t.Port).ToList(),
|
||||||
|
EServerColName.Network => lstProfile.OrderBy(t => t.Network).ToList(),
|
||||||
|
EServerColName.StreamSecurity => lstProfile.OrderBy(t => t.StreamSecurity).ToList(),
|
||||||
|
EServerColName.DelayVal => lstProfile.OrderBy(t => t.Delay).ToList(),
|
||||||
|
EServerColName.SpeedVal => lstProfile.OrderBy(t => t.Speed).ToList(),
|
||||||
|
EServerColName.SubRemarks => lstProfile.OrderBy(t => t.Subid).ToList(),
|
||||||
|
_ => lstProfile
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lstProfile = items.OrderByDescending(propertyName).ToList();
|
lstProfile = name switch
|
||||||
|
{
|
||||||
|
EServerColName.ConfigType => lstProfile.OrderByDescending(t => t.ConfigType).ToList(),
|
||||||
|
EServerColName.Remarks => lstProfile.OrderByDescending(t => t.Remarks).ToList(),
|
||||||
|
EServerColName.Address => lstProfile.OrderByDescending(t => t.Address).ToList(),
|
||||||
|
EServerColName.Port => lstProfile.OrderByDescending(t => t.Port).ToList(),
|
||||||
|
EServerColName.Network => lstProfile.OrderByDescending(t => t.Network).ToList(),
|
||||||
|
EServerColName.StreamSecurity => lstProfile.OrderByDescending(t => t.StreamSecurity).ToList(),
|
||||||
|
EServerColName.DelayVal => lstProfile.OrderByDescending(t => t.Delay).ToList(),
|
||||||
|
EServerColName.SpeedVal => lstProfile.OrderByDescending(t => t.Speed).ToList(),
|
||||||
|
EServerColName.SubRemarks => lstProfile.OrderByDescending(t => t.Subid).ToList(),
|
||||||
|
_ => lstProfile
|
||||||
|
};
|
||||||
}
|
}
|
||||||
for (int i = 0; i < lstProfile.Count; i++)
|
|
||||||
|
for (var i = 0; i < lstProfile.Count; i++)
|
||||||
{
|
{
|
||||||
ProfileExHandler.Instance.SetSort(lstProfile[i].IndexId, (i + 1) * 10);
|
ProfileExHandler.Instance.SetSort(lstProfile[i].IndexId, (i + 1) * 10);
|
||||||
}
|
}
|
||||||
if (name == EServerColName.DelayVal)
|
switch (name)
|
||||||
{
|
{
|
||||||
var maxSort = lstProfile.Max(t => t.Sort) + 10;
|
case EServerColName.DelayVal:
|
||||||
foreach (var item in lstProfile)
|
|
||||||
{
|
|
||||||
if (item.Delay <= 0)
|
|
||||||
{
|
{
|
||||||
ProfileExHandler.Instance.SetSort(item.IndexId, maxSort);
|
var maxSort = lstProfile.Max(t => t.Sort) + 10;
|
||||||
|
foreach (var item in lstProfile.Where(item => item.Delay <= 0))
|
||||||
|
{
|
||||||
|
ProfileExHandler.Instance.SetSort(item.IndexId, maxSort);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case EServerColName.SpeedVal:
|
||||||
}
|
|
||||||
if (name == EServerColName.SpeedVal)
|
|
||||||
{
|
|
||||||
var maxSort = lstProfile.Max(t => t.Sort) + 10;
|
|
||||||
foreach (var item in lstProfile)
|
|
||||||
{
|
|
||||||
if (item.Speed <= 0)
|
|
||||||
{
|
{
|
||||||
ProfileExHandler.Instance.SetSort(item.IndexId, maxSort);
|
var maxSort = lstProfile.Max(t => t.Sort) + 10;
|
||||||
|
foreach (var item in lstProfile.Where(item => item.Speed <= 0))
|
||||||
|
{
|
||||||
|
ProfileExHandler.Instance.SetSort(item.IndexId, maxSort);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace ServiceLib.Handler
|
|||||||
Environment.SetEnvironmentVariable("V2RAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
Environment.SetEnvironmentVariable("V2RAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
||||||
Environment.SetEnvironmentVariable("XRAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
Environment.SetEnvironmentVariable("XRAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
||||||
|
|
||||||
if (Utils.IsLinux() || Utils.IsOSX())
|
if (Utils.IsNonWindows())
|
||||||
{
|
{
|
||||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
|
||||||
foreach (var it in coreInfo)
|
foreach (var it in coreInfo)
|
||||||
@@ -221,7 +221,7 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
return _config.TunModeItem.EnableTun
|
return _config.TunModeItem.EnableTun
|
||||||
&& eCoreType == ECoreType.sing_box
|
&& eCoreType == ECoreType.sing_box
|
||||||
&& (Utils.IsLinux() || Utils.IsOSX())
|
&& (Utils.IsNonWindows())
|
||||||
//&& _config.TunModeItem.LinuxSudoPwd.IsNotEmpty()
|
//&& _config.TunModeItem.LinuxSudoPwd.IsNotEmpty()
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
{
|
{
|
||||||
lstCmd.Add(new CmdItem()
|
lstCmd.Add(new CmdItem()
|
||||||
{
|
{
|
||||||
Cmd = "kwriteconfig5",
|
Cmd = GetKdeVersion(),
|
||||||
Arguments = ["--file", $"{configDir}/kioslaverc", "--group", "Proxy Settings", "--key", "ProxyType", "0"]
|
Arguments = ["--file", $"{configDir}/kioslaverc", "--group", "Proxy Settings", "--key", "ProxyType", "0"]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -88,12 +88,13 @@
|
|||||||
private static List<CmdItem> GetSetCmd4Kde(string type, string host, int port, string configDir)
|
private static List<CmdItem> GetSetCmd4Kde(string type, string host, int port, string configDir)
|
||||||
{
|
{
|
||||||
List<CmdItem> lstCmd = [];
|
List<CmdItem> lstCmd = [];
|
||||||
|
var cmd = GetKdeVersion();
|
||||||
|
|
||||||
if (type.IsNullOrEmpty())
|
if (type.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
lstCmd.Add(new()
|
lstCmd.Add(new()
|
||||||
{
|
{
|
||||||
Cmd = "kwriteconfig5",
|
Cmd = cmd,
|
||||||
Arguments = ["--file", $"{configDir}/kioslaverc", "--group", "Proxy Settings", "--key", "ProxyType", "1"]
|
Arguments = ["--file", $"{configDir}/kioslaverc", "--group", "Proxy Settings", "--key", "ProxyType", "1"]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -101,7 +102,7 @@
|
|||||||
{
|
{
|
||||||
lstCmd.Add(new()
|
lstCmd.Add(new()
|
||||||
{
|
{
|
||||||
Cmd = "kwriteconfig5",
|
Cmd = cmd,
|
||||||
Arguments = ["--file", $"{configDir}/kioslaverc", "--group", "Proxy Settings", "--key", "NoProxyFor", host]
|
Arguments = ["--file", $"{configDir}/kioslaverc", "--group", "Proxy Settings", "--key", "NoProxyFor", host]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -110,7 +111,7 @@
|
|||||||
var type2 = type.Equals("https") ? "http" : type;
|
var type2 = type.Equals("https") ? "http" : type;
|
||||||
lstCmd.Add(new CmdItem()
|
lstCmd.Add(new CmdItem()
|
||||||
{
|
{
|
||||||
Cmd = "kwriteconfig5",
|
Cmd = cmd,
|
||||||
Arguments = ["--file", $"{configDir}/kioslaverc", "--group", "Proxy Settings", "--key", $"{type}Proxy", $"{type2}://{host}:{port}"]
|
Arguments = ["--file", $"{configDir}/kioslaverc", "--group", "Proxy Settings", "--key", $"{type}Proxy", $"{type2}://{host}:{port}"]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -172,5 +173,14 @@
|
|||||||
|
|
||||||
return isKde;
|
return isKde;
|
||||||
}
|
}
|
||||||
|
private static string GetKdeVersion()
|
||||||
|
{
|
||||||
|
var ver = Environment.GetEnvironmentVariable("KDE_SESSION_VERSION") ?? "0";
|
||||||
|
return ver switch
|
||||||
|
{
|
||||||
|
"6" => "kwriteconfig6",
|
||||||
|
_ => "kwriteconfig5"
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,9 +16,9 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly List<string> LstTypes = ["setwebproxy", "setsecurewebproxy", "setsocksfirewallproxy"];
|
private static readonly List<string> LstTypes = ["setwebproxy", "setsecurewebproxy", "setsocksfirewallproxy"];
|
||||||
|
|
||||||
public static async Task SetProxy(string host, int port)
|
public static async Task SetProxy(string host, int port, string exceptions)
|
||||||
{
|
{
|
||||||
var lstCmd = GetSetCmds(host, port);
|
var lstCmd = GetSetCmds(host, port, exceptions);
|
||||||
await ExecCmd(lstCmd);
|
await ExecCmd(lstCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<CmdItem> GetSetCmds(string host, int port)
|
private static List<CmdItem> GetSetCmds(string host, int port, string exceptions)
|
||||||
{
|
{
|
||||||
List<CmdItem> lstCmd = [];
|
List<CmdItem> lstCmd = [];
|
||||||
foreach (var interf in LstInterface)
|
foreach (var interf in LstInterface)
|
||||||
@@ -52,7 +52,17 @@
|
|||||||
lstCmd.Add(new CmdItem()
|
lstCmd.Add(new CmdItem()
|
||||||
{
|
{
|
||||||
Cmd = "networksetup",
|
Cmd = "networksetup",
|
||||||
Arguments = [$"-{type}", interf, host, (type.Contains("socks") ? (port - 1) : port).ToString()]
|
Arguments = [$"-{type}", interf, host, port.ToString()]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (exceptions.IsNotEmpty())
|
||||||
|
{
|
||||||
|
List<string> args = [$"-setproxybypassdomains", interf];
|
||||||
|
args.AddRange(exceptions.Split(','));
|
||||||
|
lstCmd.Add(new CmdItem()
|
||||||
|
{
|
||||||
|
Cmd = "networksetup",
|
||||||
|
Arguments = args
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ESysProxyType.ForcedChange when Utils.IsOSX():
|
case ESysProxyType.ForcedChange when Utils.IsOSX():
|
||||||
await ProxySettingOSX.SetProxy(Global.Loopback, port);
|
await ProxySettingOSX.SetProxy(Global.Loopback, port, exceptions);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESysProxyType.ForcedClear when Utils.IsWindows():
|
case ESysProxyType.ForcedClear when Utils.IsWindows():
|
||||||
|
|||||||
@@ -324,7 +324,8 @@ namespace ServiceLib.Models
|
|||||||
|
|
||||||
public class WsSettings4Ray
|
public class WsSettings4Ray
|
||||||
{
|
{
|
||||||
public string path { get; set; }
|
public string? path { get; set; }
|
||||||
|
public string? host { get; set; }
|
||||||
|
|
||||||
public Headers4Ray headers { get; set; }
|
public Headers4Ray headers { get; set; }
|
||||||
}
|
}
|
||||||
@@ -349,21 +350,9 @@ namespace ServiceLib.Models
|
|||||||
public string? path { get; set; }
|
public string? path { get; set; }
|
||||||
public string? host { get; set; }
|
public string? host { get; set; }
|
||||||
public string? mode { get; set; }
|
public string? mode { get; set; }
|
||||||
public object? scMaxEachPostBytes { get; set; }
|
|
||||||
public object? scMaxConcurrentPosts { get; set; }
|
|
||||||
public object? scMinPostsIntervalMs { get; set; }
|
|
||||||
//public Xmux4Ray? xmux { get; set; }
|
|
||||||
public object? extra { get; set; }
|
public object? extra { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
//public class Xmux4Ray
|
|
||||||
//{
|
|
||||||
// public object? maxConcurrency { get; set; }
|
|
||||||
// public object? maxConnections { get; set; }
|
|
||||||
// public object? cMaxReuseTimes { get; set; }
|
|
||||||
// public object? cMaxLifetimeMs { get; set; }
|
|
||||||
//}
|
|
||||||
|
|
||||||
public class HttpSettings4Ray
|
public class HttpSettings4Ray
|
||||||
{
|
{
|
||||||
public string? path { get; set; }
|
public string? path { get; set; }
|
||||||
|
|||||||
@@ -1388,6 +1388,6 @@
|
|||||||
<value>تعداد در هر زمان برای دسته خودکار در طول تست سرعت (حداکثر 1000)</value>
|
<value>تعداد در هر زمان برای دسته خودکار در طول تست سرعت (حداکثر 1000)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsExceptionTip2" xml:space="preserve">
|
<data name="TbSettingsExceptionTip2" xml:space="preserve">
|
||||||
<value>Exception. Do not use proxy server for addresses,with a comma (,)</value>
|
<value>استثنا:از سرور پروکسی برای آدرس ها، با کاما (،) استفاده نکنید</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
1393
v2rayN/ServiceLib/Resx/ResUI.hu.resx
Normal file
1393
v2rayN/ServiceLib/Resx/ResUI.hu.resx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1382,7 +1382,7 @@
|
|||||||
<value>关闭窗口时隐藏至托盘</value>
|
<value>关闭窗口时隐藏至托盘</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsSpeedTestPageSize" xml:space="preserve">
|
<data name="TbSettingsSpeedTestPageSize" xml:space="preserve">
|
||||||
<value>测速时自动分批的每批数量(最大1000)</value>
|
<value>测试时自动分批的每批数量(最大1000)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsExceptionTip2" xml:space="preserve">
|
<data name="TbSettingsExceptionTip2" xml:space="preserve">
|
||||||
<value>例外. 对于下列地址不使用代理配置文件:使用逗号(,)分隔</value>
|
<value>例外. 对于下列地址不使用代理配置文件:使用逗号(,)分隔</value>
|
||||||
|
|||||||
@@ -1382,7 +1382,7 @@
|
|||||||
<value>關閉視窗時隱藏至托盤</value>
|
<value>關閉視窗時隱藏至托盤</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsSpeedTestPageSize" xml:space="preserve">
|
<data name="TbSettingsSpeedTestPageSize" xml:space="preserve">
|
||||||
<value>測速時自動分批的每批數量(最大1000)</value>
|
<value>測試時自動分批的每批數量(最大1000)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsExceptionTip2" xml:space="preserve">
|
<data name="TbSettingsExceptionTip2" xml:space="preserve">
|
||||||
<value>例外. 對於下列位址不使用代理設定檔:使用逗號(,)分隔</value>
|
<value>例外. 對於下列位址不使用代理設定檔:使用逗號(,)分隔</value>
|
||||||
|
|||||||
@@ -1,149 +1,156 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"remarks": "绕过bittorrent",
|
"remarks": "绕过bittorrent",
|
||||||
"outboundTag": "direct",
|
"outboundTag": "direct",
|
||||||
"protocol": [
|
"protocol": [
|
||||||
"bittorrent"
|
"bittorrent"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"remarks": "Google cn",
|
"remarks": "api.ip.sb",
|
||||||
"outboundTag": "proxy",
|
"outboundTag": "proxy",
|
||||||
"domain": [
|
"domain": [
|
||||||
"domain:googleapis.cn",
|
"api.ip.sb"
|
||||||
"domain:gstatic.com"
|
]
|
||||||
]
|
},
|
||||||
},
|
{
|
||||||
{
|
"remarks": "Google cn",
|
||||||
"remarks": "阻断udp443",
|
"outboundTag": "proxy",
|
||||||
"outboundTag": "block",
|
"domain": [
|
||||||
"port": "443",
|
"domain:googleapis.cn",
|
||||||
"network": "udp"
|
"domain:gstatic.com"
|
||||||
},
|
]
|
||||||
{
|
},
|
||||||
"remarks": "阻断广告",
|
{
|
||||||
"outboundTag": "block",
|
"remarks": "阻断udp443",
|
||||||
"domain": [
|
"outboundTag": "block",
|
||||||
"geosite:category-ads-all"
|
"port": "443",
|
||||||
]
|
"network": "udp"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"remarks": "绕过局域网IP",
|
"remarks": "阻断广告",
|
||||||
"outboundTag": "direct",
|
"outboundTag": "block",
|
||||||
"ip": [
|
"domain": [
|
||||||
"geoip:private"
|
"geosite:category-ads-all"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"remarks": "绕过局域网域名",
|
"remarks": "绕过局域网IP",
|
||||||
"outboundTag": "direct",
|
"outboundTag": "direct",
|
||||||
"domain": [
|
"ip": [
|
||||||
"geosite:private"
|
"geoip:private"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"remarks": "代理海外公共DNSIP",
|
"remarks": "绕过局域网域名",
|
||||||
"outboundTag": "proxy",
|
"outboundTag": "direct",
|
||||||
"ip": [
|
"domain": [
|
||||||
"1.1.1.1",
|
"geosite:private"
|
||||||
"1.0.0.1",
|
]
|
||||||
"2606:4700:4700::1111",
|
},
|
||||||
"2606:4700:4700::1001",
|
{
|
||||||
"1.1.1.2",
|
"remarks": "代理海外公共DNSIP",
|
||||||
"1.0.0.2",
|
"outboundTag": "proxy",
|
||||||
"2606:4700:4700::1112",
|
"ip": [
|
||||||
"2606:4700:4700::1002",
|
"1.1.1.1",
|
||||||
"1.1.1.3",
|
"1.0.0.1",
|
||||||
"1.0.0.3",
|
"2606:4700:4700::1111",
|
||||||
"2606:4700:4700::1113",
|
"2606:4700:4700::1001",
|
||||||
"2606:4700:4700::1003",
|
"1.1.1.2",
|
||||||
"8.8.8.8",
|
"1.0.0.2",
|
||||||
"8.8.4.4",
|
"2606:4700:4700::1112",
|
||||||
"2001:4860:4860::8888",
|
"2606:4700:4700::1002",
|
||||||
"2001:4860:4860::8844",
|
"1.1.1.3",
|
||||||
"94.140.14.14",
|
"1.0.0.3",
|
||||||
"94.140.15.15",
|
"2606:4700:4700::1113",
|
||||||
"2a10:50c0::ad1:ff",
|
"2606:4700:4700::1003",
|
||||||
"2a10:50c0::ad2:ff",
|
"8.8.8.8",
|
||||||
"94.140.14.15",
|
"8.8.4.4",
|
||||||
"94.140.15.16",
|
"2001:4860:4860::8888",
|
||||||
"2a10:50c0::bad1:ff",
|
"2001:4860:4860::8844",
|
||||||
"2a10:50c0::bad2:ff",
|
"94.140.14.14",
|
||||||
"94.140.14.140",
|
"94.140.15.15",
|
||||||
"94.140.14.141",
|
"2a10:50c0::ad1:ff",
|
||||||
"2a10:50c0::1:ff",
|
"2a10:50c0::ad2:ff",
|
||||||
"2a10:50c0::2:ff",
|
"94.140.14.15",
|
||||||
"208.67.222.222",
|
"94.140.15.16",
|
||||||
"208.67.220.220",
|
"2a10:50c0::bad1:ff",
|
||||||
"2620:119:35::35",
|
"2a10:50c0::bad2:ff",
|
||||||
"2620:119:53::53",
|
"94.140.14.140",
|
||||||
"208.67.222.123",
|
"94.140.14.141",
|
||||||
"208.67.220.123",
|
"2a10:50c0::1:ff",
|
||||||
"2620:119:35::123",
|
"2a10:50c0::2:ff",
|
||||||
"2620:119:53::123",
|
"208.67.222.222",
|
||||||
"9.9.9.9",
|
"208.67.220.220",
|
||||||
"149.112.112.112",
|
"2620:119:35::35",
|
||||||
"2620:fe::9",
|
"2620:119:53::53",
|
||||||
"2620:fe::fe",
|
"208.67.222.123",
|
||||||
"9.9.9.11",
|
"208.67.220.123",
|
||||||
"149.112.112.11",
|
"2620:119:35::123",
|
||||||
"2620:fe::11",
|
"2620:119:53::123",
|
||||||
"2620:fe::fe:11",
|
"9.9.9.9",
|
||||||
"9.9.9.10",
|
"149.112.112.112",
|
||||||
"149.112.112.10",
|
"2620:fe::9",
|
||||||
"2620:fe::10",
|
"2620:fe::fe",
|
||||||
"2620:fe::fe:10",
|
"9.9.9.11",
|
||||||
"77.88.8.8",
|
"149.112.112.11",
|
||||||
"77.88.8.1",
|
"2620:fe::11",
|
||||||
"2a02:6b8::feed:0ff",
|
"2620:fe::fe:11",
|
||||||
"2a02:6b8:0:1::feed:0ff",
|
"9.9.9.10",
|
||||||
"77.88.8.88",
|
"149.112.112.10",
|
||||||
"77.88.8.2",
|
"2620:fe::10",
|
||||||
"2a02:6b8::feed:bad",
|
"2620:fe::fe:10",
|
||||||
"2a02:6b8:0:1::feed:bad",
|
"77.88.8.8",
|
||||||
"77.88.8.7",
|
"77.88.8.1",
|
||||||
"77.88.8.3",
|
"2a02:6b8::feed:0ff",
|
||||||
"2a02:6b8::feed:a11",
|
"2a02:6b8:0:1::feed:0ff",
|
||||||
"2a02:6b8:0:1::feed:a11"
|
"77.88.8.88",
|
||||||
]
|
"77.88.8.2",
|
||||||
},
|
"2a02:6b8::feed:bad",
|
||||||
{
|
"2a02:6b8:0:1::feed:bad",
|
||||||
"remarks": "代理海外公共DNS域名",
|
"77.88.8.7",
|
||||||
"outboundTag": "proxy",
|
"77.88.8.3",
|
||||||
"domain": [
|
"2a02:6b8::feed:a11",
|
||||||
"domain:cloudflare-dns.com",
|
"2a02:6b8:0:1::feed:a11"
|
||||||
"domain:one.one.one.one",
|
]
|
||||||
"domain:dns.google",
|
},
|
||||||
"domain:adguard-dns.com",
|
{
|
||||||
"domain:opendns.com",
|
"remarks": "代理海外公共DNS域名",
|
||||||
"domain:umbrella.com",
|
"outboundTag": "proxy",
|
||||||
"domain:quad9.net",
|
"domain": [
|
||||||
"domain:yandex.net"
|
"domain:cloudflare-dns.com",
|
||||||
]
|
"domain:one.one.one.one",
|
||||||
},
|
"domain:dns.google",
|
||||||
{
|
"domain:adguard-dns.com",
|
||||||
"remarks": "代理IP",
|
"domain:opendns.com",
|
||||||
"outboundTag": "proxy",
|
"domain:umbrella.com",
|
||||||
"ip": [
|
"domain:quad9.net",
|
||||||
"geoip:facebook",
|
"domain:yandex.net"
|
||||||
"geoip:fastly",
|
]
|
||||||
"geoip:google",
|
},
|
||||||
"geoip:netflix",
|
{
|
||||||
"geoip:telegram",
|
"remarks": "代理IP",
|
||||||
"geoip:twitter"
|
"outboundTag": "proxy",
|
||||||
]
|
"ip": [
|
||||||
},
|
"geoip:facebook",
|
||||||
{
|
"geoip:fastly",
|
||||||
"remarks": "代理GFW",
|
"geoip:google",
|
||||||
"outboundTag": "proxy",
|
"geoip:netflix",
|
||||||
"domain": [
|
"geoip:telegram",
|
||||||
"geosite:gfw",
|
"geoip:twitter"
|
||||||
"geosite:greatfire"
|
]
|
||||||
]
|
},
|
||||||
},
|
{
|
||||||
{
|
"remarks": "代理GFW",
|
||||||
"remarks": "最终直连",
|
"outboundTag": "proxy",
|
||||||
"port": "0-65535",
|
"domain": [
|
||||||
"outboundTag": "direct"
|
"geosite:gfw",
|
||||||
}
|
"geosite:greatfire"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"remarks": "最终直连",
|
||||||
|
"port": "0-65535",
|
||||||
|
"outboundTag": "direct"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"domain": [
|
|
||||||
"geosite:google"
|
|
||||||
],
|
|
||||||
"outboundTag": "proxy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"outboundTag": "direct",
|
|
||||||
"domain": [
|
|
||||||
"domain:example-example.com",
|
|
||||||
"domain:example-example2.com"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"outboundTag": "block",
|
|
||||||
"domain": [
|
|
||||||
"geosite:category-ads-all"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"remarks": "block",
|
|
||||||
"outboundTag": "block",
|
|
||||||
"domain": [
|
|
||||||
"geosite:category-ads-all"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"remarks": "direct",
|
|
||||||
"outboundTag": "direct",
|
|
||||||
"domain": [
|
|
||||||
"geosite:cn"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"remarks": "direct",
|
|
||||||
"outboundTag": "direct",
|
|
||||||
"ip": [
|
|
||||||
"geoip:private",
|
|
||||||
"geoip:cn"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"remarks": "proxy",
|
|
||||||
"port": "0-65535",
|
|
||||||
"outboundTag": "proxy"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Version>7.3.1</Version>
|
<Version>7.4.1</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<PackageReference Include="WebDav.Client" Version="2.8.0" />
|
<PackageReference Include="WebDav.Client" Version="2.8.0" />
|
||||||
<PackageReference Include="YamlDotNet" Version="16.2.1" />
|
<PackageReference Include="YamlDotNet" Version="16.2.1" />
|
||||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||||
<PackageReference Include="CliWrap" Version="3.6.7" />
|
<PackageReference Include="CliWrap" Version="3.7.0" />
|
||||||
<PackageReference Include="SkiaSharp.QrCode" Version="0.7.0" />
|
<PackageReference Include="SkiaSharp.QrCode" Version="0.7.0" />
|
||||||
<PackageReference Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
<PackageReference Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
||||||
<PackageReference Include="TaskScheduler" Version="2.11.0" />
|
<PackageReference Include="TaskScheduler" Version="2.11.0" />
|
||||||
@@ -28,8 +28,6 @@
|
|||||||
<EmbeddedResource Include="Sample\clash_tun_yaml" />
|
<EmbeddedResource Include="Sample\clash_tun_yaml" />
|
||||||
<EmbeddedResource Include="Sample\custom_routing_black" />
|
<EmbeddedResource Include="Sample\custom_routing_black" />
|
||||||
<EmbeddedResource Include="Sample\custom_routing_global" />
|
<EmbeddedResource Include="Sample\custom_routing_global" />
|
||||||
<EmbeddedResource Include="Sample\custom_routing_locked" />
|
|
||||||
<EmbeddedResource Include="Sample\custom_routing_rules" />
|
|
||||||
<EmbeddedResource Include="Sample\custom_routing_white" />
|
<EmbeddedResource Include="Sample\custom_routing_white" />
|
||||||
<EmbeddedResource Include="Sample\dns_singbox_normal" />
|
<EmbeddedResource Include="Sample\dns_singbox_normal" />
|
||||||
<EmbeddedResource Include="Sample\dns_v2ray_normal" />
|
<EmbeddedResource Include="Sample\dns_v2ray_normal" />
|
||||||
@@ -60,6 +58,9 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Update="Resx\ResUI.hu.resx">
|
||||||
|
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Update="Resx\ResUI.resx">
|
<EmbeddedResource Update="Resx\ResUI.resx">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<LastGenOutput>ResUI.Designer.cs</LastGenOutput>
|
<LastGenOutput>ResUI.Designer.cs</LastGenOutput>
|
||||||
|
|||||||
@@ -442,7 +442,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
|
|
||||||
#region private gen function
|
#region private gen function
|
||||||
|
|
||||||
public async Task<int> GenLog(SingboxConfig singboxConfig)
|
private async Task<int> GenLog(SingboxConfig singboxConfig)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -570,7 +570,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return inbound;
|
return inbound;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenOutbound(ProfileItem node, Outbound4Sbox outbound)
|
private async Task<int> GenOutbound(ProfileItem node, Outbound4Sbox outbound)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -694,7 +694,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenOutboundMux(ProfileItem node, Outbound4Sbox outbound)
|
private async Task<int> GenOutboundMux(ProfileItem node, Outbound4Sbox outbound)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -717,7 +717,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenOutboundTls(ProfileItem node, Outbound4Sbox outbound)
|
private async Task<int> GenOutboundTls(ProfileItem node, Outbound4Sbox outbound)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -767,7 +767,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenOutboundTransport(ProfileItem node, Outbound4Sbox outbound)
|
private async Task<int> GenOutboundTransport(ProfileItem node, Outbound4Sbox outbound)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -994,7 +994,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenRoutingUserRule(RulesItem item, List<Rule4Sbox> rules)
|
private async Task<int> GenRoutingUserRule(RulesItem item, List<Rule4Sbox> rules)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1152,7 +1152,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenDns(ProfileItem? node, SingboxConfig singboxConfig)
|
private async Task<int> GenDns(ProfileItem? node, SingboxConfig singboxConfig)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1183,7 +1183,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenDnsDomains(ProfileItem? node, SingboxConfig singboxConfig, DNSItem? dNSItem)
|
private async Task<int> GenDnsDomains(ProfileItem? node, SingboxConfig singboxConfig, DNSItem? dNSItem)
|
||||||
{
|
{
|
||||||
var dns4Sbox = singboxConfig.dns ?? new();
|
var dns4Sbox = singboxConfig.dns ?? new();
|
||||||
dns4Sbox.servers ??= [];
|
dns4Sbox.servers ??= [];
|
||||||
@@ -1236,7 +1236,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenExperimental(SingboxConfig singboxConfig)
|
private async Task<int> GenExperimental(SingboxConfig singboxConfig)
|
||||||
{
|
{
|
||||||
//if (_config.guiItem.enableStatistics)
|
//if (_config.guiItem.enableStatistics)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
|
|
||||||
#region private gen function
|
#region private gen function
|
||||||
|
|
||||||
public async Task<int> GenLog(V2rayConfig v2rayConfig)
|
private async Task<int> GenLog(V2rayConfig v2rayConfig)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -384,7 +384,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenInbounds(V2rayConfig v2rayConfig)
|
private async Task<int> GenInbounds(V2rayConfig v2rayConfig)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -481,7 +481,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenRoutingUserRule(RulesItem4Ray? rule, V2rayConfig v2rayConfig)
|
private async Task<int> GenRoutingUserRule(RulesItem4Ray? rule, V2rayConfig v2rayConfig)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -559,7 +559,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenOutbound(ProfileItem node, Outbounds4Ray outbound)
|
private async Task<int> GenOutbound(ProfileItem node, Outbounds4Ray outbound)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -700,8 +700,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
|
|
||||||
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
|
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
|
||||||
|
|
||||||
if (node.StreamSecurity == Global.StreamSecurityReality
|
if (node.StreamSecurity == Global.StreamSecurityReality || node.StreamSecurity == Global.StreamSecurity)
|
||||||
|| node.StreamSecurity == Global.StreamSecurity)
|
|
||||||
{
|
{
|
||||||
if (Utils.IsNotEmpty(node.Flow))
|
if (Utils.IsNotEmpty(node.Flow))
|
||||||
{
|
{
|
||||||
@@ -745,7 +744,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
outbound.protocol = Global.ProtocolTypes[node.ConfigType];
|
outbound.protocol = Global.ProtocolTypes[node.ConfigType];
|
||||||
await GenBoundStreamSettings(node, outbound.streamSettings);
|
await GenBoundStreamSettings(node, outbound);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -754,7 +753,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenOutboundMux(ProfileItem node, Outbounds4Ray outbound, bool enabled)
|
private async Task<int> GenOutboundMux(ProfileItem node, Outbounds4Ray outbound, bool enabled)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -778,14 +777,16 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenBoundStreamSettings(ProfileItem node, StreamSettings4Ray streamSettings)
|
private async Task<int> GenBoundStreamSettings(ProfileItem node, Outbounds4Ray outbound)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var streamSettings = outbound.streamSettings;
|
||||||
streamSettings.network = node.GetNetwork();
|
streamSettings.network = node.GetNetwork();
|
||||||
string host = node.RequestHost.TrimEx();
|
var host = node.RequestHost.TrimEx();
|
||||||
string sni = node.Sni;
|
var path = node.Path.TrimEx();
|
||||||
string useragent = "";
|
var sni = node.Sni.TrimEx();
|
||||||
|
var useragent = "";
|
||||||
if (!_config.CoreBasicItem.DefUserAgent.IsNullOrEmpty())
|
if (!_config.CoreBasicItem.DefUserAgent.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -858,9 +859,9 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
{
|
{
|
||||||
type = node.HeaderType
|
type = node.HeaderType
|
||||||
};
|
};
|
||||||
if (Utils.IsNotEmpty(node.Path))
|
if (Utils.IsNotEmpty(path))
|
||||||
{
|
{
|
||||||
kcpSettings.seed = node.Path;
|
kcpSettings.seed = path;
|
||||||
}
|
}
|
||||||
streamSettings.kcpSettings = kcpSettings;
|
streamSettings.kcpSettings = kcpSettings;
|
||||||
break;
|
break;
|
||||||
@@ -868,9 +869,10 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
case nameof(ETransport.ws):
|
case nameof(ETransport.ws):
|
||||||
WsSettings4Ray wsSettings = new();
|
WsSettings4Ray wsSettings = new();
|
||||||
wsSettings.headers = new Headers4Ray();
|
wsSettings.headers = new Headers4Ray();
|
||||||
string path = node.Path;
|
|
||||||
if (Utils.IsNotEmpty(host))
|
if (Utils.IsNotEmpty(host))
|
||||||
{
|
{
|
||||||
|
wsSettings.host = host;
|
||||||
wsSettings.headers.Host = host;
|
wsSettings.headers.Host = host;
|
||||||
}
|
}
|
||||||
if (Utils.IsNotEmpty(path))
|
if (Utils.IsNotEmpty(path))
|
||||||
@@ -888,9 +890,9 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
case nameof(ETransport.httpupgrade):
|
case nameof(ETransport.httpupgrade):
|
||||||
HttpupgradeSettings4Ray httpupgradeSettings = new();
|
HttpupgradeSettings4Ray httpupgradeSettings = new();
|
||||||
|
|
||||||
if (Utils.IsNotEmpty(node.Path))
|
if (Utils.IsNotEmpty(path))
|
||||||
{
|
{
|
||||||
httpupgradeSettings.path = node.Path;
|
httpupgradeSettings.path = path;
|
||||||
}
|
}
|
||||||
if (Utils.IsNotEmpty(host))
|
if (Utils.IsNotEmpty(host))
|
||||||
{
|
{
|
||||||
@@ -902,16 +904,11 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
//xhttp
|
//xhttp
|
||||||
case nameof(ETransport.xhttp):
|
case nameof(ETransport.xhttp):
|
||||||
streamSettings.network = ETransport.xhttp.ToString();
|
streamSettings.network = ETransport.xhttp.ToString();
|
||||||
XhttpSettings4Ray xhttpSettings = new()
|
XhttpSettings4Ray xhttpSettings = new();
|
||||||
{
|
|
||||||
scMaxEachPostBytes = "500000-1000000",
|
|
||||||
scMaxConcurrentPosts = "50-100",
|
|
||||||
scMinPostsIntervalMs = "30-50"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Utils.IsNotEmpty(node.Path))
|
if (Utils.IsNotEmpty(path))
|
||||||
{
|
{
|
||||||
xhttpSettings.path = node.Path;
|
xhttpSettings.path = path;
|
||||||
}
|
}
|
||||||
if (Utils.IsNotEmpty(host))
|
if (Utils.IsNotEmpty(host))
|
||||||
{
|
{
|
||||||
@@ -927,6 +924,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
streamSettings.xhttpSettings = xhttpSettings;
|
streamSettings.xhttpSettings = xhttpSettings;
|
||||||
|
await GenOutboundMux(node, outbound, false);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
//h2
|
//h2
|
||||||
@@ -937,7 +935,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
{
|
{
|
||||||
httpSettings.host = Utils.String2List(host);
|
httpSettings.host = Utils.String2List(host);
|
||||||
}
|
}
|
||||||
httpSettings.path = node.Path;
|
httpSettings.path = path;
|
||||||
|
|
||||||
streamSettings.httpSettings = httpSettings;
|
streamSettings.httpSettings = httpSettings;
|
||||||
|
|
||||||
@@ -947,7 +945,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
QuicSettings4Ray quicsettings = new()
|
QuicSettings4Ray quicsettings = new()
|
||||||
{
|
{
|
||||||
security = host,
|
security = host,
|
||||||
key = node.Path,
|
key = path,
|
||||||
header = new Header4Ray
|
header = new Header4Ray
|
||||||
{
|
{
|
||||||
type = node.HeaderType
|
type = node.HeaderType
|
||||||
@@ -971,7 +969,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
GrpcSettings4Ray grpcSettings = new()
|
GrpcSettings4Ray grpcSettings = new()
|
||||||
{
|
{
|
||||||
authority = Utils.IsNullOrEmpty(host) ? null : host,
|
authority = Utils.IsNullOrEmpty(host) ? null : host,
|
||||||
serviceName = node.Path,
|
serviceName = path,
|
||||||
multiMode = node.HeaderType == Global.GrpcMultiMode,
|
multiMode = node.HeaderType == Global.GrpcMultiMode,
|
||||||
idle_timeout = _config.GrpcItem.IdleTimeout,
|
idle_timeout = _config.GrpcItem.IdleTimeout,
|
||||||
health_check_timeout = _config.GrpcItem.HealthCheckTimeout,
|
health_check_timeout = _config.GrpcItem.HealthCheckTimeout,
|
||||||
@@ -1001,9 +999,9 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
request = request.Replace("$requestUserAgent$", $"{useragent.AppendQuotes()}");
|
request = request.Replace("$requestUserAgent$", $"{useragent.AppendQuotes()}");
|
||||||
//Path
|
//Path
|
||||||
string pathHttp = @"/";
|
string pathHttp = @"/";
|
||||||
if (Utils.IsNotEmpty(node.Path))
|
if (Utils.IsNotEmpty(path))
|
||||||
{
|
{
|
||||||
string[] arrPath = node.Path.Split(',');
|
string[] arrPath = path.Split(',');
|
||||||
pathHttp = string.Join(",".AppendQuotes(), arrPath);
|
pathHttp = string.Join(",".AppendQuotes(), arrPath);
|
||||||
}
|
}
|
||||||
request = request.Replace("$requestPath$", $"{pathHttp.AppendQuotes()}");
|
request = request.Replace("$requestPath$", $"{pathHttp.AppendQuotes()}");
|
||||||
@@ -1021,7 +1019,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenDns(ProfileItem? node, V2rayConfig v2rayConfig)
|
private async Task<int> GenDns(ProfileItem? node, V2rayConfig v2rayConfig)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1084,7 +1082,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenDnsDomains(ProfileItem? node, JsonNode dns, DNSItem? dNSItem)
|
private async Task<int> GenDnsDomains(ProfileItem? node, JsonNode dns, DNSItem? dNSItem)
|
||||||
{
|
{
|
||||||
if (node == null)
|
if (node == null)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
@@ -1104,7 +1102,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GenStatistic(V2rayConfig v2rayConfig)
|
private async Task<int> GenStatistic(V2rayConfig v2rayConfig)
|
||||||
{
|
{
|
||||||
if (_config.GuiItem.EnableStatistics)
|
if (_config.GuiItem.EnableStatistics)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -160,9 +160,9 @@ namespace ServiceLib.ViewModels
|
|||||||
var configDirZipTemp = Utils.GetTempPath($"v2rayN_{DateTime.Now:yyyyMMddHHmmss}");
|
var configDirZipTemp = Utils.GetTempPath($"v2rayN_{DateTime.Now:yyyyMMddHHmmss}");
|
||||||
var configDirTemp = Path.Combine(configDirZipTemp, _guiConfigs);
|
var configDirTemp = Path.Combine(configDirZipTemp, _guiConfigs);
|
||||||
|
|
||||||
await Task.Run(() => FileManager.CopyDirectory(configDir, configDirTemp, false, "cache.db"));
|
FileManager.CopyDirectory(configDir, configDirTemp, false, "cache.db");
|
||||||
var ret = await Task.Run(() => FileManager.CreateFromDirectory(configDirZipTemp, fileName));
|
var ret = FileManager.CreateFromDirectory(configDirZipTemp, fileName);
|
||||||
await Task.Run(() => Directory.Delete(configDirZipTemp, true));
|
Directory.Delete(configDirZipTemp, true);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ namespace ServiceLib.ViewModels
|
|||||||
FileManager.ZipExtractToFile(fileName, toPath, _config.GuiItem.IgnoreGeoUpdateCore ? "geo" : "");
|
FileManager.ZipExtractToFile(fileName, toPath, _config.GuiItem.IgnoreGeoUpdateCore ? "geo" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.IsLinux() || Utils.IsOSX())
|
if (Utils.IsNonWindows())
|
||||||
{
|
{
|
||||||
var filesList = (new DirectoryInfo(toPath)).GetFiles().Select(u => u.FullName).ToList();
|
var filesList = (new DirectoryInfo(toPath)).GetFiles().Select(u => u.FullName).ToList();
|
||||||
foreach (var file in filesList)
|
foreach (var file in filesList)
|
||||||
|
|||||||
@@ -283,6 +283,7 @@ namespace ServiceLib.ViewModels
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logging.SaveLog("MyAppExitAsync Begin");
|
Logging.SaveLog("MyAppExitAsync Begin");
|
||||||
|
MessageBus.Current.SendMessage("", EMsgCommand.AppExit.ToString());
|
||||||
|
|
||||||
await ConfigHandler.SaveConfig(_config);
|
await ConfigHandler.SaveConfig(_config);
|
||||||
await SysProxyHandler.UpdateSysProxy(_config, true);
|
await SysProxyHandler.UpdateSysProxy(_config, true);
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
private ConcurrentQueue<string> _queueMsg = new();
|
private ConcurrentQueue<string> _queueMsg = new();
|
||||||
private int _numMaxMsg = 500;
|
private int _numMaxMsg = 500;
|
||||||
private string _lastMsgFilter = string.Empty;
|
|
||||||
private bool _lastMsgFilterNotAvailable;
|
private bool _lastMsgFilterNotAvailable;
|
||||||
private bool _blLockShow = false;
|
private bool _blLockShow = false;
|
||||||
|
|
||||||
@@ -28,7 +27,7 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.MsgFilter)
|
x => x.MsgFilter)
|
||||||
.Subscribe(c => _config.MsgUIItem.MainMsgFilter = MsgFilter);
|
.Subscribe(c => DoMsgFilter());
|
||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.AutoRefresh,
|
x => x.AutoRefresh,
|
||||||
@@ -77,8 +76,7 @@ namespace ServiceLib.ViewModels
|
|||||||
private async Task EnqueueQueueMsg(string msg)
|
private async Task EnqueueQueueMsg(string msg)
|
||||||
{
|
{
|
||||||
//filter msg
|
//filter msg
|
||||||
if (MsgFilter != _lastMsgFilter) _lastMsgFilterNotAvailable = false;
|
if (MsgFilter.IsNotEmpty() && !_lastMsgFilterNotAvailable)
|
||||||
if (Utils.IsNotEmpty(MsgFilter) && !_lastMsgFilterNotAvailable)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -87,12 +85,12 @@ namespace ServiceLib.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_queueMsg.Enqueue(ex.Message);
|
||||||
_lastMsgFilterNotAvailable = true;
|
_lastMsgFilterNotAvailable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_lastMsgFilter = MsgFilter;
|
|
||||||
|
|
||||||
//Enqueue
|
//Enqueue
|
||||||
if (_queueMsg.Count > _numMaxMsg)
|
if (_queueMsg.Count > _numMaxMsg)
|
||||||
@@ -113,5 +111,11 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
_queueMsg.Clear();
|
_queueMsg.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DoMsgFilter()
|
||||||
|
{
|
||||||
|
_config.MsgUIItem.MainMsgFilter = MsgFilter;
|
||||||
|
_lastMsgFilterNotAvailable = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,13 +56,13 @@ public partial class App : Application
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MenuAddServerViaClipboardClick(object? sender, EventArgs e)
|
private async void MenuAddServerViaClipboardClick(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
{
|
{
|
||||||
if (desktop.MainWindow != null)
|
if (desktop.MainWindow != null)
|
||||||
{
|
{
|
||||||
var clipboardData = AvaUtils.GetClipboardData(desktop.MainWindow).Result;
|
var clipboardData = await AvaUtils.GetClipboardData(desktop.MainWindow);
|
||||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||||
if (service != null) _ = service.AddServerViaClipboardAsync(clipboardData);
|
if (service != null) _ = service.AddServerViaClipboardAsync(clipboardData);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,18 +6,18 @@
|
|||||||
</Design.PreviewWith>
|
</Design.PreviewWith>
|
||||||
|
|
||||||
<Style Selector="TextBlock.Margin8">
|
<Style Selector="TextBlock.Margin8">
|
||||||
<Setter Property="Margin" Value="10" />
|
<Setter Property="Margin" Value="8" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="StackPanel.Margin8">
|
<Style Selector="StackPanel.Margin8">
|
||||||
<Setter Property="Margin" Value="10" />
|
<Setter Property="Margin" Value="8" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="DockPanel.Margin8">
|
<Style Selector="DockPanel.Margin8">
|
||||||
<Setter Property="Margin" Value="10" />
|
<Setter Property="Margin" Value="8" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="WrapPanel.Margin8">
|
<Style Selector="WrapPanel.Margin8">
|
||||||
<Setter Property="Margin" Value="10" />
|
<Setter Property="Margin" Value="8" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="Grid.Margin8">
|
<Style Selector="Grid.Margin8">
|
||||||
<Setter Property="Margin" Value="10" />
|
<Setter Property="Margin" Value="8" />
|
||||||
</Style>
|
</Style>
|
||||||
</Styles>
|
</Styles>
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Common
|
namespace v2rayN.Desktop.Common
|
||||||
{
|
{
|
||||||
@@ -8,7 +7,7 @@ namespace v2rayN.Desktop.Common
|
|||||||
{
|
{
|
||||||
public static AppBuilder WithFontByDefault(this AppBuilder appBuilder)
|
public static AppBuilder WithFontByDefault(this AppBuilder appBuilder)
|
||||||
{
|
{
|
||||||
var uri = $"avares://{Assembly.GetExecutingAssembly().GetName().Name}/Assets/Fonts#Noto Sans SC";
|
var uri = Path.Combine(Global.AvaAssets, "Fonts#Noto Sans SC");
|
||||||
return appBuilder.With(new FontManagerOptions()
|
return appBuilder.With(new FontManagerOptions()
|
||||||
{
|
{
|
||||||
DefaultFamilyName = uri,
|
DefaultFamilyName = uri,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Platform;
|
using Avalonia.Platform;
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Common
|
namespace v2rayN.Desktop.Common
|
||||||
{
|
{
|
||||||
@@ -41,7 +40,7 @@ namespace v2rayN.Desktop.Common
|
|||||||
public static WindowIcon GetAppIcon(ESysProxyType sysProxyType)
|
public static WindowIcon GetAppIcon(ESysProxyType sysProxyType)
|
||||||
{
|
{
|
||||||
var index = (int)sysProxyType + 1;
|
var index = (int)sysProxyType + 1;
|
||||||
var uri = new Uri($"avares://{Assembly.GetExecutingAssembly().GetName().Name}/Assets/NotifyIcon{index}.ico");
|
var uri = new Uri(Path.Combine(Global.AvaAssets, $"NotifyIcon{index}.ico"));
|
||||||
using var bitmap = new Bitmap(AssetLoader.Open(uri));
|
using var bitmap = new Bitmap(AssetLoader.Open(uri));
|
||||||
return new(bitmap);
|
return new(bitmap);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuServers}"
|
Title="{x:Static resx:ResUI.menuServers}"
|
||||||
Width="900"
|
Width="900"
|
||||||
Height="700"
|
Height="600"
|
||||||
x:DataType="vms:AddServerViewModel"
|
x:DataType="vms:AddServerViewModel"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
<Border
|
<Border
|
||||||
Width="500"
|
Width="500"
|
||||||
Height="80"
|
Height="80"
|
||||||
Margin="-2"
|
Margin="-8"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Theme="{StaticResource CardBorder}">
|
Theme="{StaticResource CardBorder}">
|
||||||
<Grid>
|
<Grid>
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Border
|
<Border
|
||||||
Width="160"
|
Width="160"
|
||||||
Margin="0"
|
Margin="-6"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
Theme="{StaticResource CardBorder}">
|
Theme="{StaticResource CardBorder}">
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
@@ -143,13 +143,12 @@
|
|||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Border
|
<Border
|
||||||
Width="160"
|
Width="160"
|
||||||
Margin="0"
|
Margin="-6"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
Theme="{StaticResource CardBorder}">
|
Theme="{StaticResource CardBorder}">
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<Border
|
<Border
|
||||||
Width="5"
|
Width="5"
|
||||||
Height="30"
|
|
||||||
Margin="0,1"
|
Margin="0,1"
|
||||||
Background="YellowGreen"
|
Background="YellowGreen"
|
||||||
CornerRadius="4"
|
CornerRadius="4"
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuDNSSetting}"
|
Title="{x:Static resx:ResUI.menuDNSSetting}"
|
||||||
Width="1000"
|
Width="900"
|
||||||
Height="700"
|
Height="600"
|
||||||
x:DataType="vms:DNSSettingViewModel"
|
x:DataType="vms:DNSSettingViewModel"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="v2rayN"
|
Title="v2rayN"
|
||||||
Width="900"
|
Width="900"
|
||||||
Height="700"
|
Height="600"
|
||||||
MinWidth="900"
|
MinWidth="900"
|
||||||
x:DataType="vms:MainWindowViewModel"
|
x:DataType="vms:MainWindowViewModel"
|
||||||
Icon="/Assets/NotifyIcon1.ico"
|
Icon="/Assets/NotifyIcon1.ico"
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
RestoreUI();
|
RestoreUI();
|
||||||
AddHelpMenuItem();
|
AddHelpMenuItem();
|
||||||
//WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
//WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
||||||
|
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Event
|
#region Event
|
||||||
@@ -441,7 +442,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StorageUI()
|
private void StorageUI(string? n = null)
|
||||||
{
|
{
|
||||||
_config.UiItem.MainWidth = Utils.ToInt(this.Width);
|
_config.UiItem.MainWidth = Utils.ToInt(this.Width);
|
||||||
_config.UiItem.MainHeight = Utils.ToInt(this.Height);
|
_config.UiItem.MainHeight = Utils.ToInt(this.Height);
|
||||||
@@ -456,7 +457,6 @@ namespace v2rayN.Desktop.Views
|
|||||||
_config.UiItem.MainGirdHeight1 = Math.Ceiling(gridMain1.RowDefinitions[0].ActualHeight + 0.1);
|
_config.UiItem.MainGirdHeight1 = Math.Ceiling(gridMain1.RowDefinitions[0].ActualHeight + 0.1);
|
||||||
_config.UiItem.MainGirdHeight2 = Math.Ceiling(gridMain1.RowDefinitions[2].ActualHeight + 0.1);
|
_config.UiItem.MainGirdHeight2 = Math.Ceiling(gridMain1.RowDefinitions[2].ActualHeight + 0.1);
|
||||||
}
|
}
|
||||||
ConfigHandler.SaveConfig(_config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddHelpMenuItem()
|
private void AddHelpMenuItem()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuSetting}"
|
Title="{x:Static resx:ResUI.menuSetting}"
|
||||||
Width="1000"
|
Width="1000"
|
||||||
Height="700"
|
Height="600"
|
||||||
x:DataType="vms:OptionSettingViewModel"
|
x:DataType="vms:OptionSettingViewModel"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
{
|
{
|
||||||
return lstFonts;
|
return lstFonts;
|
||||||
}
|
}
|
||||||
else if (Utils.IsLinux() || Utils.IsOSX())
|
else if (Utils.IsNonWindows())
|
||||||
{
|
{
|
||||||
var result = await Utils.GetLinuxFontFamily("zh");
|
var result = await Utils.GetLinuxFontFamily("zh");
|
||||||
if (result.IsNullOrEmpty())
|
if (result.IsNullOrEmpty())
|
||||||
|
|||||||
@@ -56,28 +56,23 @@
|
|||||||
Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
||||||
</Button.Content>
|
</Button.Content>
|
||||||
</Button>
|
</Button>
|
||||||
<SplitButton
|
|
||||||
|
<Button
|
||||||
x:Name="btnAutofitColumnWidth"
|
x:Name="btnAutofitColumnWidth"
|
||||||
Width="54"
|
Width="30"
|
||||||
Height="30"
|
Height="30"
|
||||||
Margin="20,0"
|
Margin="4,0"
|
||||||
Padding="2"
|
Classes="Success"
|
||||||
Classes="Tertiary"
|
Theme="{DynamicResource BorderlessButton}"
|
||||||
Theme="{DynamicResource BorderlessSplitButton}"
|
|
||||||
ToolTip.Tip="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}">
|
ToolTip.Tip="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}">
|
||||||
<SplitButton.Content>
|
<Button.Content>
|
||||||
<PathIcon
|
<PathIcon
|
||||||
Width="24"
|
Width="24"
|
||||||
Height="24"
|
Height="24"
|
||||||
Data="{StaticResource building_fit}"
|
Data="{StaticResource building_fit}"
|
||||||
Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
||||||
</SplitButton.Content>
|
</Button.Content>
|
||||||
<SplitButton.Flyout>
|
</Button>
|
||||||
<MenuFlyout>
|
|
||||||
<MenuItem Name="menuStorageUI" Header="{x:Static resx:ResUI.menuStorageUI}" />
|
|
||||||
</MenuFlyout>
|
|
||||||
</SplitButton.Flyout>
|
|
||||||
</SplitButton>
|
|
||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txtServerFilter"
|
x:Name="txtServerFilter"
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ namespace v2rayN.Desktop.Views
|
|||||||
menuSelectAll.Click += menuSelectAll_Click;
|
menuSelectAll.Click += menuSelectAll_Click;
|
||||||
btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;
|
btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;
|
||||||
txtServerFilter.KeyDown += TxtServerFilter_KeyDown;
|
txtServerFilter.KeyDown += TxtServerFilter_KeyDown;
|
||||||
menuStorageUI.Click += MenuStorageUI_Click;
|
|
||||||
lstProfiles.KeyDown += LstProfiles_KeyDown;
|
lstProfiles.KeyDown += LstProfiles_KeyDown;
|
||||||
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
|
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
|
||||||
lstProfiles.DoubleTapped += LstProfiles_DoubleTapped;
|
lstProfiles.DoubleTapped += LstProfiles_DoubleTapped;
|
||||||
@@ -91,6 +90,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
RestoreUI();
|
RestoreUI();
|
||||||
ViewModel?.RefreshServers();
|
ViewModel?.RefreshServers();
|
||||||
|
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void LstProfiles_Sorting(object? sender, DataGridColumnEventArgs e)
|
private async void LstProfiles_Sorting(object? sender, DataGridColumnEventArgs e)
|
||||||
@@ -324,11 +324,6 @@ namespace v2rayN.Desktop.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MenuStorageUI_Click(object? sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
StorageUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion Event
|
//#endregion Event
|
||||||
|
|
||||||
//#region UI
|
//#region UI
|
||||||
@@ -358,17 +353,14 @@ namespace v2rayN.Desktop.Views
|
|||||||
}
|
}
|
||||||
if (item.Name.ToLower().StartsWith("to"))
|
if (item.Name.ToLower().StartsWith("to"))
|
||||||
{
|
{
|
||||||
if (!_config.GuiItem.EnableStatistics)
|
item2.IsVisible = _config.GuiItem.EnableStatistics;
|
||||||
{
|
|
||||||
item2.IsVisible = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StorageUI()
|
private void StorageUI(string? n = null)
|
||||||
{
|
{
|
||||||
List<ColumnItem> lvColumnItem = new();
|
List<ColumnItem> lvColumnItem = new();
|
||||||
for (int k = 0; k < lstProfiles.Columns.Count; k++)
|
for (int k = 0; k < lstProfiles.Columns.Count; k++)
|
||||||
@@ -386,7 +378,6 @@ namespace v2rayN.Desktop.Views
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
_config.UiItem.MainColumnItem = lvColumnItem;
|
_config.UiItem.MainColumnItem = lvColumnItem;
|
||||||
ConfigHandler.SaveConfig(_config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion UI
|
//#endregion UI
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}"
|
Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}"
|
||||||
Width="900"
|
Width="900"
|
||||||
Height="700"
|
Height="600"
|
||||||
x:DataType="vms:RoutingRuleDetailsViewModel"
|
x:DataType="vms:RoutingRuleDetailsViewModel"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuRoutingRuleSetting}"
|
Title="{x:Static resx:ResUI.menuRoutingRuleSetting}"
|
||||||
Width="1000"
|
Width="900"
|
||||||
Height="700"
|
Height="600"
|
||||||
x:DataType="vms:RoutingRuleSettingViewModel"
|
x:DataType="vms:RoutingRuleSettingViewModel"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuRoutingSetting}"
|
Title="{x:Static resx:ResUI.menuRoutingSetting}"
|
||||||
Width="1000"
|
Width="900"
|
||||||
Height="700"
|
Height="600"
|
||||||
x:DataType="vms:RoutingSettingViewModel"
|
x:DataType="vms:RoutingSettingViewModel"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Width="240"
|
|
||||||
Margin="8,0"
|
Margin="8,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
DockPanel.Dock="Left">
|
DockPanel.Dock="Left">
|
||||||
@@ -34,7 +33,6 @@
|
|||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
x:Name="spEnableTun"
|
x:Name="spEnableTun"
|
||||||
Width="100"
|
|
||||||
Margin="8,0"
|
Margin="8,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
DockPanel.Dock="Left"
|
DockPanel.Dock="Left"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuSubSetting}"
|
Title="{x:Static resx:ResUI.menuSubSetting}"
|
||||||
Width="700"
|
Width="700"
|
||||||
Height="650"
|
Height="600"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuSubSetting}"
|
Title="{x:Static resx:ResUI.menuSubSetting}"
|
||||||
Width="1000"
|
Width="900"
|
||||||
Height="700"
|
Height="600"
|
||||||
x:DataType="vms:SubSettingViewModel"
|
x:DataType="vms:SubSettingViewModel"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.2.2" />
|
<PackageReference Include="Avalonia.ReactiveUI" Version="11.2.2" />
|
||||||
<PackageReference Include="DialogHost.Avalonia" Version="0.8.1" />
|
<PackageReference Include="DialogHost.Avalonia" Version="0.8.1" />
|
||||||
<PackageReference Include="MessageBox.Avalonia" Version="3.2.0" />
|
<PackageReference Include="MessageBox.Avalonia" Version="3.2.0" />
|
||||||
<PackageReference Include="Semi.Avalonia" Version="11.2.1.1" />
|
<PackageReference Include="Semi.Avalonia" Version="11.2.1.2" />
|
||||||
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.2.1.1" />
|
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.2.1.2" />
|
||||||
<PackageReference Include="ReactiveUI" Version="20.1.63" />
|
<PackageReference Include="ReactiveUI" Version="20.1.63" />
|
||||||
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ namespace v2rayN
|
|||||||
|
|
||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
// Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetCallingAssembly());
|
|
||||||
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
|
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
|
||||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||||
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace v2rayN.Views
|
|||||||
_config.GlobalHotkeys ??= new List<KeyEventItem>();
|
_config.GlobalHotkeys ??= new List<KeyEventItem>();
|
||||||
|
|
||||||
btnReset.Click += btnReset_Click;
|
btnReset.Click += btnReset_Click;
|
||||||
btnSave.Click += btnSave_Click;
|
btnSave.Click += btnSave_ClickAsync;
|
||||||
|
|
||||||
txtGlobalHotkey0.KeyDown += TxtGlobalHotkey_PreviewKeyDown;
|
txtGlobalHotkey0.KeyDown += TxtGlobalHotkey_PreviewKeyDown;
|
||||||
txtGlobalHotkey1.KeyDown += TxtGlobalHotkey_PreviewKeyDown;
|
txtGlobalHotkey1.KeyDown += TxtGlobalHotkey_PreviewKeyDown;
|
||||||
@@ -99,11 +99,11 @@ namespace v2rayN.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnSave_Click(object sender, RoutedEventArgs e)
|
private async void btnSave_ClickAsync(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_config.GlobalHotkeys = _TextBoxKeyEventItem.Values.ToList();
|
_config.GlobalHotkeys = _TextBoxKeyEventItem.Values.ToList();
|
||||||
|
|
||||||
if (ConfigHandler.SaveConfig(_config).Result == 0)
|
if (await ConfigHandler.SaveConfig(_config) == 0)
|
||||||
{
|
{
|
||||||
HotkeyHandler.Instance.ReLoad();
|
HotkeyHandler.Instance.ReLoad();
|
||||||
this.DialogResult = true;
|
this.DialogResult = true;
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ namespace v2rayN.Views
|
|||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
||||||
|
|
||||||
Application.Current.Exit += Current_Exit;
|
|
||||||
App.Current.SessionEnding += Current_SessionEnding;
|
App.Current.SessionEnding += Current_SessionEnding;
|
||||||
this.Closing += MainWindow_Closing;
|
this.Closing += MainWindow_Closing;
|
||||||
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
|
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
|
||||||
@@ -142,6 +141,7 @@ namespace v2rayN.Views
|
|||||||
RestoreUI();
|
RestoreUI();
|
||||||
AddHelpMenuItem();
|
AddHelpMenuItem();
|
||||||
WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
WindowsHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, null);
|
||||||
|
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Event
|
#region Event
|
||||||
@@ -265,11 +265,6 @@ namespace v2rayN.Views
|
|||||||
ShowHideWindow(false);
|
ShowHideWindow(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Current_Exit(object sender, ExitEventArgs e)
|
|
||||||
{
|
|
||||||
StorageUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void Current_SessionEnding(object sender, SessionEndingCancelEventArgs e)
|
private async void Current_SessionEnding(object sender, SessionEndingCancelEventArgs e)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("Current_SessionEnding");
|
Logging.SaveLog("Current_SessionEnding");
|
||||||
@@ -402,7 +397,7 @@ namespace v2rayN.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StorageUI()
|
private void StorageUI(string? n = null)
|
||||||
{
|
{
|
||||||
_config.UiItem.MainWidth = Utils.ToInt(this.Width);
|
_config.UiItem.MainWidth = Utils.ToInt(this.Width);
|
||||||
_config.UiItem.MainHeight = Utils.ToInt(this.Height);
|
_config.UiItem.MainHeight = Utils.ToInt(this.Height);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ namespace v2rayN.Views
|
|||||||
|
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
|
|
||||||
Application.Current.Exit += Current_Exit;
|
|
||||||
btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;
|
btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;
|
||||||
txtServerFilter.PreviewKeyDown += TxtServerFilter_PreviewKeyDown;
|
txtServerFilter.PreviewKeyDown += TxtServerFilter_PreviewKeyDown;
|
||||||
lstProfiles.PreviewKeyDown += LstProfiles_PreviewKeyDown;
|
lstProfiles.PreviewKeyDown += LstProfiles_PreviewKeyDown;
|
||||||
@@ -90,15 +89,11 @@ namespace v2rayN.Views
|
|||||||
|
|
||||||
RestoreUI();
|
RestoreUI();
|
||||||
ViewModel?.RefreshServers();
|
ViewModel?.RefreshServers();
|
||||||
|
MessageBus.Current.Listen<string>(EMsgCommand.AppExit.ToString()).Subscribe(StorageUI);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Event
|
#region Event
|
||||||
|
|
||||||
private void Current_Exit(object sender, ExitEventArgs e)
|
|
||||||
{
|
|
||||||
StorageUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||||
{
|
{
|
||||||
switch (action)
|
switch (action)
|
||||||
@@ -346,17 +341,14 @@ namespace v2rayN.Views
|
|||||||
}
|
}
|
||||||
if (item.Name.ToLower().StartsWith("to"))
|
if (item.Name.ToLower().StartsWith("to"))
|
||||||
{
|
{
|
||||||
if (!_config.GuiItem.EnableStatistics)
|
item2.Visibility = _config.GuiItem.EnableStatistics ? Visibility.Visible : Visibility.Hidden;
|
||||||
{
|
|
||||||
item2.Visibility = Visibility.Hidden;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StorageUI()
|
private void StorageUI(string? n = null)
|
||||||
{
|
{
|
||||||
List<ColumnItem> lvColumnItem = new();
|
List<ColumnItem> lvColumnItem = new();
|
||||||
for (int k = 0; k < lstProfiles.Columns.Count; k++)
|
for (int k = 0; k < lstProfiles.Columns.Count; k++)
|
||||||
@@ -370,7 +362,6 @@ namespace v2rayN.Views
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
_config.UiItem.MainColumnItem = lvColumnItem;
|
_config.UiItem.MainColumnItem = lvColumnItem;
|
||||||
ConfigHandler.SaveConfig(_config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion UI
|
#endregion UI
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Width="240"
|
Width="Auto"
|
||||||
Margin="{StaticResource MarginLeftRight8}"
|
Margin="{StaticResource MarginLeftRight8}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
DockPanel.Dock="Left">
|
DockPanel.Dock="Left">
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
x:Name="spEnableTun"
|
x:Name="spEnableTun"
|
||||||
Width="auto"
|
Width="Auto"
|
||||||
Margin="{StaticResource MarginLeftRight8}"
|
Margin="{StaticResource MarginLeftRight8}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
DockPanel.Dock="Left"
|
DockPanel.Dock="Left"
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="{StaticResource MarginLeftRight8}"
|
Margin="{StaticResource MarginLeftRight8}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource StatusbarItem}"
|
||||||
Text="{x:Static resx:ResUI.TbEnableTunAs}" />
|
Text="{x:Static resx:ResUI.TbEnableTunAs}" />
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
x:Name="togEnableTun"
|
x:Name="togEnableTun"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MaterialDesignThemes" Version="5.1.0" />
|
<PackageReference Include="MaterialDesignThemes" Version="5.1.0" />
|
||||||
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.1.4" />
|
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.2.0" />
|
||||||
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
||||||
<PackageReference Include="ReactiveUI.WPF" Version="20.1.63" />
|
<PackageReference Include="ReactiveUI.WPF" Version="20.1.63" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user