Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5dbce16895 | ||
|
|
1016dcb3d1 | ||
|
|
ba5ad12e13 | ||
|
|
57f9c8158e | ||
|
|
b8a0293b52 | ||
|
|
59b7daaef5 | ||
|
|
d781c768e9 | ||
|
|
04efed2079 | ||
|
|
2de9e14c7d | ||
|
|
a849dec6c2 | ||
|
|
28019dc511 | ||
|
|
9d638968a9 | ||
|
|
f921ff7d77 | ||
|
|
e3ea329795 | ||
|
|
87f1c129b6 | ||
|
|
a1c8bc0e61 | ||
|
|
61e9101851 | ||
|
|
a6289347cc | ||
|
|
9e84de8e76 | ||
|
|
d04cc53152 | ||
|
|
1ff3c5fc07 | ||
|
|
3db047a12f | ||
|
|
bf4615f2f2 | ||
|
|
798c7fad9a | ||
|
|
5797b37262 | ||
|
|
ce22f34cd6 | ||
|
|
4c49e52e26 | ||
|
|
47318b5d70 | ||
|
|
d12297909c | ||
|
|
5fb4edae2d | ||
|
|
c4b490e46d | ||
|
|
45febe3fff | ||
|
|
689a81a985 | ||
|
|
28620b385a | ||
|
|
be13446e69 | ||
|
|
ee57d5b8e6 | ||
|
|
4eda3dd8fa | ||
|
|
911dc7f90e | ||
|
|
18005b96e8 | ||
|
|
a3e45d206e | ||
|
|
0accf262dc | ||
|
|
e0eb73bb0a | ||
|
|
258e822c13 | ||
|
|
4f05b93d63 | ||
|
|
bb661d4f50 | ||
|
|
201cfaa922 | ||
|
|
c339aa349c | ||
|
|
046421f345 | ||
|
|
3a2c9e7aaa | ||
|
|
0bb6e6bd86 | ||
|
|
693e8ab157 | ||
|
|
033c16c992 | ||
|
|
6ec61433fb | ||
|
|
072f773245 | ||
|
|
0086f65a96 | ||
|
|
281f14f47e | ||
|
|
9fd20ff001 | ||
|
|
7df90a6034 | ||
|
|
019869ec28 | ||
|
|
b7f4fd7469 | ||
|
|
1273d2aee1 | ||
|
|
88990b4828 | ||
|
|
2f02c2970c | ||
|
|
ade789c6d4 |
@@ -1,5 +1,5 @@
|
|||||||
# v2rayN
|
# v2rayN
|
||||||
A GUI client for Windows, support [Xray core](https://github.com/XTLS/Xray-core) and [v2fly core](https://github.com/v2fly/v2ray-core) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
|
A GUI client for Windows and Linux, support [Xray core](https://github.com/XTLS/Xray-core) and [v2fly core](https://github.com/v2fly/v2ray-core) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
|
||||||
|
|
||||||
|
|
||||||
[](https://github.com/2dust/v2rayN/commits/master)
|
[](https://github.com/2dust/v2rayN/commits/master)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace AmazTool
|
|||||||
Console.WriteLine(fileName);
|
Console.WriteLine(fileName);
|
||||||
Console.WriteLine("In progress, please wait...(正在进行中,请等待)");
|
Console.WriteLine("In progress, please wait...(正在进行中,请等待)");
|
||||||
|
|
||||||
Thread.Sleep(5000);
|
Thread.Sleep(9000);
|
||||||
|
|
||||||
if (!File.Exists(fileName))
|
if (!File.Exists(fileName))
|
||||||
{
|
{
|
||||||
@@ -22,13 +22,13 @@ namespace AmazTool
|
|||||||
Console.WriteLine("Try to end the process(尝试结束进程).");
|
Console.WriteLine("Try to end the process(尝试结束进程).");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var path = GetPath(V2rayN);
|
|
||||||
Console.WriteLine(path);
|
|
||||||
var existing = Process.GetProcessesByName(V2rayN);
|
var existing = Process.GetProcessesByName(V2rayN);
|
||||||
var pp = existing.FirstOrDefault(p => p.MainModule?.FileName != null && p.MainModule?.FileName == path);
|
foreach (var pp in existing)
|
||||||
|
{
|
||||||
pp?.Kill();
|
pp?.Kill();
|
||||||
pp?.WaitForExit(1000);
|
pp?.WaitForExit(1000);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Access may be denied without admin right. The user may not be an administrator.
|
// Access may be denied without admin right. The user may not be an administrator.
|
||||||
@@ -54,6 +54,8 @@ namespace AmazTool
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(entry.FullName);
|
||||||
|
|
||||||
var lst = entry.FullName.Split(splitKey);
|
var lst = entry.FullName.Split(splitKey);
|
||||||
if (lst.Length == 1) continue;
|
if (lst.Length == 1) continue;
|
||||||
string fullName = string.Join(splitKey, lst[1..lst.Length]);
|
string fullName = string.Join(splitKey, lst[1..lst.Length]);
|
||||||
@@ -78,12 +80,12 @@ namespace AmazTool
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Upgrade Failed(升级失败)." + ex.StackTrace);
|
Console.WriteLine("Upgrade Failed(升级失败)." + ex.StackTrace);
|
||||||
return;
|
//return;
|
||||||
}
|
}
|
||||||
if (sb.Length > 0)
|
if (sb.Length > 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Upgrade Failed(升级失败)." + sb.ToString());
|
Console.WriteLine("Upgrade Failed(升级失败)." + sb.ToString());
|
||||||
return;
|
//return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Start v2rayN, please wait...(正在重启,请等待)");
|
Console.WriteLine("Start v2rayN, please wait...(正在重启,请等待)");
|
||||||
@@ -92,6 +94,7 @@ namespace AmazTool
|
|||||||
{
|
{
|
||||||
StartInfo = new()
|
StartInfo = new()
|
||||||
{
|
{
|
||||||
|
UseShellExecute = true,
|
||||||
FileName = V2rayN,
|
FileName = V2rayN,
|
||||||
WorkingDirectory = StartupPath()
|
WorkingDirectory = StartupPath()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ public class PacHandler
|
|||||||
private static int _httpPort;
|
private static int _httpPort;
|
||||||
private static int _pacPort;
|
private static int _pacPort;
|
||||||
private static TcpListener? _tcpListener;
|
private static TcpListener? _tcpListener;
|
||||||
private static string _pacText;
|
private static byte[] _writeContent;
|
||||||
private static bool _isRunning;
|
private static bool _isRunning;
|
||||||
private static bool _needRestart = true;
|
private static bool _needRestart = true;
|
||||||
|
|
||||||
public static void Start(string configPath, int httpPort, int pacPort)
|
public static async Task Start(string configPath, int httpPort, int pacPort)
|
||||||
{
|
{
|
||||||
_needRestart = (configPath != _configPath || httpPort != _httpPort || pacPort != _pacPort || !_isRunning);
|
_needRestart = (configPath != _configPath || httpPort != _httpPort || pacPort != _pacPort || !_isRunning);
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ public class PacHandler
|
|||||||
_httpPort = httpPort;
|
_httpPort = httpPort;
|
||||||
_pacPort = pacPort;
|
_pacPort = pacPort;
|
||||||
|
|
||||||
InitText();
|
await InitText();
|
||||||
|
|
||||||
if (_needRestart)
|
if (_needRestart)
|
||||||
{
|
{
|
||||||
@@ -32,15 +32,24 @@ public class PacHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InitText()
|
private static async Task InitText()
|
||||||
{
|
{
|
||||||
var path = Path.Combine(_configPath, "pac.txt");
|
var path = Path.Combine(_configPath, "pac.txt");
|
||||||
if (!File.Exists(path))
|
if (!File.Exists(path))
|
||||||
{
|
{
|
||||||
File.AppendAllText(path, Resources.ResourceManager.GetString("pac"));
|
await File.AppendAllTextAsync(path, Resources.ResourceManager.GetString("pac"));
|
||||||
}
|
}
|
||||||
|
|
||||||
_pacText = File.ReadAllText(path).Replace("__PROXY__", $"PROXY 127.0.0.1:{_httpPort};DIRECT;");
|
var pacText = (await File.ReadAllTextAsync(path)).Replace("__PROXY__", $"PROXY 127.0.0.1:{_httpPort};DIRECT;");
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine("HTTP/1.0 200 OK");
|
||||||
|
sb.AppendLine("Content-type:application/x-ns-proxy-autoconfig");
|
||||||
|
sb.AppendLine("Connection:close");
|
||||||
|
sb.AppendLine("Content-Length:" + Encoding.UTF8.GetByteCount(pacText));
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.Append(pacText);
|
||||||
|
_writeContent = Encoding.UTF8.GetBytes(sb.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RunListener()
|
private static void RunListener()
|
||||||
@@ -60,21 +69,8 @@ public class PacHandler
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var client = _tcpListener.AcceptTcpClient();
|
var client = await _tcpListener.AcceptTcpClientAsync();
|
||||||
await Task.Run(() =>
|
await Task.Run(() => { WriteContent(client); });
|
||||||
{
|
|
||||||
var stream = client.GetStream();
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine("HTTP/1.0 200 OK");
|
|
||||||
sb.AppendLine("Content-type:application/x-ns-proxy-autoconfig");
|
|
||||||
sb.AppendLine("Connection:close");
|
|
||||||
sb.AppendLine("Content-Length:" + Encoding.UTF8.GetByteCount(_pacText));
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.Append(_pacText);
|
|
||||||
var content = Encoding.UTF8.GetBytes(sb.ToString());
|
|
||||||
stream.Write(content, 0, content.Length);
|
|
||||||
stream.Flush();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -84,6 +80,13 @@ public class PacHandler
|
|||||||
}, TaskCreationOptions.LongRunning);
|
}, TaskCreationOptions.LongRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void WriteContent(TcpClient client)
|
||||||
|
{
|
||||||
|
var stream = client.GetStream();
|
||||||
|
stream.Write(_writeContent, 0, _writeContent.Length);
|
||||||
|
stream.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
public static void Stop()
|
public static void Stop()
|
||||||
{
|
{
|
||||||
if (_tcpListener == null) return;
|
if (_tcpListener == null) return;
|
||||||
|
|||||||
75
v2rayN/ServiceLib/Common/DesUtils.cs
Normal file
75
v2rayN/ServiceLib/Common/DesUtils.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace ServiceLib.Common
|
||||||
|
{
|
||||||
|
public class DesUtils
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Encrypt
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// /// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string Encrypt(string? text, string? key = null)
|
||||||
|
{
|
||||||
|
if (text.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
GetKeyIv(key ?? GetDefaultKey(), out var rgbKey, out var rgbIv);
|
||||||
|
var dsp = DES.Create();
|
||||||
|
using var memStream = new MemoryStream();
|
||||||
|
using var cryStream = new CryptoStream(memStream, dsp.CreateEncryptor(rgbKey, rgbIv), CryptoStreamMode.Write);
|
||||||
|
using var sWriter = new StreamWriter(cryStream);
|
||||||
|
sWriter.Write(text);
|
||||||
|
sWriter.Flush();
|
||||||
|
cryStream.FlushFinalBlock();
|
||||||
|
memStream.Flush();
|
||||||
|
return Convert.ToBase64String(memStream.GetBuffer(), 0, (int)memStream.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decrypt
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="encryptText"></param>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string Decrypt(string? encryptText, string? key = null)
|
||||||
|
{
|
||||||
|
if (encryptText.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
GetKeyIv(key ?? GetDefaultKey(), out var rgbKey, out var rgbIv);
|
||||||
|
var dsp = DES.Create();
|
||||||
|
var buffer = Convert.FromBase64String(encryptText);
|
||||||
|
|
||||||
|
using var memStream = new MemoryStream();
|
||||||
|
using var cryStream = new CryptoStream(memStream, dsp.CreateDecryptor(rgbKey, rgbIv), CryptoStreamMode.Write);
|
||||||
|
cryStream.Write(buffer, 0, buffer.Length);
|
||||||
|
cryStream.FlushFinalBlock();
|
||||||
|
return Encoding.UTF8.GetString(memStream.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GetKeyIv(string key, out byte[] rgbKey, out byte[] rgbIv)
|
||||||
|
{
|
||||||
|
if (key.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("The key cannot be null");
|
||||||
|
}
|
||||||
|
if (key.Length <= 8)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("The key length cannot be less than 8 characters.");
|
||||||
|
}
|
||||||
|
|
||||||
|
rgbKey = Encoding.ASCII.GetBytes(key.Substring(0, 8));
|
||||||
|
rgbIv = Encoding.ASCII.GetBytes(key.Insert(0, "w").Substring(0, 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetDefaultKey()
|
||||||
|
{
|
||||||
|
return Utils.GetMd5(Utils.GetHomePath() + "DesUtils");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.Mime;
|
using System.Net.Mime;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ namespace ServiceLib.Common
|
|||||||
totalRead += read;
|
totalRead += read;
|
||||||
|
|
||||||
if (read == 0) break;
|
if (read == 0) break;
|
||||||
await file.WriteAsync(buffer, 0, read, token);
|
await file.WriteAsync(buffer.AsMemory(0, read), token);
|
||||||
|
|
||||||
if (canReportProgress)
|
if (canReportProgress)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,33 +37,35 @@ namespace ServiceLib.Common
|
|||||||
foreach (var filePath in files)
|
foreach (var filePath in files)
|
||||||
{
|
{
|
||||||
var file = new FileInfo(filePath);
|
var file = new FileInfo(filePath);
|
||||||
if (file.CreationTime < now)
|
if (file.CreationTime >= now) continue;
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
file.Delete();
|
file.Delete();
|
||||||
}
|
}
|
||||||
catch { }
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SaveLog(string strContent)
|
public static void SaveLog(string strContent)
|
||||||
{
|
{
|
||||||
if (LogManager.IsLoggingEnabled())
|
if (!LogManager.IsLoggingEnabled()) return;
|
||||||
{
|
|
||||||
var logger = LogManager.GetLogger("Log1");
|
LogManager.GetLogger("Log1").Info(strContent);
|
||||||
logger.Info(strContent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SaveLog(string strTitle, Exception ex)
|
public static void SaveLog(string strTitle, Exception ex)
|
||||||
{
|
{
|
||||||
if (LogManager.IsLoggingEnabled())
|
if (!LogManager.IsLoggingEnabled()) return;
|
||||||
{
|
|
||||||
var logger = LogManager.GetLogger("Log2");
|
var logger = LogManager.GetLogger("Log2");
|
||||||
logger.Debug($"{strTitle},{ex.Message}");
|
logger.Debug($"{strTitle},{ex.Message}");
|
||||||
logger.Debug(ex.StackTrace);
|
logger.Debug(ex.StackTrace);
|
||||||
@@ -74,4 +76,3 @@ namespace ServiceLib.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using CliWrap;
|
using CliWrap;
|
||||||
using CliWrap.Buffered;
|
using CliWrap.Buffered;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -38,6 +38,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +94,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,6 +119,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +141,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +161,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Logging.SaveLog("Base64Encode", ex);
|
Logging.SaveLog("Base64Encode", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +185,7 @@ namespace ServiceLib.Common
|
|||||||
|
|
||||||
if (plainText.Length % 4 > 0)
|
if (plainText.Length % 4 > 0)
|
||||||
{
|
{
|
||||||
plainText = plainText.PadRight(plainText.Length + 4 - plainText.Length % 4, '=');
|
plainText = plainText.PadRight(plainText.Length + 4 - (plainText.Length % 4), '=');
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = Convert.FromBase64String(plainText);
|
var data = Convert.FromBase64String(plainText);
|
||||||
@@ -189,6 +195,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Logging.SaveLog("Base64Decode", ex);
|
Logging.SaveLog("Base64Decode", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,14 +258,17 @@ namespace ServiceLib.Common
|
|||||||
unit = "TB";
|
unit = "TB";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = GBs + ((MBs % factor) / (factor + 0.0));
|
result = GBs + ((MBs % factor) / (factor + 0.0));
|
||||||
unit = "GB";
|
unit = "GB";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = MBs + ((KBs % factor) / (factor + 0.0));
|
result = MBs + ((KBs % factor) / (factor + 0.0));
|
||||||
unit = "MB";
|
unit = "MB";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = KBs + ((amount % factor) / (factor + 0.0));
|
result = KBs + ((amount % factor) / (factor + 0.0));
|
||||||
unit = "KB";
|
unit = "KB";
|
||||||
return;
|
return;
|
||||||
@@ -302,6 +312,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = Uri.UnescapeDataString(keyValue[0]);
|
var key = Uri.UnescapeDataString(keyValue[0]);
|
||||||
var val = Uri.UnescapeDataString(keyValue[1]);
|
var val = Uri.UnescapeDataString(keyValue[1]);
|
||||||
|
|
||||||
@@ -323,6 +334,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
sb.Append(b.ToString("x2"));
|
sb.Append(b.ToString("x2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,6 +349,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Uri uri = new(url);
|
Uri uri = new(url);
|
||||||
@@ -368,6 +381,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
return text.Replace(",", ",").Replace(Environment.NewLine, ",");
|
return text.Replace(",", ",").Replace(Environment.NewLine, ",");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,6 +405,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return text == "null";
|
return text == "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,6 +439,7 @@ namespace ServiceLib.Common
|
|||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,6 +464,7 @@ namespace ServiceLib.Common
|
|||||||
if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31) return true;
|
if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31) return true;
|
||||||
if (ipBytes[0] == 192 && ipBytes[1] == 168) return true;
|
if (ipBytes[0] == 192 && ipBytes[1] == 168) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,6 +485,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,6 +507,7 @@ namespace ServiceLib.Common
|
|||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
return 59090;
|
return 59090;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,7 +531,8 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
if (blFull)
|
if (blFull)
|
||||||
{
|
{
|
||||||
return $"{Global.AppName} - V{GetVersionInfo()} - {RuntimeInformation.ProcessArchitecture} - {File.GetLastWriteTime(GetExePath()):yyyy/MM/dd}";
|
return
|
||||||
|
$"{Global.AppName} - V{GetVersionInfo()} - {RuntimeInformation.ProcessArchitecture} - {File.GetLastWriteTime(GetExePath()):yyyy/MM/dd}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -523,6 +543,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Global.AppName;
|
return Global.AppName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,6 +581,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,7 +594,11 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (fileName.IsNullOrEmpty()) { return; }
|
if (fileName.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Process.Start(new ProcessStartInfo(fileName, arguments) { UseShellExecute = true });
|
Process.Start(new ProcessStartInfo(fileName, arguments) { UseShellExecute = true });
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -605,6 +631,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return systemHosts;
|
return systemHosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,17 +656,20 @@ namespace ServiceLib.Common
|
|||||||
cmd = cmd.WithArguments(args);
|
cmd = cmd.WithArguments(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await cmd.ExecuteBufferedAsync();
|
var result = await cmd.ExecuteBufferedAsync();
|
||||||
if (result.IsSuccess)
|
if (result.IsSuccess)
|
||||||
{
|
{
|
||||||
return result.StandardOutput.ToString();
|
return result.StandardOutput.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.SaveLog(result.ToString() ?? "");
|
Logging.SaveLog(result.ToString() ?? "");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("GetCliWrapOutput", ex);
|
Logging.SaveLog("GetCliWrapOutput", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,6 +684,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
return startupPath;
|
return startupPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Path.Combine(startupPath, fileName);
|
return Path.Combine(startupPath, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,6 +705,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(tempPath);
|
Directory.CreateDirectory(tempPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsNullOrEmpty(filename))
|
if (IsNullOrEmpty(filename))
|
||||||
{
|
{
|
||||||
return tempPath;
|
return tempPath;
|
||||||
@@ -691,6 +723,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(tempPath);
|
Directory.CreateDirectory(tempPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Path.Combine(tempPath, filename);
|
return Path.Combine(tempPath, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,6 +734,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(tempPath);
|
Directory.CreateDirectory(tempPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(filename))
|
if (Utils.IsNullOrEmpty(filename))
|
||||||
{
|
{
|
||||||
return tempPath;
|
return tempPath;
|
||||||
@@ -718,6 +752,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(tempPath);
|
Directory.CreateDirectory(tempPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coreType != null)
|
if (coreType != null)
|
||||||
{
|
{
|
||||||
tempPath = Path.Combine(tempPath, coreType.ToLower().ToString());
|
tempPath = Path.Combine(tempPath, coreType.ToLower().ToString());
|
||||||
@@ -726,6 +761,7 @@ namespace ServiceLib.Common
|
|||||||
Directory.CreateDirectory(tempPath);
|
Directory.CreateDirectory(tempPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsNullOrEmpty(filename))
|
if (IsNullOrEmpty(filename))
|
||||||
{
|
{
|
||||||
return tempPath;
|
return tempPath;
|
||||||
@@ -743,6 +779,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(tempPath);
|
Directory.CreateDirectory(tempPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(filename))
|
if (Utils.IsNullOrEmpty(filename))
|
||||||
{
|
{
|
||||||
return tempPath;
|
return tempPath;
|
||||||
@@ -760,6 +797,7 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(tempPath);
|
Directory.CreateDirectory(tempPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(filename))
|
if (Utils.IsNullOrEmpty(filename))
|
||||||
{
|
{
|
||||||
return tempPath;
|
return tempPath;
|
||||||
@@ -818,6 +856,20 @@ namespace ServiceLib.Common
|
|||||||
return await GetCliWrapOutput("/bin/bash", arg);
|
return await GetCliWrapOutput("/bin/bash", arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<string?> GetLinuxFontFamily(string lang)
|
||||||
|
{
|
||||||
|
// var arg = new List<string>() { "-c", $"fc-list :lang={lang} family" };
|
||||||
|
var arg = new List<string>() { "-c", $"fc-list : family" };
|
||||||
|
return await GetCliWrapOutput("/bin/bash", arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string? GetHomePath()
|
||||||
|
{
|
||||||
|
return IsWindows()
|
||||||
|
? Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%")
|
||||||
|
: Environment.GetEnvironmentVariable("HOME");
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Platform
|
#endregion Platform
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
52
v2rayN/ServiceLib/Common/WindowsUtils.cs
Normal file
52
v2rayN/ServiceLib/Common/WindowsUtils.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
|
namespace ServiceLib.Common
|
||||||
|
{
|
||||||
|
internal static class WindowsUtils
|
||||||
|
{
|
||||||
|
public static string? RegReadValue(string path, string name, string def)
|
||||||
|
{
|
||||||
|
RegistryKey? regKey = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
regKey = Registry.CurrentUser.OpenSubKey(path, false);
|
||||||
|
var value = regKey?.GetValue(name) as string;
|
||||||
|
return Utils.IsNullOrEmpty(value) ? def : value;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(ex.Message, ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
regKey?.Close();
|
||||||
|
}
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RegWriteValue(string path, string name, object value)
|
||||||
|
{
|
||||||
|
RegistryKey? regKey = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
regKey = Registry.CurrentUser.CreateSubKey(path);
|
||||||
|
if (Utils.IsNullOrEmpty(value.ToString()))
|
||||||
|
{
|
||||||
|
regKey?.DeleteValue(name, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regKey?.SetValue(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(ex.Message, ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
regKey?.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,12 +4,8 @@
|
|||||||
{
|
{
|
||||||
v2fly = 1,
|
v2fly = 1,
|
||||||
Xray = 2,
|
Xray = 2,
|
||||||
|
|
||||||
//SagerNet = 3,
|
|
||||||
v2fly_v5 = 4,
|
v2fly_v5 = 4,
|
||||||
|
|
||||||
//clash = 11,
|
|
||||||
//clash_meta = 12,
|
|
||||||
mihomo = 13,
|
mihomo = 13,
|
||||||
|
|
||||||
hysteria = 21,
|
hysteria = 21,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
ClearMsg,
|
ClearMsg,
|
||||||
SendMsgView,
|
SendMsgView,
|
||||||
SendSnackMsg,
|
SendSnackMsg,
|
||||||
RefreshProfiles
|
RefreshProfiles,
|
||||||
|
StopSpeedtest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
ws,
|
ws,
|
||||||
httpupgrade,
|
httpupgrade,
|
||||||
splithttp,
|
splithttp,
|
||||||
|
xhttp,
|
||||||
h2,
|
h2,
|
||||||
http,
|
http,
|
||||||
quic,
|
quic,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
Shutdown,
|
Shutdown,
|
||||||
BrowseServer,
|
BrowseServer,
|
||||||
ImportRulesFromFile,
|
ImportRulesFromFile,
|
||||||
|
InitSettingFont,
|
||||||
SubEditWindow,
|
SubEditWindow,
|
||||||
RoutingRuleSettingWindow,
|
RoutingRuleSettingWindow,
|
||||||
RoutingRuleDetailsWindow,
|
RoutingRuleDetailsWindow,
|
||||||
|
|||||||
@@ -28,21 +28,24 @@
|
|||||||
public const string CoreSpeedtestConfigFileName = "configSpeedtest.json";
|
public const string CoreSpeedtestConfigFileName = "configSpeedtest.json";
|
||||||
public const string CoreMultipleLoadConfigFileName = "configMultipleLoad.json";
|
public const string CoreMultipleLoadConfigFileName = "configMultipleLoad.json";
|
||||||
public const string ClashMixinConfigFileName = "Mixin.yaml";
|
public const string ClashMixinConfigFileName = "Mixin.yaml";
|
||||||
public const string V2raySampleClient = "ServiceLib.Sample.SampleClientConfig";
|
|
||||||
public const string SingboxSampleClient = "ServiceLib.Sample.SingboxSampleClientConfig";
|
public const string NamespaceSample = "ServiceLib.Sample.";
|
||||||
public const string V2raySampleHttpRequestFileName = "ServiceLib.Sample.SampleHttpRequest";
|
public const string V2raySampleClient = NamespaceSample + "SampleClientConfig";
|
||||||
public const string V2raySampleHttpResponseFileName = "ServiceLib.Sample.SampleHttpResponse";
|
public const string SingboxSampleClient = NamespaceSample + "SingboxSampleClientConfig";
|
||||||
public const string V2raySampleInbound = "ServiceLib.Sample.SampleInbound";
|
public const string V2raySampleHttpRequestFileName = NamespaceSample + "SampleHttpRequest";
|
||||||
public const string V2raySampleOutbound = "ServiceLib.Sample.SampleOutbound";
|
public const string V2raySampleHttpResponseFileName = NamespaceSample + "SampleHttpResponse";
|
||||||
public const string SingboxSampleOutbound = "ServiceLib.Sample.SingboxSampleOutbound";
|
public const string V2raySampleInbound = NamespaceSample + "SampleInbound";
|
||||||
public const string CustomRoutingFileName = "ServiceLib.Sample.custom_routing_";
|
public const string V2raySampleOutbound = NamespaceSample + "SampleOutbound";
|
||||||
public const string TunSingboxDNSFileName = "ServiceLib.Sample.tun_singbox_dns";
|
public const string SingboxSampleOutbound = NamespaceSample + "SingboxSampleOutbound";
|
||||||
public const string TunSingboxInboundFileName = "ServiceLib.Sample.tun_singbox_inbound";
|
public const string CustomRoutingFileName = NamespaceSample + "custom_routing_";
|
||||||
public const string TunSingboxRulesFileName = "ServiceLib.Sample.tun_singbox_rules";
|
public const string TunSingboxDNSFileName = NamespaceSample + "tun_singbox_dns";
|
||||||
public const string DNSV2rayNormalFileName = "ServiceLib.Sample.dns_v2ray_normal";
|
public const string TunSingboxInboundFileName = NamespaceSample + "tun_singbox_inbound";
|
||||||
public const string DNSSingboxNormalFileName = "ServiceLib.Sample.dns_singbox_normal";
|
public const string TunSingboxRulesFileName = NamespaceSample + "tun_singbox_rules";
|
||||||
public const string ClashMixinYaml = "ServiceLib.Sample.clash_mixin_yaml";
|
public const string DNSV2rayNormalFileName = NamespaceSample + "dns_v2ray_normal";
|
||||||
public const string ClashTunYaml = "ServiceLib.Sample.clash_tun_yaml";
|
public const string DNSSingboxNormalFileName = NamespaceSample + "dns_singbox_normal";
|
||||||
|
public const string ClashMixinYaml = NamespaceSample + "clash_mixin_yaml";
|
||||||
|
public const string ClashTunYaml = NamespaceSample + "clash_tun_yaml";
|
||||||
|
public const string LinuxAutostartConfig = NamespaceSample + "linux_autostart_config";
|
||||||
|
|
||||||
public const string DefaultSecurity = "auto";
|
public const string DefaultSecurity = "auto";
|
||||||
public const string DefaultNetwork = "tcp";
|
public const string DefaultNetwork = "tcp";
|
||||||
@@ -102,9 +105,9 @@
|
|||||||
|
|
||||||
public static readonly List<string> SpeedTestUrls = new() {
|
public static readonly List<string> SpeedTestUrls = new() {
|
||||||
@"https://speed.cloudflare.com/__down?bytes=100000000",
|
@"https://speed.cloudflare.com/__down?bytes=100000000",
|
||||||
|
@"https://speed.cloudflare.com/__down?bytes=50000000",
|
||||||
@"https://speed.cloudflare.com/__down?bytes=10000000",
|
@"https://speed.cloudflare.com/__down?bytes=10000000",
|
||||||
@"http://cachefly.cachefly.net/50mb.test",
|
@"https://cachefly.cachefly.net/50mb.test",
|
||||||
@"http://cachefly.cachefly.net/10mb.test"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly List<string> SpeedPingTestUrls = new() {
|
public static readonly List<string> SpeedPingTestUrls = new() {
|
||||||
@@ -172,11 +175,10 @@
|
|||||||
|
|
||||||
public static readonly List<string> VmessSecurities = new() { "aes-128-gcm", "chacha20-poly1305", "auto", "none", "zero" };
|
public static readonly List<string> VmessSecurities = new() { "aes-128-gcm", "chacha20-poly1305", "auto", "none", "zero" };
|
||||||
public static readonly List<string> SsSecurities = new() { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "none", "plain" };
|
public static readonly List<string> SsSecurities = new() { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "none", "plain" };
|
||||||
public static readonly List<string> SsSecuritiesInSagerNet = new() { "none", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "rc4", "rc4-md5", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-cfb8", "aes-192-cfb8", "aes-256-cfb8", "aes-128-ofb", "aes-192-ofb", "aes-256-ofb", "bf-cfb", "cast5-cfb", "des-cfb", "idea-cfb", "rc2-cfb", "seed-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb", "camellia-128-cfb8", "camellia-192-cfb8", "camellia-256-cfb8", "salsa20", "chacha20", "chacha20-ietf", "xchacha20" };
|
|
||||||
public static readonly List<string> SsSecuritiesInXray = new() { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "xchacha20-poly1305", "xchacha20-ietf-poly1305", "none", "plain", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" };
|
public static readonly List<string> SsSecuritiesInXray = new() { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "xchacha20-poly1305", "xchacha20-ietf-poly1305", "none", "plain", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" };
|
||||||
public static readonly List<string> SsSecuritiesInSingbox = new() { "aes-256-gcm", "aes-192-gcm", "aes-128-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "none", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "rc4-md5", "chacha20-ietf", "xchacha20" };
|
public static readonly List<string> SsSecuritiesInSingbox = new() { "aes-256-gcm", "aes-192-gcm", "aes-128-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "none", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "rc4-md5", "chacha20-ietf", "xchacha20" };
|
||||||
public static readonly List<string> Flows = new() { "", "xtls-rprx-vision", "xtls-rprx-vision-udp443" };
|
public static readonly List<string> Flows = new() { "", "xtls-rprx-vision", "xtls-rprx-vision-udp443" };
|
||||||
public static readonly List<string> Networks = new() { "tcp", "kcp", "ws", "httpupgrade", "splithttp", "h2", "quic", "grpc" };
|
public static readonly List<string> Networks = new() { "tcp", "kcp", "ws", "httpupgrade", "xhttp", "splithttp", "h2", "quic", "grpc" };
|
||||||
public static readonly List<string> KcpHeaderTypes = new() { "srtp", "utp", "wechat-video", "dtls", "wireguard" };
|
public static readonly List<string> KcpHeaderTypes = new() { "srtp", "utp", "wechat-video", "dtls", "wireguard" };
|
||||||
public static readonly List<string> CoreTypes = new() { "v2fly", "Xray", "sing_box" };
|
public static readonly List<string> CoreTypes = new() { "v2fly", "Xray", "sing_box" };
|
||||||
public static readonly List<string> CoreTypes4VLESS = new() { "Xray", "sing_box" };
|
public static readonly List<string> CoreTypes4VLESS = new() { "Xray", "sing_box" };
|
||||||
@@ -185,6 +187,7 @@
|
|||||||
public static readonly List<string> DomainMatchers = new() { "linear", "mph", "" };
|
public static readonly List<string> DomainMatchers = new() { "linear", "mph", "" };
|
||||||
public static readonly List<string> Fingerprints = new() { "chrome", "firefox", "safari", "ios", "android", "edge", "360", "qq", "random", "randomized", "" };
|
public static readonly List<string> Fingerprints = new() { "chrome", "firefox", "safari", "ios", "android", "edge", "360", "qq", "random", "randomized", "" };
|
||||||
public static readonly List<string> UserAgent = new() { "chrome", "firefox", "safari", "edge", "none" };
|
public static readonly List<string> UserAgent = new() { "chrome", "firefox", "safari", "edge", "none" };
|
||||||
|
public static readonly List<string> XhttpMode = new() { "auto", "packet-up", "stream-up" };
|
||||||
|
|
||||||
public static readonly List<string> AllowInsecure = new() { "true", "false", "" };
|
public static readonly List<string> AllowInsecure = new() { "true", "false", "" };
|
||||||
public static readonly List<string> DomainStrategy4Freedoms = new() { "AsIs", "UseIP", "UseIPv4", "UseIPv6", "" };
|
public static readonly List<string> DomainStrategy4Freedoms = new() { "AsIs", "UseIP", "UseIPv4", "UseIPv6", "" };
|
||||||
@@ -204,9 +207,9 @@
|
|||||||
public static readonly List<string> SingboxMuxs = new() { "h2mux", "smux", "yamux", "" };
|
public static readonly List<string> SingboxMuxs = new() { "h2mux", "smux", "yamux", "" };
|
||||||
public static readonly List<string> TuicCongestionControls = new() { "cubic", "new_reno", "bbr" };
|
public static readonly List<string> TuicCongestionControls = new() { "cubic", "new_reno", "bbr" };
|
||||||
|
|
||||||
public static readonly List<string> allowSelectType = new List<string> { "selector", "urltest", "loadbalance", "fallback" };
|
public static readonly List<string> allowSelectType = new() { "selector", "urltest", "loadbalance", "fallback" };
|
||||||
public static readonly List<string> notAllowTestType = new List<string> { "selector", "urltest", "direct", "reject", "compatible", "pass", "loadbalance", "fallback" };
|
public static readonly List<string> notAllowTestType = new() { "selector", "urltest", "direct", "reject", "compatible", "pass", "loadbalance", "fallback" };
|
||||||
public static readonly List<string> proxyVehicleType = new List<string> { "file", "http" };
|
public static readonly List<string> proxyVehicleType = new() { "file", "http" };
|
||||||
|
|
||||||
#endregion const
|
#endregion const
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
public bool InitComponents()
|
public bool InitComponents()
|
||||||
{
|
{
|
||||||
Logging.Setup();
|
Logging.Setup();
|
||||||
Logging.LoggingEnabled(true);
|
Logging.LoggingEnabled(_config.GuiItem.EnableLog);
|
||||||
Logging.SaveLog($"v2rayN start up | {Utils.GetVersion()} | {Utils.GetExePath()}");
|
Logging.SaveLog($"v2rayN start up | {Utils.GetVersion()} | {Utils.GetExePath()}");
|
||||||
Logging.SaveLog($"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
|
Logging.SaveLog($"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
|
||||||
Logging.ClearLogs();
|
Logging.ClearLogs();
|
||||||
@@ -247,7 +247,7 @@
|
|||||||
case ECoreType.sing_box:
|
case ECoreType.sing_box:
|
||||||
return Global.SsSecuritiesInSingbox;
|
return Global.SsSecuritiesInSingbox;
|
||||||
}
|
}
|
||||||
return Global.SsSecuritiesInSagerNet;
|
return Global.SsSecuritiesInSingbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ECoreType GetCoreType(ProfileItem profileItem, EConfigType eConfigType)
|
public ECoreType GetCoreType(ProfileItem profileItem, EConfigType eConfigType)
|
||||||
|
|||||||
155
v2rayN/ServiceLib/Handler/AutoStartupHandler.cs
Normal file
155
v2rayN/ServiceLib/Handler/AutoStartupHandler.cs
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
using System.Security.Principal;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace ServiceLib.Handler
|
||||||
|
{
|
||||||
|
public static class AutoStartupHandler
|
||||||
|
{
|
||||||
|
public static async Task<bool> UpdateTask(Config config)
|
||||||
|
{
|
||||||
|
if (Utils.IsWindows())
|
||||||
|
{
|
||||||
|
await ClearTaskWindows();
|
||||||
|
|
||||||
|
if (config.GuiItem.AutoRun)
|
||||||
|
{
|
||||||
|
await SetTaskWindows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Utils.IsLinux())
|
||||||
|
{
|
||||||
|
await ClearTaskLinux();
|
||||||
|
|
||||||
|
if (config.GuiItem.AutoRun)
|
||||||
|
{
|
||||||
|
await SetTaskLinux();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows
|
||||||
|
|
||||||
|
private static async Task ClearTaskWindows()
|
||||||
|
{
|
||||||
|
var autoRunName = GetAutoRunNameWindows();
|
||||||
|
WindowsUtils.RegWriteValue(Global.AutoRunRegPath, autoRunName, "");
|
||||||
|
if (Utils.IsAdministrator())
|
||||||
|
{
|
||||||
|
AutoStartTaskService(autoRunName, "", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task SetTaskWindows()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var autoRunName = GetAutoRunNameWindows();
|
||||||
|
var exePath = Utils.GetExePath();
|
||||||
|
if (Utils.IsAdministrator())
|
||||||
|
{
|
||||||
|
AutoStartTaskService(autoRunName, exePath, "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WindowsUtils.RegWriteValue(Global.AutoRunRegPath, autoRunName, exePath.AppendQuotes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(ex.Message, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Auto Start via TaskService
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="taskName"></param>
|
||||||
|
/// <param name="fileName"></param>
|
||||||
|
/// <param name="description"></param>
|
||||||
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
|
public static void AutoStartTaskService(string taskName, string fileName, string description)
|
||||||
|
{
|
||||||
|
if (Utils.IsNullOrEmpty(taskName))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var logonUser = WindowsIdentity.GetCurrent().Name;
|
||||||
|
using var taskService = new Microsoft.Win32.TaskScheduler.TaskService();
|
||||||
|
var tasks = taskService.RootFolder.GetTasks(new Regex(taskName));
|
||||||
|
if (Utils.IsNullOrEmpty(fileName))
|
||||||
|
{
|
||||||
|
foreach (var t in tasks)
|
||||||
|
{
|
||||||
|
taskService.RootFolder.DeleteTask(t.Name);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var task = taskService.NewTask();
|
||||||
|
task.RegistrationInfo.Description = description;
|
||||||
|
task.Settings.DisallowStartIfOnBatteries = false;
|
||||||
|
task.Settings.StopIfGoingOnBatteries = false;
|
||||||
|
task.Settings.RunOnlyIfIdle = false;
|
||||||
|
task.Settings.IdleSettings.StopOnIdleEnd = false;
|
||||||
|
task.Settings.ExecutionTimeLimit = TimeSpan.Zero;
|
||||||
|
task.Triggers.Add(new Microsoft.Win32.TaskScheduler.LogonTrigger { UserId = logonUser, Delay = TimeSpan.FromSeconds(10) });
|
||||||
|
task.Principal.RunLevel = Microsoft.Win32.TaskScheduler.TaskRunLevel.Highest;
|
||||||
|
task.Actions.Add(new Microsoft.Win32.TaskScheduler.ExecAction(fileName.AppendQuotes(), null, Path.GetDirectoryName(fileName)));
|
||||||
|
|
||||||
|
taskService.RootFolder.RegisterTaskDefinition(taskName, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetAutoRunNameWindows()
|
||||||
|
{
|
||||||
|
return $"{Global.AutoRunName}_{Utils.GetMd5(Utils.StartupPath())}";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Windows
|
||||||
|
|
||||||
|
#region Linux
|
||||||
|
|
||||||
|
private static async Task ClearTaskLinux()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(GetHomePathLinux());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(ex.Message, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task SetTaskLinux()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var linuxConfig = Utils.GetEmbedText(Global.LinuxAutostartConfig);
|
||||||
|
if (linuxConfig.IsNotEmpty())
|
||||||
|
{
|
||||||
|
linuxConfig = linuxConfig.Replace("$ExecPath$", Utils.GetExePath());
|
||||||
|
Logging.SaveLog(linuxConfig);
|
||||||
|
|
||||||
|
var homePath = GetHomePathLinux();
|
||||||
|
await File.WriteAllTextAsync(homePath, linuxConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(ex.Message, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetHomePathLinux()
|
||||||
|
{
|
||||||
|
var homePath = Path.Combine(Utils.GetHomePath(), ".config", "autostart", $"{Global.AppName}.desktop");
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(homePath));
|
||||||
|
return homePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Linux
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace ServiceLib.Handler
|
namespace ServiceLib.Handler
|
||||||
@@ -162,6 +162,7 @@ namespace ServiceLib.Handler
|
|||||||
config.ClashUIItem ??= new();
|
config.ClashUIItem ??= new();
|
||||||
config.SystemProxyItem ??= new();
|
config.SystemProxyItem ??= new();
|
||||||
config.WebDavItem ??= new();
|
config.WebDavItem ??= new();
|
||||||
|
config.CheckUpdateItem ??= new();
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
@@ -239,6 +240,7 @@ namespace ServiceLib.Handler
|
|||||||
item.PublicKey = profileItem.PublicKey;
|
item.PublicKey = profileItem.PublicKey;
|
||||||
item.ShortId = profileItem.ShortId;
|
item.ShortId = profileItem.ShortId;
|
||||||
item.SpiderX = profileItem.SpiderX;
|
item.SpiderX = profileItem.SpiderX;
|
||||||
|
item.Extra = profileItem.Extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret = item.ConfigType switch
|
var ret = item.ConfigType switch
|
||||||
@@ -465,7 +467,7 @@ namespace ServiceLib.Handler
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EMove.Position:
|
case EMove.Position:
|
||||||
sort = pos * 10 + 1;
|
sort = (pos * 10) + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1034,14 +1036,14 @@ namespace ServiceLib.Handler
|
|||||||
/// <param name="strData"></param>
|
/// <param name="strData"></param>
|
||||||
/// <param name="subid"></param>
|
/// <param name="subid"></param>
|
||||||
/// <returns>成功导入的数量</returns>
|
/// <returns>成功导入的数量</returns>
|
||||||
private static async Task<int> AddBatchServers(Config config, string strData, string subid, bool isSub, List<ProfileItem> lstOriSub)
|
private static async Task<int> AddBatchServersCommon(Config config, string strData, string subid, bool isSub)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(strData))
|
if (Utils.IsNullOrEmpty(strData))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
string subFilter = string.Empty;
|
var subFilter = string.Empty;
|
||||||
//remove sub items
|
//remove sub items
|
||||||
if (isSub && Utils.IsNotEmpty(subid))
|
if (isSub && Utils.IsNotEmpty(subid))
|
||||||
{
|
{
|
||||||
@@ -1049,16 +1051,14 @@ namespace ServiceLib.Handler
|
|||||||
subFilter = (await AppHandler.Instance.GetSubItem(subid))?.Filter ?? "";
|
subFilter = (await AppHandler.Instance.GetSubItem(subid))?.Filter ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
int countServers = 0;
|
var countServers = 0;
|
||||||
//Check for duplicate indexId
|
|
||||||
List<string>? lstDbIndexId = null;
|
|
||||||
List<ProfileItem> lstAdd = new();
|
List<ProfileItem> lstAdd = new();
|
||||||
var arrData = strData.Split(Environment.NewLine.ToCharArray()).Where(t => !t.IsNullOrEmpty());
|
var arrData = strData.Split(Environment.NewLine.ToCharArray()).Where(t => !t.IsNullOrEmpty());
|
||||||
if (isSub)
|
if (isSub)
|
||||||
{
|
{
|
||||||
arrData = arrData.Distinct();
|
arrData = arrData.Distinct();
|
||||||
}
|
}
|
||||||
foreach (string str in arrData)
|
foreach (var str in arrData)
|
||||||
{
|
{
|
||||||
//maybe sub
|
//maybe sub
|
||||||
if (!isSub && (str.StartsWith(Global.HttpsProtocol) || str.StartsWith(Global.HttpProtocol)))
|
if (!isSub && (str.StartsWith(Global.HttpsProtocol) || str.StartsWith(Global.HttpProtocol)))
|
||||||
@@ -1075,37 +1075,14 @@ namespace ServiceLib.Handler
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//exist sub items
|
//exist sub items //filter
|
||||||
if (isSub && Utils.IsNotEmpty(subid))
|
if (isSub && Utils.IsNotEmpty(subid) && Utils.IsNotEmpty(subFilter))
|
||||||
{
|
|
||||||
var existItem = lstOriSub?.FirstOrDefault(t => t.IsSub == isSub
|
|
||||||
&& config.UiItem.EnableUpdateSubOnlyRemarksExist ? t.Remarks == profileItem.Remarks : CompareProfileItem(t, profileItem, true));
|
|
||||||
if (existItem != null)
|
|
||||||
{
|
|
||||||
//Check for duplicate indexId
|
|
||||||
if (lstDbIndexId is null)
|
|
||||||
{
|
|
||||||
lstDbIndexId = await AppHandler.Instance.ProfileItemIndexes("");
|
|
||||||
}
|
|
||||||
if (lstAdd.Any(t => t.IndexId == existItem.IndexId)
|
|
||||||
|| lstDbIndexId.Any(t => t == existItem.IndexId))
|
|
||||||
{
|
|
||||||
profileItem.IndexId = string.Empty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
profileItem.IndexId = existItem.IndexId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//filter
|
|
||||||
if (Utils.IsNotEmpty(subFilter))
|
|
||||||
{
|
{
|
||||||
if (!Regex.IsMatch(profileItem.Remarks, subFilter))
|
if (!Regex.IsMatch(profileItem.Remarks, subFilter))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
profileItem.Subid = subid;
|
profileItem.Subid = subid;
|
||||||
profileItem.IsSub = isSub;
|
profileItem.IsSub = isSub;
|
||||||
|
|
||||||
@@ -1138,7 +1115,7 @@ namespace ServiceLib.Handler
|
|||||||
return countServers;
|
return countServers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<int> AddBatchServers4Custom(Config config, string strData, string subid, bool isSub, List<ProfileItem> lstOriSub)
|
private static async Task<int> AddBatchServers4Custom(Config config, string strData, string subid, bool isSub)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(strData))
|
if (Utils.IsNullOrEmpty(strData))
|
||||||
{
|
{
|
||||||
@@ -1222,10 +1199,7 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
await RemoveServerViaSubid(config, subid, isSub);
|
await RemoveServerViaSubid(config, subid, isSub);
|
||||||
}
|
}
|
||||||
if (isSub && lstOriSub?.Count == 1)
|
|
||||||
{
|
|
||||||
profileItem.IndexId = lstOriSub[0].IndexId;
|
|
||||||
}
|
|
||||||
profileItem.Subid = subid;
|
profileItem.Subid = subid;
|
||||||
profileItem.IsSub = isSub;
|
profileItem.IsSub = isSub;
|
||||||
profileItem.PreSocksPort = preSocksPort;
|
profileItem.PreSocksPort = preSocksPort;
|
||||||
@@ -1239,7 +1213,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<int> AddBatchServers4SsSIP008(Config config, string strData, string subid, bool isSub, List<ProfileItem> lstOriSub)
|
private static async Task<int> AddBatchServers4SsSIP008(Config config, string strData, string subid, bool isSub)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(strData))
|
if (Utils.IsNullOrEmpty(strData))
|
||||||
{
|
{
|
||||||
@@ -1278,34 +1252,47 @@ namespace ServiceLib.Handler
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
List<ProfileItem>? lstOriSub = null;
|
List<ProfileItem>? lstOriSub = null;
|
||||||
|
ProfileItem? activeProfile = null;
|
||||||
if (isSub && Utils.IsNotEmpty(subid))
|
if (isSub && Utils.IsNotEmpty(subid))
|
||||||
{
|
{
|
||||||
lstOriSub = await AppHandler.Instance.ProfileItems(subid);
|
lstOriSub = await AppHandler.Instance.ProfileItems(subid);
|
||||||
|
activeProfile = lstOriSub?.FirstOrDefault(t => t.IndexId == config.IndexId);
|
||||||
}
|
}
|
||||||
|
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
if (Utils.IsBase64String(strData))
|
if (Utils.IsBase64String(strData))
|
||||||
{
|
{
|
||||||
counter = await AddBatchServers(config, Utils.Base64Decode(strData), subid, isSub, lstOriSub);
|
counter = await AddBatchServersCommon(config, Utils.Base64Decode(strData), subid, isSub);
|
||||||
}
|
}
|
||||||
if (counter < 1)
|
if (counter < 1)
|
||||||
{
|
{
|
||||||
counter = await AddBatchServers(config, strData, subid, isSub, lstOriSub);
|
counter = await AddBatchServersCommon(config, strData, subid, isSub);
|
||||||
}
|
}
|
||||||
if (counter < 1)
|
if (counter < 1)
|
||||||
{
|
{
|
||||||
counter = await AddBatchServers(config, Utils.Base64Decode(strData), subid, isSub, lstOriSub);
|
counter = await AddBatchServersCommon(config, Utils.Base64Decode(strData), subid, isSub);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (counter < 1)
|
if (counter < 1)
|
||||||
{
|
{
|
||||||
counter = await AddBatchServers4SsSIP008(config, strData, subid, isSub, lstOriSub);
|
counter = await AddBatchServers4SsSIP008(config, strData, subid, isSub);
|
||||||
}
|
}
|
||||||
|
|
||||||
//maybe other sub
|
//maybe other sub
|
||||||
if (counter < 1)
|
if (counter < 1)
|
||||||
{
|
{
|
||||||
counter = await AddBatchServers4Custom(config, strData, subid, isSub, lstOriSub);
|
counter = await AddBatchServers4Custom(config, strData, subid, isSub);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Select active node
|
||||||
|
if (activeProfile != null)
|
||||||
|
{
|
||||||
|
var lstSub = await AppHandler.Instance.ProfileItems(subid);
|
||||||
|
var existItem = lstSub?.FirstOrDefault(t => config.UiItem.EnableUpdateSubOnlyRemarksExist ? t.Remarks == activeProfile.Remarks : CompareProfileItem(t, activeProfile, true));
|
||||||
|
if (existItem != null)
|
||||||
|
{
|
||||||
|
await ConfigHandler.SetDefaultServerIndex(config, existItem.IndexId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return counter;
|
return counter;
|
||||||
@@ -1373,6 +1360,7 @@ namespace ServiceLib.Handler
|
|||||||
item.PrevProfile = subItem.PrevProfile;
|
item.PrevProfile = subItem.PrevProfile;
|
||||||
item.NextProfile = subItem.NextProfile;
|
item.NextProfile = subItem.NextProfile;
|
||||||
item.PreSocksPort = subItem.PreSocksPort;
|
item.PreSocksPort = subItem.PreSocksPort;
|
||||||
|
item.Memo = subItem.Memo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(item.Id))
|
if (Utils.IsNullOrEmpty(item.Id))
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ namespace ServiceLib.Handler
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var vName in it.CoreExes)
|
foreach (var name in it.CoreExes)
|
||||||
{
|
{
|
||||||
var exe = Utils.GetExeName(Utils.GetBinPath(vName, it.CoreType.ToString()));
|
var exe = Utils.GetBinPath(Utils.GetExeName(name), it.CoreType.ToString());
|
||||||
if (File.Exists(exe))
|
if (File.Exists(exe))
|
||||||
{
|
{
|
||||||
await Utils.SetLinuxChmod(exe);
|
await Utils.SetLinuxChmod(exe);
|
||||||
@@ -59,7 +59,7 @@ namespace ServiceLib.Handler
|
|||||||
|
|
||||||
var fileName = Utils.GetConfigPath(Global.CoreConfigFileName);
|
var fileName = Utils.GetConfigPath(Global.CoreConfigFileName);
|
||||||
var result = await CoreConfigHandler.GenerateClientConfig(node, fileName);
|
var result = await CoreConfigHandler.GenerateClientConfig(node, fileName);
|
||||||
ShowMsg(false, result.Msg);
|
ShowMsg(true, result.Msg);
|
||||||
if (result.Success != true)
|
if (result.Success != true)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -68,6 +68,7 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
ShowMsg(true, $"{node.GetSummary()}");
|
ShowMsg(true, $"{node.GetSummary()}");
|
||||||
await CoreStop();
|
await CoreStop();
|
||||||
|
await Task.Delay(100);
|
||||||
await CoreStart(node);
|
await CoreStart(node);
|
||||||
|
|
||||||
//In tun mode, do a delay check and restart the core
|
//In tun mode, do a delay check and restart the core
|
||||||
@@ -108,13 +109,11 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool hasProc = false;
|
|
||||||
if (_process != null)
|
if (_process != null)
|
||||||
{
|
{
|
||||||
await KillProcess(_process);
|
await KillProcess(_process);
|
||||||
_process.Dispose();
|
_process.Dispose();
|
||||||
_process = null;
|
_process = null;
|
||||||
hasProc = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_processPre != null)
|
if (_processPre != null)
|
||||||
@@ -122,31 +121,6 @@ namespace ServiceLib.Handler
|
|||||||
await KillProcess(_processPre);
|
await KillProcess(_processPre);
|
||||||
_processPre.Dispose();
|
_processPre.Dispose();
|
||||||
_processPre = null;
|
_processPre = null;
|
||||||
hasProc = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasProc)
|
|
||||||
{
|
|
||||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
|
|
||||||
foreach (var it in coreInfo)
|
|
||||||
{
|
|
||||||
if (it.CoreType == ECoreType.v2rayN)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
foreach (string vName in it.CoreExes)
|
|
||||||
{
|
|
||||||
var existing = Process.GetProcessesByName(vName);
|
|
||||||
foreach (Process p in existing)
|
|
||||||
{
|
|
||||||
string? path = p.MainModule?.FileName;
|
|
||||||
if (path == Utils.GetExeName(Utils.GetBinPath(vName, it.CoreType.ToString())))
|
|
||||||
{
|
|
||||||
await KillProcess(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -172,11 +146,10 @@ namespace ServiceLib.Handler
|
|||||||
|
|
||||||
private string CoreFindExe(CoreInfo coreInfo)
|
private string CoreFindExe(CoreInfo coreInfo)
|
||||||
{
|
{
|
||||||
string fileName = string.Empty;
|
var fileName = string.Empty;
|
||||||
foreach (string name in coreInfo.CoreExes)
|
foreach (var name in coreInfo.CoreExes)
|
||||||
{
|
{
|
||||||
string vName = Utils.GetExeName(name);
|
var vName = Utils.GetBinPath(Utils.GetExeName(name), coreInfo.CoreType.ToString());
|
||||||
vName = Utils.GetBinPath(vName, coreInfo.CoreType.ToString());
|
|
||||||
if (File.Exists(vName))
|
if (File.Exists(vName))
|
||||||
{
|
{
|
||||||
fileName = vName;
|
fileName = vName;
|
||||||
@@ -185,7 +158,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
if (Utils.IsNullOrEmpty(fileName))
|
if (Utils.IsNullOrEmpty(fileName))
|
||||||
{
|
{
|
||||||
string msg = string.Format(ResUI.NotFoundCore, Utils.GetBinPath("", coreInfo.CoreType.ToString()), string.Join(", ", coreInfo.CoreExes.ToArray()), coreInfo.Url);
|
var msg = string.Format(ResUI.NotFoundCore, Utils.GetBinPath("", coreInfo.CoreType.ToString()), string.Join(", ", coreInfo.CoreExes.ToArray()), coreInfo.Url);
|
||||||
Logging.SaveLog(msg);
|
Logging.SaveLog(msg);
|
||||||
ShowMsg(false, msg);
|
ShowMsg(false, msg);
|
||||||
}
|
}
|
||||||
@@ -197,21 +170,12 @@ namespace ServiceLib.Handler
|
|||||||
ShowMsg(false, $"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
|
ShowMsg(false, $"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
|
||||||
ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
|
ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
|
||||||
|
|
||||||
//ECoreType coreType;
|
|
||||||
//if (node.configType != EConfigType.Custom && _config.tunModeItem.enableTun)
|
|
||||||
//{
|
|
||||||
// coreType = ECoreType.sing_box;
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// coreType = LazyConfig.Instance.GetCoreType(node, node.configType);
|
|
||||||
//}
|
|
||||||
var coreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
|
var coreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
|
||||||
_config.RunningCoreType = coreType;
|
_config.RunningCoreType = coreType;
|
||||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
||||||
|
|
||||||
var displayLog = node.ConfigType != EConfigType.Custom || node.DisplayLog;
|
var displayLog = node.ConfigType != EConfigType.Custom || node.DisplayLog;
|
||||||
var proc = await RunProcess(node, coreInfo, "", displayLog);
|
var proc = await RunProcess(coreInfo, Global.CoreConfigFileName, displayLog, true);
|
||||||
if (proc is null)
|
if (proc is null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -248,12 +212,12 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
if (itemSocks != null)
|
if (itemSocks != null)
|
||||||
{
|
{
|
||||||
string fileName2 = Utils.GetConfigPath(Global.CorePreConfigFileName);
|
var fileName2 = Utils.GetConfigPath(Global.CorePreConfigFileName);
|
||||||
var result = await CoreConfigHandler.GenerateClientConfig(itemSocks, fileName2);
|
var result = await CoreConfigHandler.GenerateClientConfig(itemSocks, fileName2);
|
||||||
if (result.Success)
|
if (result.Success)
|
||||||
{
|
{
|
||||||
var coreInfo2 = CoreInfoHandler.Instance.GetCoreInfo(preCoreType);
|
var coreInfo2 = CoreInfoHandler.Instance.GetCoreInfo(preCoreType);
|
||||||
var proc2 = await RunProcess(node, coreInfo2, $" -c {Global.CorePreConfigFileName}", true);
|
var proc2 = await RunProcess(coreInfo2, Global.CorePreConfigFileName, true, true);
|
||||||
if (proc2 is not null)
|
if (proc2 is not null)
|
||||||
{
|
{
|
||||||
_processPre = proc2;
|
_processPre = proc2;
|
||||||
@@ -271,7 +235,7 @@ namespace ServiceLib.Handler
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
||||||
var proc = await RunProcess(new(), coreInfo, $" -c {Global.CoreSpeedtestConfigFileName}", true);
|
var proc = await RunProcess(coreInfo, Global.CoreSpeedtestConfigFileName, true, false);
|
||||||
if (proc is null)
|
if (proc is null)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
@@ -282,8 +246,7 @@ namespace ServiceLib.Handler
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
string msg = ex.Message;
|
ShowMsg(false, ex.Message);
|
||||||
ShowMsg(false, msg);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -293,19 +256,30 @@ namespace ServiceLib.Handler
|
|||||||
_updateFunc?.Invoke(notify, msg);
|
_updateFunc?.Invoke(notify, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsNeedSudo(ECoreType eCoreType)
|
||||||
|
{
|
||||||
|
return _config.TunModeItem.EnableTun
|
||||||
|
&& eCoreType == ECoreType.sing_box
|
||||||
|
&& Utils.IsLinux()
|
||||||
|
&& _config.TunModeItem.LinuxSudoPwd.IsNotEmpty()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Private
|
#endregion Private
|
||||||
|
|
||||||
#region Process
|
#region Process
|
||||||
|
|
||||||
private async Task<Process?> RunProcess(ProfileItem node, CoreInfo coreInfo, string configPath, bool displayLog)
|
private async Task<Process?> RunProcess(CoreInfo coreInfo, string configPath, bool displayLog, bool mayNeedSudo)
|
||||||
{
|
{
|
||||||
try
|
var fileName = CoreFindExe(coreInfo);
|
||||||
{
|
|
||||||
string fileName = CoreFindExe(coreInfo);
|
|
||||||
if (Utils.IsNullOrEmpty(fileName))
|
if (Utils.IsNullOrEmpty(fileName))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isNeedSudo = mayNeedSudo && IsNeedSudo(coreInfo.CoreType);
|
||||||
|
try
|
||||||
|
{
|
||||||
Process proc = new()
|
Process proc = new()
|
||||||
{
|
{
|
||||||
StartInfo = new()
|
StartInfo = new()
|
||||||
@@ -321,33 +295,47 @@ namespace ServiceLib.Handler
|
|||||||
StandardErrorEncoding = displayLog ? Encoding.UTF8 : null,
|
StandardErrorEncoding = displayLog ? Encoding.UTF8 : null,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (isNeedSudo)
|
||||||
|
{
|
||||||
|
proc.StartInfo.FileName = $"/bin/sudo";
|
||||||
|
proc.StartInfo.Arguments = $"-S {fileName} {string.Format(coreInfo.Arguments, Utils.GetConfigPath(configPath))}";
|
||||||
|
proc.StartInfo.WorkingDirectory = null;
|
||||||
|
proc.StartInfo.StandardInputEncoding = Encoding.UTF8;
|
||||||
|
proc.StartInfo.RedirectStandardInput = true;
|
||||||
|
}
|
||||||
|
|
||||||
var startUpErrorMessage = new StringBuilder();
|
var startUpErrorMessage = new StringBuilder();
|
||||||
var startUpSuccessful = false;
|
var startUpSuccessful = false;
|
||||||
if (displayLog)
|
if (displayLog)
|
||||||
{
|
{
|
||||||
proc.OutputDataReceived += (sender, e) =>
|
proc.OutputDataReceived += (sender, e) =>
|
||||||
{
|
{
|
||||||
if (Utils.IsNotEmpty(e.Data))
|
if (Utils.IsNullOrEmpty(e.Data)) return;
|
||||||
{
|
ShowMsg(false, e.Data + Environment.NewLine);
|
||||||
string msg = e.Data + Environment.NewLine;
|
|
||||||
ShowMsg(false, msg);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
proc.ErrorDataReceived += (sender, e) =>
|
proc.ErrorDataReceived += (sender, e) =>
|
||||||
{
|
{
|
||||||
if (Utils.IsNotEmpty(e.Data))
|
if (Utils.IsNullOrEmpty(e.Data)) return;
|
||||||
{
|
ShowMsg(false, e.Data + Environment.NewLine);
|
||||||
string msg = e.Data + Environment.NewLine;
|
|
||||||
ShowMsg(false, msg);
|
|
||||||
|
|
||||||
if (!startUpSuccessful)
|
if (!startUpSuccessful)
|
||||||
{
|
{
|
||||||
startUpErrorMessage.Append(msg);
|
startUpErrorMessage.Append(e.Data + Environment.NewLine);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
proc.Start();
|
proc.Start();
|
||||||
|
|
||||||
|
if (isNeedSudo)
|
||||||
|
{
|
||||||
|
var pwd = DesUtils.Decrypt(_config.TunModeItem.LinuxSudoPwd);
|
||||||
|
await Task.Delay(10);
|
||||||
|
await proc.StandardInput.WriteLineAsync(pwd);
|
||||||
|
await Task.Delay(10);
|
||||||
|
await proc.StandardInput.WriteLineAsync(pwd);
|
||||||
|
}
|
||||||
|
|
||||||
if (displayLog)
|
if (displayLog)
|
||||||
{
|
{
|
||||||
proc.BeginOutputReadLine();
|
proc.BeginOutputReadLine();
|
||||||
@@ -370,8 +358,7 @@ namespace ServiceLib.Handler
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
Logging.SaveLog(ex.Message, ex);
|
||||||
string msg = ex.Message;
|
ShowMsg(true, ex.Message);
|
||||||
ShowMsg(true, msg);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,19 +369,25 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(1));
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
await proc.WaitForExitAsync(timeout.Token);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
proc.Kill();
|
proc.Kill();
|
||||||
proc.WaitForExit(100);
|
}
|
||||||
if (!proc.HasExited)
|
if (!proc.HasExited)
|
||||||
{
|
{
|
||||||
proc.Kill();
|
try
|
||||||
proc.WaitForExit(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
{
|
||||||
Logging.SaveLog(ex.Message, ex);
|
await proc.WaitForExitAsync(timeout.Token);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
proc.Kill();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System.Runtime.Intrinsics.X86;
|
namespace ServiceLib.Handler
|
||||||
|
|
||||||
namespace ServiceLib.Handler
|
|
||||||
{
|
{
|
||||||
public sealed class CoreInfoHandler
|
public sealed class CoreInfoHandler
|
||||||
{
|
{
|
||||||
@@ -74,7 +72,7 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
CoreType = ECoreType.Xray,
|
CoreType = ECoreType.Xray,
|
||||||
CoreExes = new List<string> { "xray", "wxray" },
|
CoreExes = new List<string> { "xray", "wxray" },
|
||||||
Arguments = "run {0}",
|
Arguments = "run -c {0}",
|
||||||
Url = Global.XrayCoreUrl,
|
Url = Global.XrayCoreUrl,
|
||||||
ReleaseApiUrl = Global.XrayCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
ReleaseApiUrl = Global.XrayCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
DownloadUrlWin64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-64.zip",
|
DownloadUrlWin64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-64.zip",
|
||||||
@@ -89,7 +87,7 @@ namespace ServiceLib.Handler
|
|||||||
_coreInfo.Add(new CoreInfo
|
_coreInfo.Add(new CoreInfo
|
||||||
{
|
{
|
||||||
CoreType = ECoreType.mihomo,
|
CoreType = ECoreType.mihomo,
|
||||||
CoreExes = new List<string> { $"mihomo-windows-amd64{(Avx2.X64.IsSupported ? "" : "-compatible")}", "mihomo-windows-amd64-compatible", "mihomo-windows-amd64", "mihomo-windows-386", "mihomo", "clash" },
|
CoreExes = new List<string> { "mihomo-windows-amd64-compatible", "mihomo-windows-amd64", "mihomo-linux-amd64", "mihomo", "clash" },
|
||||||
Arguments = "-f config.json" + PortableMode(),
|
Arguments = "-f config.json" + PortableMode(),
|
||||||
Url = Global.MihomoCoreUrl,
|
Url = Global.MihomoCoreUrl,
|
||||||
ReleaseApiUrl = Global.MihomoCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
ReleaseApiUrl = Global.MihomoCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
@@ -105,7 +103,7 @@ namespace ServiceLib.Handler
|
|||||||
_coreInfo.Add(new CoreInfo
|
_coreInfo.Add(new CoreInfo
|
||||||
{
|
{
|
||||||
CoreType = ECoreType.hysteria,
|
CoreType = ECoreType.hysteria,
|
||||||
CoreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" },
|
CoreExes = new List<string> { "hysteria-windows-amd64", "hysteria" },
|
||||||
Arguments = "",
|
Arguments = "",
|
||||||
Url = Global.HysteriaCoreUrl,
|
Url = Global.HysteriaCoreUrl,
|
||||||
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
@@ -134,7 +132,7 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
CoreType = ECoreType.sing_box,
|
CoreType = ECoreType.sing_box,
|
||||||
CoreExes = new List<string> { "sing-box-client", "sing-box" },
|
CoreExes = new List<string> { "sing-box-client", "sing-box" },
|
||||||
Arguments = "run {0} --disable-color",
|
Arguments = "run -c {0} --disable-color",
|
||||||
Url = Global.SingboxCoreUrl,
|
Url = Global.SingboxCoreUrl,
|
||||||
RedirectInfo = true,
|
RedirectInfo = true,
|
||||||
ReleaseApiUrl = Global.SingboxCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
ReleaseApiUrl = Global.SingboxCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
@@ -157,7 +155,7 @@ namespace ServiceLib.Handler
|
|||||||
_coreInfo.Add(new CoreInfo
|
_coreInfo.Add(new CoreInfo
|
||||||
{
|
{
|
||||||
CoreType = ECoreType.hysteria2,
|
CoreType = ECoreType.hysteria2,
|
||||||
CoreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" },
|
CoreExes = new List<string> { "hysteria-windows-amd64", "hysteria-linux-amd64", "hysteria" },
|
||||||
Arguments = "",
|
Arguments = "",
|
||||||
Url = Global.HysteriaCoreUrl,
|
Url = Global.HysteriaCoreUrl,
|
||||||
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ namespace ServiceLib.Handler.Fmt
|
|||||||
|
|
||||||
case nameof(ETransport.ws):
|
case nameof(ETransport.ws):
|
||||||
case nameof(ETransport.httpupgrade):
|
case nameof(ETransport.httpupgrade):
|
||||||
case nameof(ETransport.splithttp):
|
|
||||||
if (Utils.IsNotEmpty(item.RequestHost))
|
if (Utils.IsNotEmpty(item.RequestHost))
|
||||||
{
|
{
|
||||||
dicQuery.Add("host", Utils.UrlEncode(item.RequestHost));
|
dicQuery.Add("host", Utils.UrlEncode(item.RequestHost));
|
||||||
@@ -94,6 +93,26 @@ namespace ServiceLib.Handler.Fmt
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nameof(ETransport.splithttp):
|
||||||
|
case nameof(ETransport.xhttp):
|
||||||
|
if (Utils.IsNotEmpty(item.RequestHost))
|
||||||
|
{
|
||||||
|
dicQuery.Add("host", Utils.UrlEncode(item.RequestHost));
|
||||||
|
}
|
||||||
|
if (Utils.IsNotEmpty(item.Path))
|
||||||
|
{
|
||||||
|
dicQuery.Add("path", Utils.UrlEncode(item.Path));
|
||||||
|
}
|
||||||
|
if (Utils.IsNotEmpty(item.HeaderType) && Global.XhttpMode.Contains(item.HeaderType))
|
||||||
|
{
|
||||||
|
dicQuery.Add("mode", Utils.UrlEncode(item.HeaderType));
|
||||||
|
}
|
||||||
|
if (Utils.IsNotEmpty(item.Extra))
|
||||||
|
{
|
||||||
|
dicQuery.Add("extra", Utils.UrlEncode(item.Extra));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.http):
|
case nameof(ETransport.http):
|
||||||
case nameof(ETransport.h2):
|
case nameof(ETransport.h2):
|
||||||
dicQuery["type"] = nameof(ETransport.http);
|
dicQuery["type"] = nameof(ETransport.http);
|
||||||
@@ -156,11 +175,18 @@ namespace ServiceLib.Handler.Fmt
|
|||||||
|
|
||||||
case nameof(ETransport.ws):
|
case nameof(ETransport.ws):
|
||||||
case nameof(ETransport.httpupgrade):
|
case nameof(ETransport.httpupgrade):
|
||||||
case nameof(ETransport.splithttp):
|
|
||||||
item.RequestHost = Utils.UrlDecode(query["host"] ?? "");
|
item.RequestHost = Utils.UrlDecode(query["host"] ?? "");
|
||||||
item.Path = Utils.UrlDecode(query["path"] ?? "/");
|
item.Path = Utils.UrlDecode(query["path"] ?? "/");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nameof(ETransport.splithttp):
|
||||||
|
case nameof(ETransport.xhttp):
|
||||||
|
item.RequestHost = Utils.UrlDecode(query["host"] ?? "");
|
||||||
|
item.Path = Utils.UrlDecode(query["path"] ?? "/");
|
||||||
|
item.HeaderType = Utils.UrlDecode(query["mode"] ?? "");
|
||||||
|
item.Extra = Utils.UrlDecode(query["extra"] ?? "");
|
||||||
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.http):
|
case nameof(ETransport.http):
|
||||||
case nameof(ETransport.h2):
|
case nameof(ETransport.h2):
|
||||||
item.Network = nameof(ETransport.h2);
|
item.Network = nameof(ETransport.h2);
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
private ServerStatItem? _serverStatItem;
|
private ServerStatItem? _serverStatItem;
|
||||||
private List<ServerStatItem> _lstServerStat;
|
private List<ServerStatItem> _lstServerStat;
|
||||||
private Action<ServerSpeedItem>? _updateFunc;
|
private Action<ServerSpeedItem>? _updateFunc;
|
||||||
private StatisticsV2rayService? _statisticsV2Ray;
|
//private StatisticsV2rayService? _statisticsV2Ray;
|
||||||
|
private StatisticsXrayService? _statisticsXray;
|
||||||
private StatisticsSingboxService? _statisticsSingbox;
|
private StatisticsSingboxService? _statisticsSingbox;
|
||||||
|
|
||||||
public List<ServerStatItem> ServerStat => _lstServerStat;
|
public List<ServerStatItem> ServerStat => _lstServerStat;
|
||||||
@@ -25,7 +26,8 @@
|
|||||||
|
|
||||||
await InitData();
|
await InitData();
|
||||||
|
|
||||||
_statisticsV2Ray = new StatisticsV2rayService(config, UpdateServerStatHandler);
|
//_statisticsV2Ray = new StatisticsV2rayService(config, UpdateServerStatHandler);
|
||||||
|
_statisticsXray = new StatisticsXrayService(config, UpdateServerStatHandler);
|
||||||
_statisticsSingbox = new StatisticsSingboxService(config, UpdateServerStatHandler);
|
_statisticsSingbox = new StatisticsSingboxService(config, UpdateServerStatHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +35,8 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_statisticsV2Ray?.Close();
|
//_statisticsV2Ray?.Close();
|
||||||
|
_statisticsXray?.Close();
|
||||||
_statisticsSingbox?.Close();
|
_statisticsSingbox?.Close();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -2,12 +2,81 @@
|
|||||||
{
|
{
|
||||||
public class ProxySettingOSX
|
public class ProxySettingOSX
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* 仅测试了,MacOS 13.7.1 x86 版本,其他版本有待确认
|
||||||
|
*/
|
||||||
|
/// <summary>
|
||||||
|
/// 应用接口类型
|
||||||
|
/// </summary>
|
||||||
|
private static readonly List<string> LstInterface = ["Ethernet", "Wi-Fi", "Thunderbolt Bridge"];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 代理类型,对应 http,https,socks
|
||||||
|
/// </summary>
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
|
var lstCmd = GetSetCmds(host, port);
|
||||||
|
await ExecCmd(lstCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static async Task UnsetProxy()
|
public static async Task UnsetProxy()
|
||||||
{
|
{
|
||||||
|
var lstCmd = GetUnsetCmds();
|
||||||
|
await ExecCmd(lstCmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static async Task ExecCmd(List<CmdItem> lstCmd)
|
||||||
|
{
|
||||||
|
foreach (var cmd in lstCmd)
|
||||||
|
{
|
||||||
|
if (cmd is null || cmd.Cmd.IsNullOrEmpty() || cmd.Arguments is null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Delay(10);
|
||||||
|
await Utils.GetCliWrapOutput(cmd.Cmd, cmd.Arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<CmdItem> GetSetCmds(string host, int port)
|
||||||
|
{
|
||||||
|
List<CmdItem> lstCmd = [];
|
||||||
|
foreach (var interf in LstInterface)
|
||||||
|
{
|
||||||
|
foreach (var type in LstTypes)
|
||||||
|
{
|
||||||
|
lstCmd.Add(new CmdItem()
|
||||||
|
{
|
||||||
|
Cmd = "networksetup",
|
||||||
|
Arguments = [$"-{type}", interf, host, (type.Contains("socks") ? (port - 1) : port).ToString()]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lstCmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<CmdItem> GetUnsetCmds()
|
||||||
|
{
|
||||||
|
List<CmdItem> lstCmd = [];
|
||||||
|
foreach (var interf in LstInterface)
|
||||||
|
{
|
||||||
|
foreach (var type in LstTypes)
|
||||||
|
{
|
||||||
|
lstCmd.Add(new CmdItem()
|
||||||
|
{
|
||||||
|
Cmd = "networksetup",
|
||||||
|
Arguments = [$"-{type}state", interf, "off"]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lstCmd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using static ServiceLib.Handler.SysProxy.ProxySettingWindows.InternetConnectionOption;
|
using static ServiceLib.Handler.SysProxy.ProxySettingWindows.InternetConnectionOption;
|
||||||
|
|
||||||
namespace ServiceLib.Handler.SysProxy
|
namespace ServiceLib.Handler.SysProxy
|
||||||
@@ -11,24 +11,24 @@ namespace ServiceLib.Handler.SysProxy
|
|||||||
{
|
{
|
||||||
if (type == 1)
|
if (type == 1)
|
||||||
{
|
{
|
||||||
RegWriteValue(_regPath, "ProxyEnable", 0);
|
WindowsUtils.RegWriteValue(_regPath, "ProxyEnable", 0);
|
||||||
RegWriteValue(_regPath, "ProxyServer", string.Empty);
|
WindowsUtils.RegWriteValue(_regPath, "ProxyServer", string.Empty);
|
||||||
RegWriteValue(_regPath, "ProxyOverride", string.Empty);
|
WindowsUtils.RegWriteValue(_regPath, "ProxyOverride", string.Empty);
|
||||||
RegWriteValue(_regPath, "AutoConfigURL", string.Empty);
|
WindowsUtils.RegWriteValue(_regPath, "AutoConfigURL", string.Empty);
|
||||||
}
|
}
|
||||||
if (type == 2)
|
if (type == 2)
|
||||||
{
|
{
|
||||||
RegWriteValue(_regPath, "ProxyEnable", 1);
|
WindowsUtils.RegWriteValue(_regPath, "ProxyEnable", 1);
|
||||||
RegWriteValue(_regPath, "ProxyServer", strProxy ?? string.Empty);
|
WindowsUtils.RegWriteValue(_regPath, "ProxyServer", strProxy ?? string.Empty);
|
||||||
RegWriteValue(_regPath, "ProxyOverride", exceptions ?? string.Empty);
|
WindowsUtils.RegWriteValue(_regPath, "ProxyOverride", exceptions ?? string.Empty);
|
||||||
RegWriteValue(_regPath, "AutoConfigURL", string.Empty);
|
WindowsUtils.RegWriteValue(_regPath, "AutoConfigURL", string.Empty);
|
||||||
}
|
}
|
||||||
else if (type == 4)
|
else if (type == 4)
|
||||||
{
|
{
|
||||||
RegWriteValue(_regPath, "ProxyEnable", 0);
|
WindowsUtils.RegWriteValue(_regPath, "ProxyEnable", 0);
|
||||||
RegWriteValue(_regPath, "ProxyServer", string.Empty);
|
WindowsUtils.RegWriteValue(_regPath, "ProxyServer", string.Empty);
|
||||||
RegWriteValue(_regPath, "ProxyOverride", string.Empty);
|
WindowsUtils.RegWriteValue(_regPath, "ProxyOverride", string.Empty);
|
||||||
RegWriteValue(_regPath, "AutoConfigURL", strProxy ?? string.Empty);
|
WindowsUtils.RegWriteValue(_regPath, "AutoConfigURL", strProxy ?? string.Empty);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -144,12 +144,12 @@ namespace ServiceLib.Handler.SysProxy
|
|||||||
{
|
{
|
||||||
if (Environment.Is64BitOperatingSystem)
|
if (Environment.Is64BitOperatingSystem)
|
||||||
{
|
{
|
||||||
nint opt = new(optionsPtr.ToInt64() + i * optSize);
|
nint opt = new(optionsPtr.ToInt64() + (i * optSize));
|
||||||
Marshal.StructureToPtr(options[i], opt, false);
|
Marshal.StructureToPtr(options[i], opt, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nint opt = new(optionsPtr.ToInt32() + i * optSize);
|
nint opt = new(optionsPtr.ToInt32() + (i * optSize));
|
||||||
Marshal.StructureToPtr(options[i], opt, false);
|
Marshal.StructureToPtr(options[i], opt, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ namespace ServiceLib.Handler.SysProxy
|
|||||||
|
|
||||||
//[MarshalAs(UnmanagedType.)]
|
//[MarshalAs(UnmanagedType.)]
|
||||||
public nint options;
|
public nint options;
|
||||||
};
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||||
public struct InternetConnectionOption
|
public struct InternetConnectionOption
|
||||||
@@ -356,30 +356,5 @@ namespace ServiceLib.Handler.SysProxy
|
|||||||
ref int lpcEntries // Number of entries written to the buffer
|
ref int lpcEntries // Number of entries written to the buffer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RegWriteValue(string path, string name, object value)
|
|
||||||
{
|
|
||||||
Microsoft.Win32.RegistryKey? regKey = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
regKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(path);
|
|
||||||
if (string.IsNullOrEmpty(value.ToString()))
|
|
||||||
{
|
|
||||||
regKey?.DeleteValue(name, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
regKey?.SetValue(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
//Logging.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
regKey?.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,15 +33,10 @@ namespace ServiceLib.Handler.SysProxy
|
|||||||
await ProxySettingLinux.SetProxy(Global.Loopback, port);
|
await ProxySettingLinux.SetProxy(Global.Loopback, port);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESysProxyType.ForcedChange:
|
case ESysProxyType.ForcedChange when Utils.IsOSX():
|
||||||
{
|
|
||||||
if (Utils.IsOSX())
|
|
||||||
{
|
|
||||||
await ProxySettingOSX.SetProxy(Global.Loopback, port);
|
await ProxySettingOSX.SetProxy(Global.Loopback, port);
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ESysProxyType.ForcedClear when Utils.IsWindows():
|
case ESysProxyType.ForcedClear when Utils.IsWindows():
|
||||||
ProxySettingWindows.UnsetProxy();
|
ProxySettingWindows.UnsetProxy();
|
||||||
break;
|
break;
|
||||||
@@ -50,24 +45,14 @@ namespace ServiceLib.Handler.SysProxy
|
|||||||
await ProxySettingLinux.UnsetProxy();
|
await ProxySettingLinux.UnsetProxy();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESysProxyType.ForcedClear:
|
case ESysProxyType.ForcedClear when Utils.IsOSX():
|
||||||
{
|
|
||||||
if (Utils.IsOSX())
|
|
||||||
{
|
|
||||||
await ProxySettingOSX.UnsetProxy();
|
await ProxySettingOSX.UnsetProxy();
|
||||||
}
|
break;
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ESysProxyType.Pac when Utils.IsWindows():
|
case ESysProxyType.Pac when Utils.IsWindows():
|
||||||
{
|
await SetWindowsProxyPac(port);
|
||||||
var portPac = AppHandler.Instance.GetLocalPort(EInboundProtocol.pac);
|
|
||||||
PacHandler.Start(Utils.GetConfigPath(), port, portPac);
|
|
||||||
var strProxy = $"{Global.HttpProtocol}{Global.Loopback}:{portPac}/pac?t={DateTime.Now.Ticks}";
|
|
||||||
ProxySettingWindows.SetProxy(strProxy, "", 4);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (type != ESysProxyType.Pac && Utils.IsWindows())
|
if (type != ESysProxyType.Pac && Utils.IsWindows())
|
||||||
{
|
{
|
||||||
@@ -102,5 +87,13 @@ namespace ServiceLib.Handler.SysProxy
|
|||||||
.Replace("{socks_port}", portSocks.ToString());
|
.Replace("{socks_port}", portSocks.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task SetWindowsProxyPac(int port)
|
||||||
|
{
|
||||||
|
var portPac = AppHandler.Instance.GetLocalPort(EInboundProtocol.pac);
|
||||||
|
await PacHandler.Start(Utils.GetConfigPath(), port, portPac);
|
||||||
|
var strProxy = $"{Global.HttpProtocol}{Global.Loopback}:{portPac}/pac?t={DateTime.Now.Ticks}";
|
||||||
|
ProxySettingWindows.SetProxy(strProxy, "", 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace ServiceLib.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
public class CheckUpdateItem
|
public class CheckUpdateModel
|
||||||
{
|
{
|
||||||
public bool? IsSelected { get; set; }
|
public bool? IsSelected { get; set; }
|
||||||
public string? CoreType { get; set; }
|
public string? CoreType { get; set; }
|
||||||
@@ -15,16 +15,15 @@
|
|||||||
|
|
||||||
public bool IsRunningCore(ECoreType type)
|
public bool IsRunningCore(ECoreType type)
|
||||||
{
|
{
|
||||||
if (type == ECoreType.Xray && RunningCoreType is ECoreType.Xray or ECoreType.v2fly or ECoreType.v2fly_v5)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
case ECoreType.Xray when RunningCoreType is ECoreType.Xray or ECoreType.v2fly or ECoreType.v2fly_v5:
|
||||||
|
case ECoreType.sing_box when RunningCoreType is ECoreType.sing_box or ECoreType.mihomo:
|
||||||
return true;
|
return true;
|
||||||
}
|
default:
|
||||||
if (type == ECoreType.sing_box && RunningCoreType is ECoreType.sing_box or ECoreType.mihomo)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion property
|
#endregion property
|
||||||
|
|
||||||
@@ -46,6 +45,7 @@
|
|||||||
public ClashUIItem ClashUIItem { get; set; }
|
public ClashUIItem ClashUIItem { get; set; }
|
||||||
public SystemProxyItem SystemProxyItem { get; set; }
|
public SystemProxyItem SystemProxyItem { get; set; }
|
||||||
public WebDavItem WebDavItem { get; set; }
|
public WebDavItem WebDavItem { get; set; }
|
||||||
|
public CheckUpdateItem CheckUpdateItem { get; set; }
|
||||||
public List<InItem> Inbound { get; set; }
|
public List<InItem> Inbound { get; set; }
|
||||||
public List<KeyEventItem> GlobalHotkeys { get; set; }
|
public List<KeyEventItem> GlobalHotkeys { get; set; }
|
||||||
public List<CoreTypeItem> CoreTypeItem { get; set; }
|
public List<CoreTypeItem> CoreTypeItem { get; set; }
|
||||||
|
|||||||
@@ -81,13 +81,13 @@
|
|||||||
|
|
||||||
public int AutoUpdateInterval { get; set; }
|
public int AutoUpdateInterval { get; set; }
|
||||||
|
|
||||||
public bool CheckPreReleaseUpdate { get; set; } = false;
|
|
||||||
|
|
||||||
public bool EnableSecurityProtocolTls13 { get; set; }
|
public bool EnableSecurityProtocolTls13 { get; set; }
|
||||||
|
|
||||||
public int TrayMenuServersLimit { get; set; } = 20;
|
public int TrayMenuServersLimit { get; set; } = 20;
|
||||||
|
|
||||||
public bool EnableHWA { get; set; } = false;
|
public bool EnableHWA { get; set; } = false;
|
||||||
|
|
||||||
|
public bool EnableLog { get; set; } = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
@@ -161,6 +161,7 @@
|
|||||||
public int Mtu { get; set; }
|
public int Mtu { get; set; }
|
||||||
public bool EnableExInbound { get; set; }
|
public bool EnableExInbound { get; set; }
|
||||||
public bool EnableIPv6Address { get; set; }
|
public bool EnableIPv6Address { get; set; }
|
||||||
|
public string? LinuxSudoPwd { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
@@ -243,4 +244,11 @@
|
|||||||
public string? Password { get; set; }
|
public string? Password { get; set; }
|
||||||
public string? DirName { get; set; }
|
public string? DirName { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class CheckUpdateItem
|
||||||
|
{
|
||||||
|
public bool CheckPreReleaseUpdate { get; set; }
|
||||||
|
public List<string>? SelectedCoreTypes { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -30,44 +30,25 @@ namespace ServiceLib.Models
|
|||||||
|
|
||||||
public string GetSummary()
|
public string GetSummary()
|
||||||
{
|
{
|
||||||
string summary = string.Format("[{0}] ", (ConfigType).ToString());
|
var summary = $"[{(ConfigType).ToString()}] ";
|
||||||
string[] arrAddr = Address.Split('.');
|
var arrAddr = Address.Split('.');
|
||||||
string addr;
|
var addr = arrAddr.Length switch
|
||||||
if (arrAddr.Length > 2)
|
|
||||||
{
|
{
|
||||||
addr = $"{arrAddr.First()}***{arrAddr.Last()}";
|
> 2 => $"{arrAddr.First()}***{arrAddr.Last()}",
|
||||||
}
|
> 1 => $"***{arrAddr.Last()}",
|
||||||
else if (arrAddr.Length > 1)
|
_ => Address
|
||||||
|
};
|
||||||
|
summary += ConfigType switch
|
||||||
{
|
{
|
||||||
addr = $"***{arrAddr.Last()}";
|
EConfigType.Custom => $"[{CoreType.ToString()}]{Remarks}",
|
||||||
}
|
_ => $"{Remarks}({addr}:{Port})"
|
||||||
else
|
};
|
||||||
{
|
|
||||||
addr = Address;
|
|
||||||
}
|
|
||||||
switch (ConfigType)
|
|
||||||
{
|
|
||||||
case EConfigType.Custom:
|
|
||||||
summary += string.Format("[{1}]{0}", Remarks, CoreType.ToString());
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
summary += string.Format("{0}({1}:{2})", Remarks, addr, Port);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return summary;
|
return summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<string>? GetAlpn()
|
public List<string>? GetAlpn()
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(Alpn))
|
return Utils.IsNullOrEmpty(Alpn) ? null : Utils.String2List(Alpn);
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Utils.String2List(Alpn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetNetwork()
|
public string GetNetwork()
|
||||||
@@ -110,5 +91,6 @@ namespace ServiceLib.Models
|
|||||||
public string PublicKey { get; set; }
|
public string PublicKey { get; set; }
|
||||||
public string ShortId { get; set; }
|
public string ShortId { get; set; }
|
||||||
public string SpiderX { get; set; }
|
public string SpiderX { get; set; }
|
||||||
|
public string Extra { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,8 +78,7 @@
|
|||||||
public int? listen_port { get; set; }
|
public int? listen_port { get; set; }
|
||||||
public string? domain_strategy { get; set; }
|
public string? domain_strategy { get; set; }
|
||||||
public string interface_name { get; set; }
|
public string interface_name { get; set; }
|
||||||
public string inet4_address { get; set; }
|
public List<string>? address { get; set; }
|
||||||
public string? inet6_address { get; set; }
|
|
||||||
public int? mtu { get; set; }
|
public int? mtu { get; set; }
|
||||||
public bool? auto_route { get; set; }
|
public bool? auto_route { get; set; }
|
||||||
public bool? strict_route { get; set; }
|
public bool? strict_route { get; set; }
|
||||||
|
|||||||
@@ -33,5 +33,7 @@ namespace ServiceLib.Models
|
|||||||
public string? NextProfile { get; set; }
|
public string? NextProfile { get; set; }
|
||||||
|
|
||||||
public int? PreSocksPort { get; set; }
|
public int? PreSocksPort { get; set; }
|
||||||
|
|
||||||
|
public string? Memo { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,61 +1,34 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace ServiceLib.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// v2ray配置文件实体类 例子SampleConfig.txt
|
|
||||||
/// </summary>
|
|
||||||
public class V2rayConfig
|
public class V2rayConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Properties that do not belong to Ray
|
|
||||||
/// </summary>
|
|
||||||
public string? remarks { get; set; }
|
public string? remarks { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 日志配置
|
|
||||||
/// </summary>
|
|
||||||
public Log4Ray log { get; set; }
|
public Log4Ray log { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 传入连接配置
|
|
||||||
/// </summary>
|
|
||||||
public List<Inbounds4Ray> inbounds { get; set; }
|
public List<Inbounds4Ray> inbounds { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 传出连接配置
|
|
||||||
/// </summary>
|
|
||||||
public List<Outbounds4Ray> outbounds { get; set; }
|
public List<Outbounds4Ray> outbounds { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
public Stats4Ray? stats { get; set; }
|
||||||
/// 统计需要, 空对象
|
|
||||||
/// </summary>
|
|
||||||
public Stats4Ray stats { get; set; }
|
|
||||||
|
|
||||||
/// </summary>
|
public Metrics4Ray? metrics { get; set; }
|
||||||
public API4Ray api { get; set; }
|
|
||||||
|
|
||||||
/// </summary>
|
public Policy4Ray? policy { get; set; }
|
||||||
public Policy4Ray policy { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// DNS 配置
|
|
||||||
/// </summary>
|
|
||||||
public object dns { get; set; }
|
public object dns { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 路由配置
|
|
||||||
/// </summary>
|
|
||||||
public Routing4Ray routing { get; set; }
|
public Routing4Ray routing { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Stats4Ray
|
public class Stats4Ray
|
||||||
{ };
|
{ }
|
||||||
|
|
||||||
public class API4Ray
|
public class Metrics4Ray
|
||||||
{
|
{
|
||||||
public string tag { get; set; }
|
public string tag { get; set; }
|
||||||
public List<string> services { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Policy4Ray
|
public class Policy4Ray
|
||||||
@@ -71,124 +44,59 @@ namespace ServiceLib.Models
|
|||||||
|
|
||||||
public class Log4Ray
|
public class Log4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
public string? access { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string access { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public string? error { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string error { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public string? loglevel { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string loglevel { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Inbounds4Ray
|
public class Inbounds4Ray
|
||||||
{
|
{
|
||||||
public string tag { get; set; }
|
public string tag { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int port { get; set; }
|
public int port { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string listen { get; set; }
|
public string listen { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string protocol { get; set; }
|
public string protocol { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public Sniffing4Ray sniffing { get; set; }
|
public Sniffing4Ray sniffing { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public Inboundsettings4Ray settings { get; set; }
|
public Inboundsettings4Ray settings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public StreamSettings4Ray streamSettings { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Inboundsettings4Ray
|
public class Inboundsettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
public string? auth { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string auth { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public bool? udp { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public bool udp { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public string? ip { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string ip { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public string? address { get; set; }
|
||||||
/// api 使用
|
|
||||||
/// </summary>
|
|
||||||
public string address { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public List<UsersItem4Ray>? clients { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public List<UsersItem4Ray> clients { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public string? decryption { get; set; }
|
||||||
/// VLESS
|
|
||||||
/// </summary>
|
|
||||||
public string decryption { get; set; }
|
|
||||||
|
|
||||||
public bool allowTransparent { get; set; }
|
public bool? allowTransparent { get; set; }
|
||||||
|
|
||||||
public List<AccountsItem4Ray> accounts { get; set; }
|
public List<AccountsItem4Ray>? accounts { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UsersItem4Ray
|
public class UsersItem4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
public string? id { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public int? alterId { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int alterId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public string? email { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string email { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public string? security { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string security { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public string? encryption { get; set; }
|
||||||
/// VLESS
|
|
||||||
/// </summary>
|
|
||||||
public string encryption { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// VLESS
|
|
||||||
/// </summary>
|
|
||||||
public string? flow { get; set; }
|
public string? flow { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,57 +109,27 @@ namespace ServiceLib.Models
|
|||||||
|
|
||||||
public class Outbounds4Ray
|
public class Outbounds4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 默认值agentout
|
|
||||||
/// </summary>
|
|
||||||
public string tag { get; set; }
|
public string tag { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string protocol { get; set; }
|
public string protocol { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public Outboundsettings4Ray settings { get; set; }
|
public Outboundsettings4Ray settings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public StreamSettings4Ray streamSettings { get; set; }
|
public StreamSettings4Ray streamSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public Mux4Ray mux { get; set; }
|
public Mux4Ray mux { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Outboundsettings4Ray
|
public class Outboundsettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public List<VnextItem4Ray>? vnext { get; set; }
|
public List<VnextItem4Ray>? vnext { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
public List<ServersItem4Ray>? servers { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public List<ServersItem4Ray> servers { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public Response4Ray? response { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public Response4Ray response { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string domainStrategy { get; set; }
|
public string domainStrategy { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int? userLevel { get; set; }
|
public int? userLevel { get; set; }
|
||||||
|
|
||||||
public FragmentItem4Ray? fragment { get; set; }
|
public FragmentItem4Ray? fragment { get; set; }
|
||||||
@@ -259,85 +137,40 @@ namespace ServiceLib.Models
|
|||||||
|
|
||||||
public class VnextItem4Ray
|
public class VnextItem4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string address { get; set; }
|
public string address { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int port { get; set; }
|
public int port { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public List<UsersItem4Ray> users { get; set; }
|
public List<UsersItem4Ray> users { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ServersItem4Ray
|
public class ServersItem4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string email { get; set; }
|
public string email { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string address { get; set; }
|
public string address { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string? method { get; set; }
|
public string? method { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public bool? ota { get; set; }
|
public bool? ota { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string? password { get; set; }
|
public string? password { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int port { get; set; }
|
public int port { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int? level { get; set; }
|
public int? level { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// trojan
|
|
||||||
/// </summary>
|
|
||||||
public string flow { get; set; }
|
public string flow { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public List<SocksUsersItem4Ray> users { get; set; }
|
public List<SocksUsersItem4Ray> users { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SocksUsersItem4Ray
|
public class SocksUsersItem4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string user { get; set; }
|
public string user { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string pass { get; set; }
|
public string pass { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int? level { get; set; }
|
public int? level { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,17 +184,11 @@ namespace ServiceLib.Models
|
|||||||
|
|
||||||
public class Response4Ray
|
public class Response4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Dns4Ray
|
public class Dns4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public List<string> servers { get; set; }
|
public List<string> servers { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,19 +200,10 @@ namespace ServiceLib.Models
|
|||||||
|
|
||||||
public class Routing4Ray
|
public class Routing4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string domainStrategy { get; set; }
|
public string domainStrategy { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string? domainMatcher { get; set; }
|
public string? domainMatcher { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public List<RulesItem4Ray> rules { get; set; }
|
public List<RulesItem4Ray> rules { get; set; }
|
||||||
|
|
||||||
public List<BalancersItem4Ray>? balancers { get; set; }
|
public List<BalancersItem4Ray>? balancers { get; set; }
|
||||||
@@ -426,87 +244,39 @@ namespace ServiceLib.Models
|
|||||||
|
|
||||||
public class StreamSettings4Ray
|
public class StreamSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string network { get; set; }
|
public string network { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string security { get; set; }
|
public string security { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public TlsSettings4Ray? tlsSettings { get; set; }
|
public TlsSettings4Ray? tlsSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tcp传输额外设置
|
|
||||||
/// </summary>
|
|
||||||
public TcpSettings4Ray? tcpSettings { get; set; }
|
public TcpSettings4Ray? tcpSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Kcp传输额外设置
|
|
||||||
/// </summary>
|
|
||||||
public KcpSettings4Ray? kcpSettings { get; set; }
|
public KcpSettings4Ray? kcpSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ws传输额外设置
|
|
||||||
/// </summary>
|
|
||||||
public WsSettings4Ray? wsSettings { get; set; }
|
public WsSettings4Ray? wsSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public HttpupgradeSettings4Ray? httpupgradeSettings { get; set; }
|
public HttpupgradeSettings4Ray? httpupgradeSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
public XhttpSettings4Ray? xhttpSettings { get; set; }
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public SplithttpSettings4Ray? splithttpSettings { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// h2传输额外设置
|
|
||||||
/// </summary>
|
|
||||||
public HttpSettings4Ray? httpSettings { get; set; }
|
public HttpSettings4Ray? httpSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// QUIC
|
|
||||||
/// </summary>
|
|
||||||
public QuicSettings4Ray? quicSettings { get; set; }
|
public QuicSettings4Ray? quicSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// VLESS only
|
|
||||||
/// </summary>
|
|
||||||
public TlsSettings4Ray? realitySettings { get; set; }
|
public TlsSettings4Ray? realitySettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// grpc
|
|
||||||
/// </summary>
|
|
||||||
public GrpcSettings4Ray? grpcSettings { get; set; }
|
public GrpcSettings4Ray? grpcSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// sockopt
|
|
||||||
/// </summary>
|
|
||||||
public Sockopt4Ray? sockopt { get; set; }
|
public Sockopt4Ray? sockopt { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TlsSettings4Ray
|
public class TlsSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 是否允许不安全连接(用于客户端)
|
|
||||||
/// </summary>
|
|
||||||
public bool? allowInsecure { get; set; }
|
public bool? allowInsecure { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string? serverName { get; set; }
|
public string? serverName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public List<string>? alpn { get; set; }
|
public List<string>? alpn { get; set; }
|
||||||
|
|
||||||
public string? fingerprint { get; set; }
|
public string? fingerprint { get; set; }
|
||||||
@@ -519,157 +289,94 @@ namespace ServiceLib.Models
|
|||||||
|
|
||||||
public class TcpSettings4Ray
|
public class TcpSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 数据包头部伪装设置
|
|
||||||
/// </summary>
|
|
||||||
public Header4Ray header { get; set; }
|
public Header4Ray header { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Header4Ray
|
public class Header4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 伪装
|
|
||||||
/// </summary>
|
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 结构复杂,直接存起来
|
|
||||||
/// </summary>
|
|
||||||
public object request { get; set; }
|
public object request { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 结构复杂,直接存起来
|
|
||||||
/// </summary>
|
|
||||||
public object response { get; set; }
|
public object response { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class KcpSettings4Ray
|
public class KcpSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int mtu { get; set; }
|
public int mtu { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int tti { get; set; }
|
public int tti { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int uplinkCapacity { get; set; }
|
public int uplinkCapacity { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int downlinkCapacity { get; set; }
|
public int downlinkCapacity { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public bool congestion { get; set; }
|
public bool congestion { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int readBufferSize { get; set; }
|
public int readBufferSize { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public int writeBufferSize { get; set; }
|
public int writeBufferSize { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public Header4Ray header { get; set; }
|
public Header4Ray header { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string seed { get; set; }
|
public string seed { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WsSettings4Ray
|
public class WsSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string path { get; set; }
|
public string path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public Headers4Ray headers { get; set; }
|
public Headers4Ray headers { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Headers4Ray
|
public class Headers4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string Host { get; set; }
|
public string Host { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户代理
|
|
||||||
/// </summary>
|
|
||||||
[JsonPropertyName("User-Agent")]
|
[JsonPropertyName("User-Agent")]
|
||||||
public string UserAgent { get; set; }
|
public string UserAgent { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HttpupgradeSettings4Ray
|
public class HttpupgradeSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string? path { get; set; }
|
public string? path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string? host { get; set; }
|
public string? host { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SplithttpSettings4Ray
|
public class XhttpSettings4Ray
|
||||||
{
|
{
|
||||||
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? scMaxEachPostBytes { get; set; }
|
||||||
|
public string? scMaxConcurrentPosts { get; set; }
|
||||||
|
public string? scMinPostsIntervalMs { get; set; }
|
||||||
|
public Xmux4Ray? xmux { get; set; }
|
||||||
|
public object? extra { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public int? maxUploadSize { get; set; }
|
public class Xmux4Ray
|
||||||
|
{
|
||||||
public int? maxConcurrentUploads { get; set; }
|
public int? maxConcurrency { get; set; }
|
||||||
|
public int? maxConnections { get; set; }
|
||||||
|
public int? cMaxReuseTimes { get; set; }
|
||||||
|
public int? cMaxLifetimeMs { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HttpSettings4Ray
|
public class HttpSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string? path { get; set; }
|
public string? path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public List<string>? host { get; set; }
|
public List<string>? host { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class QuicSettings4Ray
|
public class QuicSettings4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string security { get; set; }
|
public string security { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string key { get; set; }
|
public string key { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public Header4Ray header { get; set; }
|
public Header4Ray header { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -686,14 +393,8 @@ namespace ServiceLib.Models
|
|||||||
|
|
||||||
public class AccountsItem4Ray
|
public class AccountsItem4Ray
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string user { get; set; }
|
public string user { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string pass { get; set; }
|
public string pass { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
20
v2rayN/ServiceLib/Models/V2rayMetricsVars.cs
Normal file
20
v2rayN/ServiceLib/Models/V2rayMetricsVars.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace ServiceLib.Models
|
||||||
|
{
|
||||||
|
internal class V2rayMetricsVars
|
||||||
|
{
|
||||||
|
public V2rayMetricsVarsStats? stats { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class V2rayMetricsVarsStats
|
||||||
|
{
|
||||||
|
public Hashtable? outbound { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class V2rayMetricsVarsLink
|
||||||
|
{
|
||||||
|
public long downlink { get; set; }
|
||||||
|
public long uplink { get; set; }
|
||||||
|
}
|
||||||
85
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
85
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
@@ -447,6 +447,15 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Remarks Memo 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string LvMemo {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("LvMemo", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 More URLs, separated by commas; Subscription conversion will be invalid 的本地化字符串。
|
/// 查找类似 More URLs, separated by commas; Subscription conversion will be invalid 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -870,6 +879,15 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Are you sure to exit? 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuExitTips {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuExitTips", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Export selected server for complete configuration 的本地化字符串。
|
/// 查找类似 Export selected server for complete configuration 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -2860,6 +2878,15 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Install the font to the system and restart the settings 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbSettingsCurrentFontFamilyLinuxTip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbSettingsCurrentFontFamilyLinuxTip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Copy the font TTF/TTC file to the directory guiFonts, restart the settings 的本地化字符串。
|
/// 查找类似 Copy the font TTF/TTC file to the directory guiFonts, restart the settings 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -3121,6 +3148,42 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Linux system sudo password 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbSettingsLinuxSudoPassword {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbSettingsLinuxSudoPassword", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Please set the sudo password in Tun mode settings first 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbSettingsLinuxSudoPasswordIsEmpty {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbSettingsLinuxSudoPasswordIsEmpty", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Please do not run this app with sudo 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbSettingsLinuxSudoPasswordNotSudoRunApp {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbSettingsLinuxSudoPasswordNotSudoRunApp", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 The password is encrypted and stored only in local files. 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbSettingsLinuxSudoPasswordTip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbSettingsLinuxSudoPasswordTip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Enable Log 的本地化字符串。
|
/// 查找类似 Enable Log 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -3634,6 +3697,15 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 XHTTP Extra raw JSON, format: { XHTTPObject } 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TransportExtraTip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TransportExtraTip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 *tcp camouflage type 的本地化字符串。
|
/// 查找类似 *tcp camouflage type 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -3671,7 +3743,16 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 *ws/httpupgrade/splithttp path 的本地化字符串。
|
/// 查找类似 *xhttp mode 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TransportHeaderTypeTip5 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TransportHeaderTypeTip5", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 *ws/httpupgrade/xhttp path 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TransportPathTip1 {
|
public static string TransportPathTip1 {
|
||||||
get {
|
get {
|
||||||
@@ -3725,7 +3806,7 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 *ws/httpupgrade/splithttp host 的本地化字符串。
|
/// 查找类似 *ws/httpupgrade/xhttp host 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string TransportRequestHostTip2 {
|
public static string TransportRequestHostTip2 {
|
||||||
get {
|
get {
|
||||||
|
|||||||
@@ -1033,4 +1033,358 @@
|
|||||||
<data name="menuProxiesSelectActivity" xml:space="preserve">
|
<data name="menuProxiesSelectActivity" xml:space="preserve">
|
||||||
<value>Select active node (Enter)</value>
|
<value>Select active node (Enter)</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuRemoteBackup" xml:space="preserve">
|
||||||
|
<value>Backup to remote (WebDAV)</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuRemoteRestore" xml:space="preserve">
|
||||||
|
<value>Restore from remote (WebDAV)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
|
||||||
|
<value>Default domain strategy for outbound</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
|
||||||
|
<value>Multi-Server lowest latency</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
|
||||||
|
<value>Main layout orientation(Require restart)</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuSetDefaultLoadBalanceServer" xml:space="preserve">
|
||||||
|
<value>Multi-server load balancing</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
|
||||||
|
<value>Outbound DNS address</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
|
||||||
|
<value>Auto column width adjustment</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExport2ShareUrlBase64" xml:space="preserve">
|
||||||
|
<value>Export Base64-encoded Share Links to Clipboard</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExport2ClientConfigClipboard" xml:space="preserve">
|
||||||
|
<value>Export selected server for complete configuration to clipboard</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuShowOrHideMainWindow" xml:space="preserve">
|
||||||
|
<value>Show or hide the main window</value>
|
||||||
|
</data>
|
||||||
|
<data name="UpdateStandalonePackageTip" xml:space="preserve">
|
||||||
|
<value>You are currently running a standalone package, please manually download the SelfContained.7z file to unzip and overwrite it!</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPreSocksPort4Sub" xml:space="preserve">
|
||||||
|
<value>Custom config socks port</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuBackupAndRestore" xml:space="preserve">
|
||||||
|
<value>Backup and Restore</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuLocalBackup" xml:space="preserve">
|
||||||
|
<value>Backup to local</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuLocalRestore" xml:space="preserve">
|
||||||
|
<value>Restore from local</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuLocalBackupAndRestore" xml:space="preserve">
|
||||||
|
<value>Local</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuRemoteBackupAndRestore" xml:space="preserve">
|
||||||
|
<value>Remote (WebDAV)</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvWebDavUrl" xml:space="preserve">
|
||||||
|
<value>WebDav Url</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvWebDavUserName" xml:space="preserve">
|
||||||
|
<value>WebDav User Name</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvWebDavPassword" xml:space="preserve">
|
||||||
|
<value>WebDav Password</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvWebDavCheck" xml:space="preserve">
|
||||||
|
<value>WebDav Check</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvWebDavDirName" xml:space="preserve">
|
||||||
|
<value>Remote folder name (optional)</value>
|
||||||
|
</data>
|
||||||
|
<data name="LocalRestoreInvalidZipTips" xml:space="preserve">
|
||||||
|
<value>Invalid backup file</value>
|
||||||
|
</data>
|
||||||
|
<data name="ConnectionsHostFilterTitle" xml:space="preserve">
|
||||||
|
<value>Host filter</value>
|
||||||
|
</data>
|
||||||
|
<data name="TipActiveServer" xml:space="preserve">
|
||||||
|
<value>Active</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuStorageUI" xml:space="preserve">
|
||||||
|
<value>Save Interface Layout</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
|
||||||
|
<value>Geo files source (optional)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsSrsFilesSource" xml:space="preserve">
|
||||||
|
<value>sing-box ruleset files source (optional)</value>
|
||||||
|
</data>
|
||||||
|
<data name="UpgradeAppNotExistTip" xml:space="preserve">
|
||||||
|
<value>UpgradeApp does not exist</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsRoutingRulesSource" xml:space="preserve">
|
||||||
|
<value>Routing rules source (optional)</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuRegionalPresets" xml:space="preserve">
|
||||||
|
<value>Regional presets setting</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuRegionalPresetsDefault" xml:space="preserve">
|
||||||
|
<value>Default</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
||||||
|
<value>Russia</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
||||||
|
<value>Users in China region can ignore this item</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||||
|
<value>Scan QR code in the image</value>
|
||||||
|
</data>
|
||||||
|
<data name="InvalidUrlTip" xml:space="preserve">
|
||||||
|
<value>Invalid address (Url)</value>
|
||||||
|
</data>
|
||||||
|
<data name="InsecureUrlProtocol" xml:space="preserve">
|
||||||
|
<value>Please do not use the insecure HTTP protocol subscription address</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
|
||||||
|
<value>Install the font to the system and restart the settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExitTips" xml:space="preserve">
|
||||||
|
<value>Are you sure to exit?</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvMemo" xml:space="preserve">
|
||||||
|
<value>Remarks Memo</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLogEnabledToFile" xml:space="preserve">
|
||||||
|
<value>Enable logging to file</value>
|
||||||
|
</data>
|
||||||
|
<data name="MsgSkipSubscriptionUpdate" xml:space="preserve">
|
||||||
|
<value>Updates are not enabled, skip this subscription</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuRebootAsAdmin" xml:space="preserve">
|
||||||
|
<value>Restart as Administrator</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvMoreUrl" xml:space="preserve">
|
||||||
|
<value>More URLs, separated by commas; Subscription conversion will be invalid</value>
|
||||||
|
</data>
|
||||||
|
<data name="SpeedDisplayText" xml:space="preserve">
|
||||||
|
<value>{0} : {1}/s↑ | {2}/s↓</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvAutoUpdateInterval" xml:space="preserve">
|
||||||
|
<value>Automatic update interval (minutes)</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvConvertTarget" xml:space="preserve">
|
||||||
|
<value>Convert target type</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvConvertTargetTip" xml:space="preserve">
|
||||||
|
<value>Please leave blank if no conversion is required</value>
|
||||||
|
</data>
|
||||||
|
<data name="TipDisplayLog" xml:space="preserve">
|
||||||
|
<value>Please turn off when there is an abnormal disconnection</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuDNSSetting" xml:space="preserve">
|
||||||
|
<value>DNS Settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbDnsSingboxObjectDoc" xml:space="preserve">
|
||||||
|
<value>Please fill in DNS Structure, Click to view the document</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingDnsImportDefConfig" xml:space="preserve">
|
||||||
|
<value>Click to import default DNS config</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbdomainStrategy4Singbox" xml:space="preserve">
|
||||||
|
<value>sing-box domain strategy</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsMux4SboxProtocol" xml:space="preserve">
|
||||||
|
<value>sing-box Mux Protocol</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleProcess" xml:space="preserve">
|
||||||
|
<value>Full process name (Tun mode)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleIP" xml:space="preserve">
|
||||||
|
<value>IP or IP CIDR</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleDomain" xml:space="preserve">
|
||||||
|
<value>Domain</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve">
|
||||||
|
<value>sing-box DNS settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="SpeedtestingWait" xml:space="preserve">
|
||||||
|
<value>Waiting for testing (press ESC to terminate)...</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSpiderX" xml:space="preserve">
|
||||||
|
<value>SpiderX</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbShortId" xml:space="preserve">
|
||||||
|
<value>ShortId</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuMoveToGroup" xml:space="preserve">
|
||||||
|
<value>Move to group</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
|
||||||
|
<value>Enable Server Drag Drop Sort(Require restart)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAutoRefresh" xml:space="preserve">
|
||||||
|
<value>AutoRefresh</value>
|
||||||
|
</data>
|
||||||
|
<data name="SpeedtestingSkip" xml:space="preserve">
|
||||||
|
<value>Skip test</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditServer" xml:space="preserve">
|
||||||
|
<value>Edit Server (Ctrl+D)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsDoubleClick2Activate" xml:space="preserve">
|
||||||
|
<value>Double-click server make active</value>
|
||||||
|
</data>
|
||||||
|
<data name="SpeedtestingCompleted" xml:space="preserve">
|
||||||
|
<value>Test completed</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsDefFingerprint" xml:space="preserve">
|
||||||
|
<value>Default TLS fingerprint</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsCurrentFontFamily" xml:space="preserve">
|
||||||
|
<value>FontFamily(Require restart)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve">
|
||||||
|
<value>Copy the font TTF/TTC file to the directory guiFonts, restart the settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsSocksPortTip" xml:space="preserve">
|
||||||
|
<value>http port = +1; Pac port = +4; *ray API port = +5; mihomo API port = +6;</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsStartBootTip" xml:space="preserve">
|
||||||
|
<value>Set this with admin privileges, get admin privileges after startup</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsFontSize" xml:space="preserve">
|
||||||
|
<value>Font Size</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
|
||||||
|
<value>SpeedTest Single Timeout Value</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
|
||||||
|
<value>SpeedTest URL</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuMoveTo" xml:space="preserve">
|
||||||
|
<value>Move up and down</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPublicKey" xml:space="preserve">
|
||||||
|
<value>PublicKey</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddHysteria2Server" xml:space="preserve">
|
||||||
|
<value>Add [Hysteria2] server</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
|
||||||
|
<value>Hysteria Max bandwidth (Up/Dw)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
|
||||||
|
<value>Follow System Theme</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddTuicServer" xml:space="preserve">
|
||||||
|
<value>Add [TUIC] server</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableUpdateSubOnlyRemarksExist" xml:space="preserve">
|
||||||
|
<value>Updating subscription, only determine remarks exists</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuProxiesReload" xml:space="preserve">
|
||||||
|
<value>Refresh Proxies</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingNetwork" xml:space="preserve">
|
||||||
|
<value>Network</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingType" xml:space="preserve">
|
||||||
|
<value>Type</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportRequestHostTip5" xml:space="preserve">
|
||||||
|
<value>*grpc Authority</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddHttpServer" xml:space="preserve">
|
||||||
|
<value>Add [HTTP] server</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsSpeedPingTestUrl" xml:space="preserve">
|
||||||
|
<value>Speed Ping Test URL</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||||
|
<value>Use Xray and enable non-Tun mode, which conflicts with the group previous proxy</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
|
||||||
|
<value>Custom the rule-set of sing-box</value>
|
||||||
|
</data>
|
||||||
|
<data name="NeedRebootTips" xml:space="preserve">
|
||||||
|
<value>Successful operation. Click the settings menu to reboot the app.</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuOpenTheFileLocation" xml:space="preserve">
|
||||||
|
<value>Open the storage location</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingChain" xml:space="preserve">
|
||||||
|
<value>Chain</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingHost" xml:space="preserve">
|
||||||
|
<value>Host</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
|
||||||
|
<value>Use System Hosts</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||||
|
<value>Enable fragment</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAutoScrollToEnd" xml:space="preserve">
|
||||||
|
<value>Auto ScrollToEnd</value>
|
||||||
|
</data>
|
||||||
|
<data name="SpeedtestingStop" xml:space="preserve">
|
||||||
|
<value>Test terminating...</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvNextProfile" xml:space="preserve">
|
||||||
|
<value>Next proxy remarks</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPath7" xml:space="preserve">
|
||||||
|
<value>obfs password</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbHeaderType8" xml:space="preserve">
|
||||||
|
<value>Congestion control</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvPrevProfile" xml:space="preserve">
|
||||||
|
<value>Previous proxy remarks</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbLocalAddress" xml:space="preserve">
|
||||||
|
<value>Address(Ip,Ipv6)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbReserved" xml:space="preserve">
|
||||||
|
<value>Reserved(2,3,4)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPrivateKey" xml:space="preserve">
|
||||||
|
<value>PrivateKey</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddWireguardServer" xml:space="preserve">
|
||||||
|
<value>Add [WireGuard] server</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
|
||||||
|
<value>Enable IPv6 Address</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableExInbound" xml:space="preserve">
|
||||||
|
<value>Enable additional Inbound</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvPrevProfileTip" xml:space="preserve">
|
||||||
|
<value>Please make sure the remarks exists and is unique</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRuleMatchingTips" xml:space="preserve">
|
||||||
|
<value>(Domain or IP or ProcName) and Port and Protocol and InboundTag => OutboundTag</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
|
||||||
|
<value>Linux system sudo password</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||||
|
<value>The password is encrypted and stored only in local files.</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
||||||
|
<value>Please set the sudo password in Tun mode settings first</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||||
|
<value>Please do not run this app with sudo</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||||
|
<value>*xhttp mode</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportExtraTip" xml:space="preserve">
|
||||||
|
<value>XHTTP Extra raw JSON, format: { XHTTPObject }</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -344,7 +344,7 @@
|
|||||||
<value>Please fill in the correct custom DNS</value>
|
<value>Please fill in the correct custom DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportPathTip1" xml:space="preserve">
|
<data name="TransportPathTip1" xml:space="preserve">
|
||||||
<value>*ws/httpupgrade/splithttp path</value>
|
<value>*ws/httpupgrade/xhttp path</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportPathTip2" xml:space="preserve">
|
<data name="TransportPathTip2" xml:space="preserve">
|
||||||
<value>*h2 path</value>
|
<value>*h2 path</value>
|
||||||
@@ -359,7 +359,7 @@
|
|||||||
<value>*http host Separated by commas (,)</value>
|
<value>*http host Separated by commas (,)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportRequestHostTip2" xml:space="preserve">
|
<data name="TransportRequestHostTip2" xml:space="preserve">
|
||||||
<value>*ws/httpupgrade/splithttp host</value>
|
<value>*ws/httpupgrade/xhttp host</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportRequestHostTip3" xml:space="preserve">
|
<data name="TransportRequestHostTip3" xml:space="preserve">
|
||||||
<value>*h2 host Separated by commas (,)</value>
|
<value>*h2 host Separated by commas (,)</value>
|
||||||
@@ -1360,4 +1360,31 @@
|
|||||||
<data name="InsecureUrlProtocol" xml:space="preserve">
|
<data name="InsecureUrlProtocol" xml:space="preserve">
|
||||||
<value>Please do not use the insecure HTTP protocol subscription address</value>
|
<value>Please do not use the insecure HTTP protocol subscription address</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
|
||||||
|
<value>Install the font to the system and restart the settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExitTips" xml:space="preserve">
|
||||||
|
<value>Are you sure to exit?</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvMemo" xml:space="preserve">
|
||||||
|
<value>Remarks Memo</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
|
||||||
|
<value>Linux system sudo password</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||||
|
<value>The password is encrypted and stored only in local files.</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
||||||
|
<value>Please set the sudo password in Tun mode settings first</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||||
|
<value>Please do not run this app with sudo</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||||
|
<value>*xhttp mode</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportExtraTip" xml:space="preserve">
|
||||||
|
<value>XHTTP Extra raw JSON, format: { XHTTPObject }</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -1046,6 +1046,345 @@
|
|||||||
<value>Россия</value>
|
<value>Россия</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
||||||
<value>Используйте Настройки -> Региональные пресеты вместо изменения этого поля</value>
|
<value>Используйте Настройки -> Региональные пресеты вместо изменения этого поля</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvMemo" xml:space="preserve">
|
||||||
|
<value>Remarks Memo</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsSpeedPingTestUrl" xml:space="preserve">
|
||||||
|
<value>Speed Ping Test URL</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuProxiesDelaytestPart" xml:space="preserve">
|
||||||
|
<value>Part Node Latency Test</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuProxiesReload" xml:space="preserve">
|
||||||
|
<value>Refresh Proxies</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAutoScrollToEnd" xml:space="preserve">
|
||||||
|
<value>Auto ScrollToEnd</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuProxiesSelectActivity" xml:space="preserve">
|
||||||
|
<value>Select active node (Enter)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRuleMatchingTips" xml:space="preserve">
|
||||||
|
<value>(Domain or IP or ProcName) and Port and Protocol and InboundTag => OutboundTag</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPath7" xml:space="preserve">
|
||||||
|
<value>obfs password</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbLocalAddress" xml:space="preserve">
|
||||||
|
<value>Address(Ip,Ipv6)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
|
||||||
|
<value>Default domain strategy for outbound</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
|
||||||
|
<value>Multi-Server lowest latency</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
|
||||||
|
<value>Main layout orientation(Require restart)</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuSetDefaultLoadBalanceServer" xml:space="preserve">
|
||||||
|
<value>Multi-server load balancing</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuProxiesDelaytest" xml:space="preserve">
|
||||||
|
<value>Latency Test</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbReserved" xml:space="preserve">
|
||||||
|
<value>Reserved(2,3,4)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPrivateKey" xml:space="preserve">
|
||||||
|
<value>PrivateKey</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddWireguardServer" xml:space="preserve">
|
||||||
|
<value>Add [WireGuard] server</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
|
||||||
|
<value>Auto column width adjustment</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExport2ShareUrlBase64" xml:space="preserve">
|
||||||
|
<value>Export Base64-encoded Share Links to Clipboard</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingDelay" xml:space="preserve">
|
||||||
|
<value>Delay</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableExInbound" xml:space="preserve">
|
||||||
|
<value>Enable additional Inbound</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvPrevProfileTip" xml:space="preserve">
|
||||||
|
<value>Please make sure the remarks exists and is unique</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExport2ClientConfigClipboard" xml:space="preserve">
|
||||||
|
<value>Export selected server for complete configuration to clipboard</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvNextProfile" xml:space="preserve">
|
||||||
|
<value>Next proxy remarks</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuShowOrHideMainWindow" xml:space="preserve">
|
||||||
|
<value>Show or hide the main window</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvPrevProfile" xml:space="preserve">
|
||||||
|
<value>Previous proxy remarks</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbHeaderType8" xml:space="preserve">
|
||||||
|
<value>Congestion control</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
|
||||||
|
<value>Outbound DNS address</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableUpdateSubOnlyRemarksExist" xml:space="preserve">
|
||||||
|
<value>Updating subscription, only determine remarks exists</value>
|
||||||
|
</data>
|
||||||
|
<data name="SpeedtestingStop" xml:space="preserve">
|
||||||
|
<value>Test terminating...</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportRequestHostTip5" xml:space="preserve">
|
||||||
|
<value>*grpc Authority</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingDefault" xml:space="preserve">
|
||||||
|
<value>Default</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingChain" xml:space="preserve">
|
||||||
|
<value>Chain</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSorting" xml:space="preserve">
|
||||||
|
<value>Sorting</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuOpenTheFileLocation" xml:space="preserve">
|
||||||
|
<value>Open the storage location</value>
|
||||||
|
</data>
|
||||||
|
<data name="NeedRebootTips" xml:space="preserve">
|
||||||
|
<value>Successful operation. Click the settings menu to reboot the app.</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
|
||||||
|
<value>Custom the rule-set of sing-box</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingDownTraffic" xml:space="preserve">
|
||||||
|
<value>Download Traffic</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingHost" xml:space="preserve">
|
||||||
|
<value>Host</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingName" xml:space="preserve">
|
||||||
|
<value>Name</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingNetwork" xml:space="preserve">
|
||||||
|
<value>Network</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingTime" xml:space="preserve">
|
||||||
|
<value>Time</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingType" xml:space="preserve">
|
||||||
|
<value>Type</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
|
||||||
|
<value>Enable cache file for sing-box (ruleset files)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingUpSpeed" xml:space="preserve">
|
||||||
|
<value>Upload Speed</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingUpTraffic" xml:space="preserve">
|
||||||
|
<value>Upload Traffic</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbConnections" xml:space="preserve">
|
||||||
|
<value>Connections</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuConnectionClose" xml:space="preserve">
|
||||||
|
<value>Close Connection</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuConnectionCloseAll" xml:space="preserve">
|
||||||
|
<value>Close All Connection</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbProxies" xml:space="preserve">
|
||||||
|
<value>Proxies</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuRulemode" xml:space="preserve">
|
||||||
|
<value>Rule mode</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuModeDirect" xml:space="preserve">
|
||||||
|
<value>Direct</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuModeGlobal" xml:space="preserve">
|
||||||
|
<value>Global</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuModeNothing" xml:space="preserve">
|
||||||
|
<value>Do not change</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||||
|
<value>Enable fragment</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
|
||||||
|
<value>Use Xray and enable non-Tun mode, which conflicts with the group previous proxy</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuModeRule" xml:space="preserve">
|
||||||
|
<value>Rule</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddHttpServer" xml:space="preserve">
|
||||||
|
<value>Add [HTTP] server</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddTuicServer" xml:space="preserve">
|
||||||
|
<value>Add [TUIC] server</value>
|
||||||
|
</data>
|
||||||
|
<data name="UpdateStandalonePackageTip" xml:space="preserve">
|
||||||
|
<value>You are currently running a standalone package, please manually download the SelfContained.7z file to unzip and overwrite it!</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
|
||||||
|
<value>Enable IPv6 Address</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPreSocksPort4Sub" xml:space="preserve">
|
||||||
|
<value>Custom config socks port</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvWebDavCheck" xml:space="preserve">
|
||||||
|
<value>WebDav Check</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleDomain" xml:space="preserve">
|
||||||
|
<value>Domain</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleIP" xml:space="preserve">
|
||||||
|
<value>IP or IP CIDR</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbRoutingRuleProcess" xml:space="preserve">
|
||||||
|
<value>Full process name (Tun mode)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsMux4SboxProtocol" xml:space="preserve">
|
||||||
|
<value>sing-box Mux Protocol</value>
|
||||||
|
</data>
|
||||||
|
<data name="LocalRestoreInvalidZipTips" xml:space="preserve">
|
||||||
|
<value>Invalid backup file</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbdomainStrategy4Singbox" xml:space="preserve">
|
||||||
|
<value>sing-box domain strategy</value>
|
||||||
|
</data>
|
||||||
|
<data name="ConnectionsHostFilterTitle" xml:space="preserve">
|
||||||
|
<value>Host filter</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingDnsImportDefConfig" xml:space="preserve">
|
||||||
|
<value>Click to import default DNS config</value>
|
||||||
|
</data>
|
||||||
|
<data name="TipActiveServer" xml:space="preserve">
|
||||||
|
<value>Active</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbDnsSingboxObjectDoc" xml:space="preserve">
|
||||||
|
<value>Please fill in DNS Structure, Click to view the document</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvConvertTargetTip" xml:space="preserve">
|
||||||
|
<value>Please leave blank if no conversion is required</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvConvertTarget" xml:space="preserve">
|
||||||
|
<value>Convert target type</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuStorageUI" xml:space="preserve">
|
||||||
|
<value>Save Interface Layout</value>
|
||||||
|
</data>
|
||||||
|
<data name="SpeedDisplayText" xml:space="preserve">
|
||||||
|
<value>{0} : {1}/s↑ | {2}/s↓</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvMoreUrl" xml:space="preserve">
|
||||||
|
<value>More URLs, separated by commas; Subscription conversion will be invalid</value>
|
||||||
|
</data>
|
||||||
|
<data name="MsgSkipSubscriptionUpdate" xml:space="preserve">
|
||||||
|
<value>Updates are not enabled, skip this subscription</value>
|
||||||
|
</data>
|
||||||
|
<data name="UpgradeAppNotExistTip" xml:space="preserve">
|
||||||
|
<value>UpgradeApp does not exist</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||||
|
<value>Scan QR code in the image</value>
|
||||||
|
</data>
|
||||||
|
<data name="TipDisplayLog" xml:space="preserve">
|
||||||
|
<value>Please turn off when there is an abnormal disconnection</value>
|
||||||
|
</data>
|
||||||
|
<data name="SpeedtestingWait" xml:space="preserve">
|
||||||
|
<value>Waiting for testing (press ESC to terminate)...</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSpiderX" xml:space="preserve">
|
||||||
|
<value>SpiderX</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbShortId" xml:space="preserve">
|
||||||
|
<value>ShortId</value>
|
||||||
|
</data>
|
||||||
|
<data name="InvalidUrlTip" xml:space="preserve">
|
||||||
|
<value>Invalid address (Url)</value>
|
||||||
|
</data>
|
||||||
|
<data name="InsecureUrlProtocol" xml:space="preserve">
|
||||||
|
<value>Please do not use the insecure HTTP protocol subscription address</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPublicKey" xml:space="preserve">
|
||||||
|
<value>PublicKey</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuMoveTo" xml:space="preserve">
|
||||||
|
<value>Move up and down</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsSocksPortTip" xml:space="preserve">
|
||||||
|
<value>http port = +1; Pac port = +4; *ray API port = +5; mihomo API port = +6;</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
|
||||||
|
<value>Install the font to the system and restart the settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddHysteria2Server" xml:space="preserve">
|
||||||
|
<value>Add [Hysteria2] server</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvWebDavPassword" xml:space="preserve">
|
||||||
|
<value>WebDav Password</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvWebDavDirName" xml:space="preserve">
|
||||||
|
<value>Remote folder name (optional)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingDownSpeed" xml:space="preserve">
|
||||||
|
<value>Download Speed</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuRemoteRestore" xml:space="preserve">
|
||||||
|
<value>Restore from remote (WebDAV)</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuRemoteBackup" xml:space="preserve">
|
||||||
|
<value>Backup to remote (WebDAV)</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvWebDavUserName" xml:space="preserve">
|
||||||
|
<value>WebDav User Name</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuLocalRestore" xml:space="preserve">
|
||||||
|
<value>Restore from local</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuLocalBackup" xml:space="preserve">
|
||||||
|
<value>Backup to local</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
|
||||||
|
<value>Use System Hosts</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuBackupAndRestore" xml:space="preserve">
|
||||||
|
<value>Backup and Restore</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuLocalBackupAndRestore" xml:space="preserve">
|
||||||
|
<value>Local</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExitTips" xml:space="preserve">
|
||||||
|
<value>Are you sure to exit?</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
|
||||||
|
<value>Hysteria Max bandwidth (Up/Dw)</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvWebDavUrl" xml:space="preserve">
|
||||||
|
<value>WebDav Url</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuRemoteBackupAndRestore" xml:space="preserve">
|
||||||
|
<value>Remote (WebDAV)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
|
||||||
|
<value>Linux system sudo password</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||||
|
<value>The password is encrypted and stored only in local files.</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
||||||
|
<value>Please set the sudo password in Tun mode settings first</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||||
|
<value>Please do not run this app with sudo</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||||
|
<value>*xhttp mode</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportExtraTip" xml:space="preserve">
|
||||||
|
<value>XHTTP Extra raw JSON, format: { XHTTPObject }</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -344,7 +344,7 @@
|
|||||||
<value>请填写正确的自定义DNS</value>
|
<value>请填写正确的自定义DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportPathTip1" xml:space="preserve">
|
<data name="TransportPathTip1" xml:space="preserve">
|
||||||
<value>*ws/httpupgrade/splithttp path</value>
|
<value>*ws/httpupgrade/xhttp path</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportPathTip2" xml:space="preserve">
|
<data name="TransportPathTip2" xml:space="preserve">
|
||||||
<value>*h2 path</value>
|
<value>*h2 path</value>
|
||||||
@@ -359,7 +359,7 @@
|
|||||||
<value>*http host中间逗号(,)分隔</value>
|
<value>*http host中间逗号(,)分隔</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportRequestHostTip2" xml:space="preserve">
|
<data name="TransportRequestHostTip2" xml:space="preserve">
|
||||||
<value>*ws/httpupgrade/splithttp host</value>
|
<value>*ws/httpupgrade/xhttp host</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportRequestHostTip3" xml:space="preserve">
|
<data name="TransportRequestHostTip3" xml:space="preserve">
|
||||||
<value>*h2 host中间逗号(,)分隔</value>
|
<value>*h2 host中间逗号(,)分隔</value>
|
||||||
@@ -1271,7 +1271,7 @@
|
|||||||
<value>显示或隐藏主界面</value>
|
<value>显示或隐藏主界面</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="UpdateStandalonePackageTip" xml:space="preserve">
|
<data name="UpdateStandalonePackageTip" xml:space="preserve">
|
||||||
<value>您当前运行的是独立包,请手动下载 SelfContained.7z文件解压覆盖</value>
|
<value>您当前运行的是独立包,请手动下载 SelfContained.7z文件解压覆盖!</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbPreSocksPort4Sub" xml:space="preserve">
|
<data name="TbPreSocksPort4Sub" xml:space="preserve">
|
||||||
<value>自定义配置的Socks端口</value>
|
<value>自定义配置的Socks端口</value>
|
||||||
@@ -1357,4 +1357,31 @@
|
|||||||
<data name="InsecureUrlProtocol" xml:space="preserve">
|
<data name="InsecureUrlProtocol" xml:space="preserve">
|
||||||
<value>请不要使用不安全的HTTP协议订阅地址</value>
|
<value>请不要使用不安全的HTTP协议订阅地址</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
|
||||||
|
<value>安装字体到系统中,重启设置</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExitTips" xml:space="preserve">
|
||||||
|
<value>是否确定退出?</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvMemo" xml:space="preserve">
|
||||||
|
<value>备注备忘</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
|
||||||
|
<value>Linux系统的sudo密码</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||||
|
<value>密码已加密且只存储在本地文件中,无密码无法开启Tun</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
||||||
|
<value>请先在Tun模式设置中设置sudo密码</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||||
|
<value>请不要用sudo运行本app</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||||
|
<value>*xhttp 模式</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportExtraTip" xml:space="preserve">
|
||||||
|
<value>XHTTP Extra 原始 JSON,格式: { XHTTPObject }</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -301,7 +301,7 @@
|
|||||||
<value>掃描匯入分享链接成功</value>
|
<value>掃描匯入分享链接成功</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TestMeOutput" xml:space="preserve">
|
<data name="TestMeOutput" xml:space="preserve">
|
||||||
<value>目前服務的真連接延遲: {0} ms</value>
|
<value>目前服務的真連線延遲: {0} ms</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="OperationSuccess" xml:space="preserve">
|
<data name="OperationSuccess" xml:space="preserve">
|
||||||
<value>操作成功</value>
|
<value>操作成功</value>
|
||||||
@@ -343,7 +343,7 @@
|
|||||||
<value>請填寫正確的自訂DNS</value>
|
<value>請填寫正確的自訂DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportPathTip1" xml:space="preserve">
|
<data name="TransportPathTip1" xml:space="preserve">
|
||||||
<value>*ws/httpupgrade/splithttp path</value>
|
<value>*ws/httpupgrade/xhttp path</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportPathTip2" xml:space="preserve">
|
<data name="TransportPathTip2" xml:space="preserve">
|
||||||
<value>*h2 path</value>
|
<value>*h2 path</value>
|
||||||
@@ -358,7 +358,7 @@
|
|||||||
<value>*http host中間逗號(,)分隔</value>
|
<value>*http host中間逗號(,)分隔</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportRequestHostTip2" xml:space="preserve">
|
<data name="TransportRequestHostTip2" xml:space="preserve">
|
||||||
<value>*ws/httpupgrade/splithttp host</value>
|
<value>*ws/httpupgrade/xhttp host</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TransportRequestHostTip3" xml:space="preserve">
|
<data name="TransportRequestHostTip3" xml:space="preserve">
|
||||||
<value>*h2 host中間逗號(,)分隔</value>
|
<value>*h2 host中間逗號(,)分隔</value>
|
||||||
@@ -511,7 +511,7 @@
|
|||||||
<value>清除所有服務統計資料</value>
|
<value>清除所有服務統計資料</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuRealPingServer" xml:space="preserve">
|
<data name="menuRealPingServer" xml:space="preserve">
|
||||||
<value>測試伺服器真連接延遲(多選) (Ctrl+R)</value>
|
<value>測試伺服器真連線延遲(多選) (Ctrl+R)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuSortServerResult" xml:space="preserve">
|
<data name="menuSortServerResult" xml:space="preserve">
|
||||||
<value>按測試結果排序</value>
|
<value>按測試結果排序</value>
|
||||||
@@ -683,7 +683,7 @@
|
|||||||
<value>進階代理設定, 協定選擇(可選)</value>
|
<value>進階代理設定, 協定選擇(可選)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsAllowLAN" xml:space="preserve">
|
<data name="TbSettingsAllowLAN" xml:space="preserve">
|
||||||
<value>允許來自區域網路的連接</value>
|
<value>允許來自區域網路的連線</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsAutoHideStartup" xml:space="preserve">
|
<data name="TbSettingsAutoHideStartup" xml:space="preserve">
|
||||||
<value>啟動後隱藏視窗</value>
|
<value>啟動後隱藏視窗</value>
|
||||||
@@ -1106,7 +1106,7 @@
|
|||||||
<value>自动滚动到末尾</value>
|
<value>自动滚动到末尾</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsSpeedPingTestUrl" xml:space="preserve">
|
<data name="TbSettingsSpeedPingTestUrl" xml:space="preserve">
|
||||||
<value>真連接測試地址</value>
|
<value>真連線測試位址</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableUpdateSubOnlyRemarksExist" xml:space="preserve">
|
<data name="TbSettingsEnableUpdateSubOnlyRemarksExist" xml:space="preserve">
|
||||||
<value>更新訂閱時只判斷別名是否存在</value>
|
<value>更新訂閱時只判斷別名是否存在</value>
|
||||||
@@ -1151,7 +1151,7 @@
|
|||||||
<value>顯示或隱藏主介面</value>
|
<value>顯示或隱藏主介面</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="UpdateStandalonePackageTip" xml:space="preserve">
|
<data name="UpdateStandalonePackageTip" xml:space="preserve">
|
||||||
<value>您目前運行的是獨立包,請手動下載 SelfContained.7z檔案解壓縮覆蓋</value>
|
<value>您目前運行的是獨立包,請手動下載 SelfContained.7z檔案解壓縮覆蓋!</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbPreSocksPort4Sub" xml:space="preserve">
|
<data name="TbPreSocksPort4Sub" xml:space="preserve">
|
||||||
<value>自訂設定的Socks端口</value>
|
<value>自訂設定的Socks端口</value>
|
||||||
@@ -1187,7 +1187,7 @@
|
|||||||
<value>WebDav 密碼</value>
|
<value>WebDav 密碼</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LvWebDavUrl" xml:space="preserve">
|
<data name="LvWebDavUrl" xml:space="preserve">
|
||||||
<value>WebDav 伺服器地址</value>
|
<value>WebDav 伺服器位址</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LvWebDavDirName" xml:space="preserve">
|
<data name="LvWebDavDirName" xml:space="preserve">
|
||||||
<value>遠端資料夾名稱(可選)</value>
|
<value>遠端資料夾名稱(可選)</value>
|
||||||
@@ -1205,25 +1205,25 @@
|
|||||||
<value>儲存介面佈局</value>
|
<value>儲存介面佈局</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
|
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
|
||||||
<value>Geo文件來源(可選)</value>
|
<value>Geo檔案來源(可選)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="UpgradeAppNotExistTip" xml:space="preserve">
|
<data name="UpgradeAppNotExistTip" xml:space="preserve">
|
||||||
<value>升级工具App不存在</value>
|
<value>升級工具App不存在</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsSrsFilesSource" xml:space="preserve">
|
<data name="TbSettingsSrsFilesSource" xml:space="preserve">
|
||||||
<value>sing-box ruleset文件來源(可選)</value>
|
<value>sing-box ruleset檔案來源(可選)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsRoutingRulesSource" xml:space="preserve">
|
<data name="TbSettingsRoutingRulesSource" xml:space="preserve">
|
||||||
<value>路由规则集来源(可选)</value>
|
<value>路由規則集來源(可選)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
||||||
<value>中国区域用户可忽略此项</value>
|
<value>中國區域用戶可忽略此項</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuRegionalPresets" xml:space="preserve">
|
<data name="menuRegionalPresets" xml:space="preserve">
|
||||||
<value>区域预置设置</value>
|
<value>區域預置設定</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuRegionalPresetsDefault" xml:space="preserve">
|
<data name="menuRegionalPresetsDefault" xml:space="preserve">
|
||||||
<value>默认区域</value>
|
<value>預設區域</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
||||||
<value>俄羅斯</value>
|
<value>俄羅斯</value>
|
||||||
@@ -1232,9 +1232,156 @@
|
|||||||
<value>掃描圖片中的二維碼</value>
|
<value>掃描圖片中的二維碼</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="InvalidUrlTip" xml:space="preserve">
|
<data name="InvalidUrlTip" xml:space="preserve">
|
||||||
<value>地址(Url)無效</value>
|
<value>位址(Url)無效</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="InsecureUrlProtocol" xml:space="preserve">
|
<data name="InsecureUrlProtocol" xml:space="preserve">
|
||||||
<value>請不要使用不安全的HTTP協定訂閱位址</value>
|
<value>請不要使用不安全的HTTP協定訂閱位址</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
|
||||||
|
<value>安裝字型到系統中,重新啟動設定</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuExitTips" xml:space="preserve">
|
||||||
|
<value>是否確定退出?</value>
|
||||||
|
</data>
|
||||||
|
<data name="LvMemo" xml:space="preserve">
|
||||||
|
<value>備註備忘</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbHeaderType8" xml:space="preserve">
|
||||||
|
<value>擁塞控制算法</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuProxiesSelectActivity" xml:space="preserve">
|
||||||
|
<value>設為活動節點 (Enter)</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuProxiesReload" xml:space="preserve">
|
||||||
|
<value>重新整理</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSorting" xml:space="preserve">
|
||||||
|
<value>排序</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuProxiesDelaytest" xml:space="preserve">
|
||||||
|
<value>延遲測試</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuModeRule" xml:space="preserve">
|
||||||
|
<value>規則</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuModeNothing" xml:space="preserve">
|
||||||
|
<value>随原配置</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuModeGlobal" xml:space="preserve">
|
||||||
|
<value>全局</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuModeDirect" xml:space="preserve">
|
||||||
|
<value>直連</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuRulemode" xml:space="preserve">
|
||||||
|
<value>規則模式</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbProxies" xml:space="preserve">
|
||||||
|
<value>目前代理</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuConnectionCloseAll" xml:space="preserve">
|
||||||
|
<value>關閉所有連線</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
|
||||||
|
<value>Outbound預設解析策略</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuConnectionClose" xml:space="preserve">
|
||||||
|
<value>關閉連線</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingUpTraffic" xml:space="preserve">
|
||||||
|
<value>上傳流量</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingUpSpeed" xml:space="preserve">
|
||||||
|
<value>上傳速度</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingType" xml:space="preserve">
|
||||||
|
<value>類型</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingTime" xml:space="preserve">
|
||||||
|
<value>時間</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingNetwork" xml:space="preserve">
|
||||||
|
<value>網路</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingName" xml:space="preserve">
|
||||||
|
<value>名稱</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingHost" xml:space="preserve">
|
||||||
|
<value>主機</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingDownTraffic" xml:space="preserve">
|
||||||
|
<value>下載流量</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingDownSpeed" xml:space="preserve">
|
||||||
|
<value>下載速度</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingDelay" xml:space="preserve">
|
||||||
|
<value>延遲</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingDefault" xml:space="preserve">
|
||||||
|
<value>預設</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbConnections" xml:space="preserve">
|
||||||
|
<value>目前連線</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
|
||||||
|
<value>多伺服器最低延遲 (多選)</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuProxiesDelaytestPart" xml:space="preserve">
|
||||||
|
<value>目前部分節點延遲測試</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuSetDefaultLoadBalanceServer" xml:space="preserve">
|
||||||
|
<value>多伺服器負載平衡 (多選)</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddHysteria2Server" xml:space="preserve">
|
||||||
|
<value>添加[Hysteria2]伺服器</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
|
||||||
|
<value>Hysteria 最大頻寬(Up/Dw)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
|
||||||
|
<value>主界面佈局方向(需重啟)</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddWireguardServer" xml:space="preserve">
|
||||||
|
<value>添加[WireGuard]伺服器</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPrivateKey" xml:space="preserve">
|
||||||
|
<value>PrivateKey</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbReserved" xml:space="preserve">
|
||||||
|
<value>Reserved(2,3,4)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbLocalAddress" xml:space="preserve">
|
||||||
|
<value>Address(Ip,Ipv6)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
|
||||||
|
<value>使用系統hosts</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSortingChain" xml:space="preserve">
|
||||||
|
<value>路由鏈</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
|
||||||
|
<value>Outbound域名解析位址</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbPath7" xml:space="preserve">
|
||||||
|
<value>混淆密碼(obfs password)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
|
||||||
|
<value>Linux系統的sudo密碼</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||||
|
<value>密碼已加密且只儲存在本機檔案中,無密碼無法開啟Tun</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
||||||
|
<value>請先在Tun模式設定中設定sudo密碼</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
|
||||||
|
<value>請不要用sudo來運行本app</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportHeaderTypeTip5" xml:space="preserve">
|
||||||
|
<value>*xhttp 模式</value>
|
||||||
|
</data>
|
||||||
|
<data name="TransportExtraTip" xml:space="preserve">
|
||||||
|
<value>XHTTP Extra 原始 JSON,格式: { XHTTPObject }</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -42,21 +42,89 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"remarks": "代理GFW",
|
"remarks": "代理海外公共DNSIP",
|
||||||
"outboundTag": "proxy",
|
"outboundTag": "proxy",
|
||||||
"domain": [
|
"ip": [
|
||||||
"geosite:gfw",
|
"1.1.1.1",
|
||||||
"geosite:greatfire"
|
"1.0.0.1",
|
||||||
|
"2606:4700:4700::1111",
|
||||||
|
"2606:4700:4700::1001",
|
||||||
|
"1.1.1.2",
|
||||||
|
"1.0.0.2",
|
||||||
|
"2606:4700:4700::1112",
|
||||||
|
"2606:4700:4700::1002",
|
||||||
|
"1.1.1.3",
|
||||||
|
"1.0.0.3",
|
||||||
|
"2606:4700:4700::1113",
|
||||||
|
"2606:4700:4700::1003",
|
||||||
|
"8.8.8.8",
|
||||||
|
"8.8.4.4",
|
||||||
|
"2001:4860:4860::8888",
|
||||||
|
"2001:4860:4860::8844",
|
||||||
|
"94.140.14.14",
|
||||||
|
"94.140.15.15",
|
||||||
|
"2a10:50c0::ad1:ff",
|
||||||
|
"2a10:50c0::ad2:ff",
|
||||||
|
"94.140.14.15",
|
||||||
|
"94.140.15.16",
|
||||||
|
"2a10:50c0::bad1:ff",
|
||||||
|
"2a10:50c0::bad2:ff",
|
||||||
|
"94.140.14.140",
|
||||||
|
"94.140.14.141",
|
||||||
|
"2a10:50c0::1:ff",
|
||||||
|
"2a10:50c0::2:ff",
|
||||||
|
"208.67.222.222",
|
||||||
|
"208.67.220.220",
|
||||||
|
"2620:119:35::35",
|
||||||
|
"2620:119:53::53",
|
||||||
|
"208.67.222.123",
|
||||||
|
"208.67.220.123",
|
||||||
|
"2620:119:35::123",
|
||||||
|
"2620:119:53::123",
|
||||||
|
"9.9.9.9",
|
||||||
|
"149.112.112.112",
|
||||||
|
"2620:fe::9",
|
||||||
|
"2620:fe::fe",
|
||||||
|
"9.9.9.11",
|
||||||
|
"149.112.112.11",
|
||||||
|
"2620:fe::11",
|
||||||
|
"2620:fe::fe:11",
|
||||||
|
"9.9.9.10",
|
||||||
|
"149.112.112.10",
|
||||||
|
"2620:fe::10",
|
||||||
|
"2620:fe::fe:10",
|
||||||
|
"77.88.8.8",
|
||||||
|
"77.88.8.1",
|
||||||
|
"2a02:6b8::feed:0ff",
|
||||||
|
"2a02:6b8:0:1::feed:0ff",
|
||||||
|
"77.88.8.88",
|
||||||
|
"77.88.8.2",
|
||||||
|
"2a02:6b8::feed:bad",
|
||||||
|
"2a02:6b8:0:1::feed:bad",
|
||||||
|
"77.88.8.7",
|
||||||
|
"77.88.8.3",
|
||||||
|
"2a02:6b8::feed:a11",
|
||||||
|
"2a02:6b8:0:1::feed:a11"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"remarks": "代理Google等",
|
"remarks": "代理海外公共DNS域名",
|
||||||
|
"outboundTag": "proxy",
|
||||||
|
"domain": [
|
||||||
|
"domain:cloudflare-dns.com",
|
||||||
|
"domain:one.one.one.one",
|
||||||
|
"domain:dns.google",
|
||||||
|
"domain:adguard-dns.com",
|
||||||
|
"domain:opendns.com",
|
||||||
|
"domain:umbrella.com",
|
||||||
|
"domain:quad9.net",
|
||||||
|
"domain:yandex.net"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"remarks": "代理IP",
|
||||||
"outboundTag": "proxy",
|
"outboundTag": "proxy",
|
||||||
"ip": [
|
"ip": [
|
||||||
"1.0.0.1",
|
|
||||||
"1.1.1.1",
|
|
||||||
"8.8.8.8",
|
|
||||||
"8.8.4.4",
|
|
||||||
"geoip:facebook",
|
"geoip:facebook",
|
||||||
"geoip:fastly",
|
"geoip:fastly",
|
||||||
"geoip:google",
|
"geoip:google",
|
||||||
@@ -65,6 +133,14 @@
|
|||||||
"geoip:twitter"
|
"geoip:twitter"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"remarks": "代理GFW",
|
||||||
|
"outboundTag": "proxy",
|
||||||
|
"domain": [
|
||||||
|
"geosite:gfw",
|
||||||
|
"geosite:greatfire"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"remarks": "最终直连",
|
"remarks": "最终直连",
|
||||||
"port": "0-65535",
|
"port": "0-65535",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
[{
|
[
|
||||||
|
{
|
||||||
"remarks": "block",
|
"remarks": "block",
|
||||||
"outboundTag": "block",
|
"outboundTag": "block",
|
||||||
"domain": [
|
"domain": [
|
||||||
|
|||||||
@@ -35,44 +35,71 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"remarks": "绕过中国域名",
|
"remarks": "绕过中国公共DNSIP",
|
||||||
|
"outboundTag": "direct",
|
||||||
|
"ip": [
|
||||||
|
"223.5.5.5",
|
||||||
|
"223.6.6.6",
|
||||||
|
"2400:3200::1",
|
||||||
|
"2400:3200:baba::1",
|
||||||
|
"119.29.29.29",
|
||||||
|
"1.12.12.12",
|
||||||
|
"120.53.53.53",
|
||||||
|
"2402:4e00::",
|
||||||
|
"2402:4e00:1::",
|
||||||
|
"180.76.76.76",
|
||||||
|
"2400:da00::6666",
|
||||||
|
"114.114.114.114",
|
||||||
|
"114.114.115.115",
|
||||||
|
"114.114.114.119",
|
||||||
|
"114.114.115.119",
|
||||||
|
"114.114.114.110",
|
||||||
|
"114.114.115.110",
|
||||||
|
"180.184.1.1",
|
||||||
|
"180.184.2.2",
|
||||||
|
"101.226.4.6",
|
||||||
|
"218.30.118.6",
|
||||||
|
"123.125.81.6",
|
||||||
|
"140.207.198.6",
|
||||||
|
"1.2.4.8",
|
||||||
|
"210.2.4.8",
|
||||||
|
"52.80.66.66",
|
||||||
|
"117.50.22.22",
|
||||||
|
"2400:7fc0:849e:200::4",
|
||||||
|
"2404:c2c0:85d8:901::4",
|
||||||
|
"117.50.10.10",
|
||||||
|
"52.80.52.52",
|
||||||
|
"2400:7fc0:849e:200::8",
|
||||||
|
"2404:c2c0:85d8:901::8",
|
||||||
|
"117.50.60.30",
|
||||||
|
"52.80.60.30"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"remarks": "绕过中国公共DNS域名",
|
||||||
"outboundTag": "direct",
|
"outboundTag": "direct",
|
||||||
"domain": [
|
"domain": [
|
||||||
"domain:dns.alidns.com",
|
"domain:alidns.com",
|
||||||
"domain:doh.pub",
|
"domain:doh.pub",
|
||||||
"domain:dot.pub",
|
"domain:dot.pub",
|
||||||
"domain:doh.360.cn",
|
"domain:360.cn",
|
||||||
"domain:dot.360.cn",
|
"domain:onedns.net"
|
||||||
"geosite:cn",
|
|
||||||
"geosite:geolocation-cn"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"remarks": "绕过中国IP",
|
"remarks": "绕过中国IP",
|
||||||
"outboundTag": "direct",
|
"outboundTag": "direct",
|
||||||
"ip": [
|
"ip": [
|
||||||
"223.5.5.5/32",
|
|
||||||
"223.6.6.6/32",
|
|
||||||
"2400:3200::1/128",
|
|
||||||
"2400:3200:baba::1/128",
|
|
||||||
"119.29.29.29/32",
|
|
||||||
"1.12.12.12/32",
|
|
||||||
"120.53.53.53/32",
|
|
||||||
"2402:4e00::/128",
|
|
||||||
"2402:4e00:1::/128",
|
|
||||||
"180.76.76.76/32",
|
|
||||||
"2400:da00::6666/128",
|
|
||||||
"114.114.114.114/32",
|
|
||||||
"114.114.115.115/32",
|
|
||||||
"180.184.1.1/32",
|
|
||||||
"180.184.2.2/32",
|
|
||||||
"101.226.4.6/32",
|
|
||||||
"218.30.118.6/32",
|
|
||||||
"123.125.81.6/32",
|
|
||||||
"140.207.198.6/32",
|
|
||||||
"geoip:cn"
|
"geoip:cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"remarks": "绕过中国域名",
|
||||||
|
"outboundTag": "direct",
|
||||||
|
"domain": [
|
||||||
|
"geosite:cn"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"remarks": "最终代理",
|
"remarks": "最终代理",
|
||||||
"port": "0-65535",
|
"port": "0-65535",
|
||||||
|
|||||||
@@ -20,8 +20,7 @@
|
|||||||
"rules": [
|
"rules": [
|
||||||
{
|
{
|
||||||
"rule_set": [
|
"rule_set": [
|
||||||
"geosite-cn",
|
"geosite-cn"
|
||||||
"geosite-geolocation-cn"
|
|
||||||
],
|
],
|
||||||
"server": "local"
|
"server": "local"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
{
|
{
|
||||||
"address": "223.5.5.5",
|
"address": "223.5.5.5",
|
||||||
"domains": [
|
"domains": [
|
||||||
"geosite:cn",
|
"geosite:cn"
|
||||||
"geosite:geolocation-cn"
|
|
||||||
],
|
],
|
||||||
"expectIPs": [
|
"expectIPs": [
|
||||||
"geoip:cn"
|
"geoip:cn"
|
||||||
|
|||||||
10
v2rayN/ServiceLib/Sample/linux_autostart_config
Normal file
10
v2rayN/ServiceLib/Sample/linux_autostart_config
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Exec=$ExecPath$
|
||||||
|
Hidden=false
|
||||||
|
NoDisplay=false
|
||||||
|
X-GNOME-Autostart-enabled=true
|
||||||
|
Name[en_US]=v2rayN
|
||||||
|
Name=v2rayN
|
||||||
|
Comment[en_US]=v2rayN
|
||||||
|
Comment=v2rayN
|
||||||
@@ -2,8 +2,10 @@
|
|||||||
"type": "tun",
|
"type": "tun",
|
||||||
"tag": "tun-in",
|
"tag": "tun-in",
|
||||||
"interface_name": "singbox_tun",
|
"interface_name": "singbox_tun",
|
||||||
"inet4_address": "172.19.0.1/30",
|
"address": [
|
||||||
"inet6_address": "fdfe:dcba:9876::1/126",
|
"172.18.0.1/30",
|
||||||
|
"fdfe:dcba:9876::1/126"
|
||||||
|
],
|
||||||
"mtu": 9000,
|
"mtu": 9000,
|
||||||
"auto_route": true,
|
"auto_route": true,
|
||||||
"strict_route": false,
|
"strict_route": false,
|
||||||
|
|||||||
@@ -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.0.2</Version>
|
<Version>7.1.1</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -14,11 +14,13 @@
|
|||||||
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
||||||
<PackageReference Include="Splat.NLog" Version="15.2.22" />
|
<PackageReference Include="Splat.NLog" Version="15.2.22" />
|
||||||
<PackageReference Include="WebDav.Client" Version="2.8.0" />
|
<PackageReference Include="WebDav.Client" Version="2.8.0" />
|
||||||
<PackageReference Include="YamlDotNet" Version="16.1.3" />
|
<PackageReference Include="YamlDotNet" Version="16.2.0" />
|
||||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||||
<PackageReference Include="CliWrap" Version="3.6.6" />
|
<PackageReference Include="CliWrap" Version="3.6.7" />
|
||||||
<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" />
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -41,6 +43,7 @@
|
|||||||
<EmbeddedResource Include="Sample\tun_singbox_dns" />
|
<EmbeddedResource Include="Sample\tun_singbox_dns" />
|
||||||
<EmbeddedResource Include="Sample\tun_singbox_inbound" />
|
<EmbeddedResource Include="Sample\tun_singbox_inbound" />
|
||||||
<EmbeddedResource Include="Sample\tun_singbox_rules" />
|
<EmbeddedResource Include="Sample\tun_singbox_rules" />
|
||||||
|
<EmbeddedResource Include="Sample\linux_autostart_config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace ServiceLib.Services.CoreConfig
|
namespace ServiceLib.Services.CoreConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Core configuration file processing class
|
/// Core configuration file processing class
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
txtFile = txtFile.Replace(tagYamlStr1, tagYamlStr2);
|
txtFile = txtFile.Replace(tagYamlStr1, tagYamlStr2);
|
||||||
|
|
||||||
//YAML anchors
|
//YAML anchors
|
||||||
if (txtFile.Contains("<<:") && txtFile.Contains("*") && txtFile.Contains("&"))
|
if (txtFile.Contains("<<:") && txtFile.Contains('*') && txtFile.Contains('&'))
|
||||||
{
|
{
|
||||||
txtFile = YamlUtils.PreprocessYaml(txtFile);
|
txtFile = YamlUtils.PreprocessYaml(txtFile);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
ret.Msg = ResUI.CheckServerSettings;
|
ret.Msg = ResUI.CheckServerSettings;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.splithttp))
|
if (node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.splithttp) or nameof(ETransport.xhttp))
|
||||||
{
|
{
|
||||||
ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
|
ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
|
||||||
return ret;
|
return ret;
|
||||||
@@ -484,7 +484,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
singboxConfig.inbounds = [];
|
singboxConfig.inbounds = [];
|
||||||
|
|
||||||
if (!_config.TunModeItem.EnableTun
|
if (!_config.TunModeItem.EnableTun
|
||||||
|| _config.TunModeItem.EnableTun && _config.TunModeItem.EnableExInbound && _config.RunningCoreType == ECoreType.sing_box)
|
|| (_config.TunModeItem.EnableTun && _config.TunModeItem.EnableExInbound && _config.RunningCoreType == ECoreType.sing_box))
|
||||||
{
|
{
|
||||||
var inbound = new Inbound4Sbox()
|
var inbound = new Inbound4Sbox()
|
||||||
{
|
{
|
||||||
@@ -558,7 +558,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
//tunInbound.sniff_override_destination = _config.inbound[0].routeOnly ? false : _config.inbound[0].sniffingEnabled;
|
//tunInbound.sniff_override_destination = _config.inbound[0].routeOnly ? false : _config.inbound[0].sniffingEnabled;
|
||||||
if (_config.TunModeItem.EnableIPv6Address == false)
|
if (_config.TunModeItem.EnableIPv6Address == false)
|
||||||
{
|
{
|
||||||
tunInbound.inet6_address = null;
|
tunInbound.address = ["172.18.0.1/30"];
|
||||||
}
|
}
|
||||||
|
|
||||||
singboxConfig.inbounds.Add(tunInbound);
|
singboxConfig.inbounds.Add(tunInbound);
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (node.GetNetwork() is nameof(ETransport.quic))
|
||||||
|
{
|
||||||
|
ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret.Msg = ResUI.InitialConfiguration;
|
ret.Msg = ResUI.InitialConfiguration;
|
||||||
|
|
||||||
var result = Utils.GetEmbedText(Global.V2raySampleClient);
|
var result = Utils.GetEmbedText(Global.V2raySampleClient);
|
||||||
@@ -366,8 +372,8 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
v2rayConfig.log.loglevel = _config.CoreBasicItem.Loglevel;
|
v2rayConfig.log.loglevel = _config.CoreBasicItem.Loglevel;
|
||||||
v2rayConfig.log.access = "";
|
v2rayConfig.log.access = null;
|
||||||
v2rayConfig.log.error = "";
|
v2rayConfig.log.error = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -920,23 +926,35 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
streamSettings.httpupgradeSettings = httpupgradeSettings;
|
streamSettings.httpupgradeSettings = httpupgradeSettings;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
//splithttp
|
//splithttp //xhttp
|
||||||
case nameof(ETransport.splithttp):
|
case nameof(ETransport.splithttp):
|
||||||
SplithttpSettings4Ray splithttpSettings = new()
|
case nameof(ETransport.xhttp):
|
||||||
|
streamSettings.network = ETransport.xhttp.ToString();
|
||||||
|
XhttpSettings4Ray xhttpSettings = new()
|
||||||
{
|
{
|
||||||
maxUploadSize = 1000000,
|
scMaxEachPostBytes = "500000-1000000",
|
||||||
maxConcurrentUploads = 10
|
scMaxConcurrentPosts = "50-100",
|
||||||
|
scMinPostsIntervalMs = "30-50"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Utils.IsNotEmpty(node.Path))
|
if (Utils.IsNotEmpty(node.Path))
|
||||||
{
|
{
|
||||||
splithttpSettings.path = node.Path;
|
xhttpSettings.path = node.Path;
|
||||||
}
|
}
|
||||||
if (Utils.IsNotEmpty(host))
|
if (Utils.IsNotEmpty(host))
|
||||||
{
|
{
|
||||||
splithttpSettings.host = host;
|
xhttpSettings.host = host;
|
||||||
}
|
}
|
||||||
streamSettings.splithttpSettings = splithttpSettings;
|
if (Utils.IsNotEmpty(node.HeaderType) && Global.XhttpMode.Contains(node.HeaderType))
|
||||||
|
{
|
||||||
|
xhttpSettings.mode = node.HeaderType;
|
||||||
|
}
|
||||||
|
if (Utils.IsNotEmpty(node.Extra))
|
||||||
|
{
|
||||||
|
xhttpSettings.extra = JsonUtils.ParseJson(node.Extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
streamSettings.xhttpSettings = xhttpSettings;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
//h2
|
//h2
|
||||||
@@ -1120,17 +1138,14 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
if (_config.GuiItem.EnableStatistics)
|
if (_config.GuiItem.EnableStatistics)
|
||||||
{
|
{
|
||||||
string tag = EInboundProtocol.api.ToString();
|
string tag = EInboundProtocol.api.ToString();
|
||||||
API4Ray apiObj = new();
|
Metrics4Ray apiObj = new();
|
||||||
Policy4Ray policyObj = new();
|
Policy4Ray policyObj = new();
|
||||||
SystemPolicy4Ray policySystemSetting = new();
|
SystemPolicy4Ray policySystemSetting = new();
|
||||||
|
|
||||||
string[] services = { "StatsService" };
|
|
||||||
|
|
||||||
v2rayConfig.stats = new Stats4Ray();
|
v2rayConfig.stats = new Stats4Ray();
|
||||||
|
|
||||||
apiObj.tag = tag;
|
apiObj.tag = tag;
|
||||||
apiObj.services = services.ToList();
|
v2rayConfig.metrics = apiObj;
|
||||||
v2rayConfig.api = apiObj;
|
|
||||||
|
|
||||||
policySystemSetting.statsOutboundDownlink = true;
|
policySystemSetting.statsOutboundDownlink = true;
|
||||||
policySystemSetting.statsOutboundUplink = true;
|
policySystemSetting.statsOutboundUplink = true;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Diagnostics;
|
using ReactiveUI;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
|
||||||
@@ -80,10 +81,12 @@ namespace ServiceLib.Services
|
|||||||
Task.Run(RunMixedtestAsync);
|
Task.Run(RunMixedtestAsync);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
MessageBus.Current.Listen<string>(EMsgCommand.StopSpeedtest.ToString()).Subscribe(ExitLoop);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExitLoop()
|
private void ExitLoop(string x)
|
||||||
{
|
{
|
||||||
|
if (_exitLoop) return;
|
||||||
_exitLoop = true;
|
_exitLoop = true;
|
||||||
UpdateFunc("", ResUI.SpeedtestingStop);
|
UpdateFunc("", ResUI.SpeedtestingStop);
|
||||||
}
|
}
|
||||||
|
|||||||
106
v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs
Normal file
106
v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
namespace ServiceLib.Services.Statistics
|
||||||
|
{
|
||||||
|
public class StatisticsXrayService
|
||||||
|
{
|
||||||
|
private const long linkBase = 1024;
|
||||||
|
private string _url;
|
||||||
|
private ServerSpeedItem _serverSpeedItem = new();
|
||||||
|
private Config _config;
|
||||||
|
private bool _exitFlag;
|
||||||
|
private Action<ServerSpeedItem>? _updateFunc;
|
||||||
|
|
||||||
|
public StatisticsXrayService(Config config, Action<ServerSpeedItem> updateFunc)
|
||||||
|
{
|
||||||
|
_config = config;
|
||||||
|
_updateFunc = updateFunc;
|
||||||
|
_exitFlag = false;
|
||||||
|
_url = $"{Global.HttpProtocol}{Global.Loopback}:{AppHandler.Instance.StatePort}/debug/vars";
|
||||||
|
|
||||||
|
Task.Run(Run);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
_exitFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void Run()
|
||||||
|
{
|
||||||
|
while (!_exitFlag)
|
||||||
|
{
|
||||||
|
await Task.Delay(1000);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_config.RunningCoreType != ECoreType.Xray)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await HttpClientHelper.Instance.TryGetAsync(_url);
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
var server = ParseOutput(result) ?? new ServerSpeedItem();
|
||||||
|
_updateFunc?.Invoke(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServerSpeedItem? ParseOutput(string result)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var source = JsonUtils.Deserialize<V2rayMetricsVars>(result);
|
||||||
|
if (source?.stats?.outbound == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerSpeedItem server = new();
|
||||||
|
foreach (string key in source.stats.outbound.Keys)
|
||||||
|
{
|
||||||
|
var value = source.stats.outbound[key];
|
||||||
|
if (value == null) continue;
|
||||||
|
var state = JsonUtils.Deserialize<V2rayMetricsVarsLink>(value.ToString());
|
||||||
|
|
||||||
|
if (key.StartsWith(Global.ProxyTag))
|
||||||
|
{
|
||||||
|
server.ProxyUp += state.uplink / linkBase;
|
||||||
|
server.ProxyDown += state.downlink / linkBase;
|
||||||
|
}
|
||||||
|
else if (key == Global.DirectTag)
|
||||||
|
{
|
||||||
|
server.DirectUp = state.uplink / linkBase;
|
||||||
|
server.DirectDown = state.downlink / linkBase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server.DirectDown < _serverSpeedItem.DirectDown || server.ProxyDown < _serverSpeedItem.ProxyDown)
|
||||||
|
{
|
||||||
|
_serverSpeedItem = new();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerSpeedItem curItem = new()
|
||||||
|
{
|
||||||
|
ProxyUp = server.ProxyUp - _serverSpeedItem.ProxyUp,
|
||||||
|
ProxyDown = server.ProxyDown - _serverSpeedItem.ProxyDown,
|
||||||
|
DirectUp = server.DirectUp - _serverSpeedItem.DirectUp,
|
||||||
|
DirectDown = server.DirectDown - _serverSpeedItem.DirectDown,
|
||||||
|
};
|
||||||
|
_serverSpeedItem = server;
|
||||||
|
return curItem;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace ServiceLib.Services
|
namespace ServiceLib.Services
|
||||||
@@ -6,12 +6,10 @@ namespace ServiceLib.Services
|
|||||||
public class UpdateService
|
public class UpdateService
|
||||||
{
|
{
|
||||||
private Action<bool, string>? _updateFunc;
|
private Action<bool, string>? _updateFunc;
|
||||||
private Config _config;
|
|
||||||
private int _timeout = 30;
|
private int _timeout = 30;
|
||||||
|
|
||||||
public async Task CheckUpdateGuiN(Config config, Action<bool, string> updateFunc, bool preRelease)
|
public async Task CheckUpdateGuiN(Config config, Action<bool, string> updateFunc, bool preRelease)
|
||||||
{
|
{
|
||||||
_config = config;
|
|
||||||
_updateFunc = updateFunc;
|
_updateFunc = updateFunc;
|
||||||
var url = string.Empty;
|
var url = string.Empty;
|
||||||
var fileName = string.Empty;
|
var fileName = string.Empty;
|
||||||
@@ -53,7 +51,6 @@ namespace ServiceLib.Services
|
|||||||
|
|
||||||
public async Task CheckUpdateCore(ECoreType type, Config config, Action<bool, string> updateFunc, bool preRelease)
|
public async Task CheckUpdateCore(ECoreType type, Config config, Action<bool, string> updateFunc, bool preRelease)
|
||||||
{
|
{
|
||||||
_config = config;
|
|
||||||
_updateFunc = updateFunc;
|
_updateFunc = updateFunc;
|
||||||
var url = string.Empty;
|
var url = string.Empty;
|
||||||
var fileName = string.Empty;
|
var fileName = string.Empty;
|
||||||
@@ -108,13 +105,12 @@ namespace ServiceLib.Services
|
|||||||
|
|
||||||
public async Task UpdateSubscriptionProcess(Config config, string subId, bool blProxy, Action<bool, string> updateFunc)
|
public async Task UpdateSubscriptionProcess(Config config, string subId, bool blProxy, Action<bool, string> updateFunc)
|
||||||
{
|
{
|
||||||
_config = config;
|
|
||||||
_updateFunc = updateFunc;
|
_updateFunc = updateFunc;
|
||||||
|
|
||||||
_updateFunc?.Invoke(false, ResUI.MsgUpdateSubscriptionStart);
|
_updateFunc?.Invoke(false, ResUI.MsgUpdateSubscriptionStart);
|
||||||
var subItem = await AppHandler.Instance.SubItems();
|
var subItem = await AppHandler.Instance.SubItems();
|
||||||
|
|
||||||
if (subItem == null || subItem.Count <= 0)
|
if (subItem is not { Count: > 0 })
|
||||||
{
|
{
|
||||||
_updateFunc?.Invoke(false, ResUI.MsgNoValidSubscription);
|
_updateFunc?.Invoke(false, ResUI.MsgNoValidSubscription);
|
||||||
return;
|
return;
|
||||||
@@ -122,11 +118,11 @@ namespace ServiceLib.Services
|
|||||||
|
|
||||||
foreach (var item in subItem)
|
foreach (var item in subItem)
|
||||||
{
|
{
|
||||||
string id = item.Id.TrimEx();
|
var id = item.Id.TrimEx();
|
||||||
string url = item.Url.TrimEx();
|
var url = item.Url.TrimEx();
|
||||||
string userAgent = item.UserAgent.TrimEx();
|
var userAgent = item.UserAgent.TrimEx();
|
||||||
string hashCode = $"{item.Remarks}->";
|
var hashCode = $"{item.Remarks}->";
|
||||||
if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url) || Utils.IsNotEmpty(subId) && item.Id != subId)
|
if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url) || (Utils.IsNotEmpty(subId) && item.Id != subId))
|
||||||
{
|
{
|
||||||
//_updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgNoValidSubscription}");
|
//_updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgNoValidSubscription}");
|
||||||
continue;
|
continue;
|
||||||
@@ -219,7 +215,7 @@ namespace ServiceLib.Services
|
|||||||
_updateFunc?.Invoke(false, $"{hashCode}{result}");
|
_updateFunc?.Invoke(false, $"{hashCode}{result}");
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = await ConfigHandler.AddBatchServers(config, result, id, true);
|
var ret = await ConfigHandler.AddBatchServers(config, result, id, true);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("FailedImportSubscription");
|
Logging.SaveLog("FailedImportSubscription");
|
||||||
@@ -231,6 +227,8 @@ namespace ServiceLib.Services
|
|||||||
: $"{hashCode}{ResUI.MsgFailedImportSubscription}");
|
: $"{hashCode}{ResUI.MsgFailedImportSubscription}");
|
||||||
}
|
}
|
||||||
_updateFunc?.Invoke(false, "-------------------------------------------------------");
|
_updateFunc?.Invoke(false, "-------------------------------------------------------");
|
||||||
|
|
||||||
|
//await ConfigHandler.DedupServerList(config, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateFunc?.Invoke(true, $"{ResUI.MsgUpdateSubscriptionEnd}");
|
_updateFunc?.Invoke(true, $"{ResUI.MsgUpdateSubscriptionEnd}");
|
||||||
@@ -309,10 +307,9 @@ namespace ServiceLib.Services
|
|||||||
{
|
{
|
||||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
|
||||||
string filePath = string.Empty;
|
string filePath = string.Empty;
|
||||||
foreach (string name in coreInfo.CoreExes)
|
foreach (var name in coreInfo.CoreExes)
|
||||||
{
|
{
|
||||||
string vName = Utils.GetExeName(name);
|
var vName = Utils.GetBinPath(Utils.GetExeName(name), coreInfo.CoreType.ToString());
|
||||||
vName = Utils.GetBinPath(vName, coreInfo.CoreType.ToString());
|
|
||||||
if (File.Exists(vName))
|
if (File.Exists(vName))
|
||||||
{
|
{
|
||||||
filePath = vName;
|
filePath = vName;
|
||||||
@@ -453,7 +450,6 @@ namespace ServiceLib.Services
|
|||||||
|
|
||||||
private async Task UpdateGeoFile(string geoName, Config config, Action<bool, string> updateFunc)
|
private async Task UpdateGeoFile(string geoName, Config config, Action<bool, string> updateFunc)
|
||||||
{
|
{
|
||||||
_config = config;
|
|
||||||
_updateFunc = updateFunc;
|
_updateFunc = updateFunc;
|
||||||
|
|
||||||
var geoUrl = string.IsNullOrEmpty(config?.ConstItem.GeoSourceUrl)
|
var geoUrl = string.IsNullOrEmpty(config?.ConstItem.GeoSourceUrl)
|
||||||
@@ -469,7 +465,6 @@ namespace ServiceLib.Services
|
|||||||
|
|
||||||
private async Task UpdateSrsFileAll(Config config, Action<bool, string> updateFunc)
|
private async Task UpdateSrsFileAll(Config config, Action<bool, string> updateFunc)
|
||||||
{
|
{
|
||||||
_config = config;
|
|
||||||
_updateFunc = updateFunc;
|
_updateFunc = updateFunc;
|
||||||
|
|
||||||
var geoipFiles = new List<string>();
|
var geoipFiles = new List<string>();
|
||||||
@@ -520,9 +515,9 @@ namespace ServiceLib.Services
|
|||||||
|
|
||||||
private async Task UpdateSrsFile(string type, string srsName, Config config, Action<bool, string> updateFunc)
|
private async Task UpdateSrsFile(string type, string srsName, Config config, Action<bool, string> updateFunc)
|
||||||
{
|
{
|
||||||
var srsUrl = string.IsNullOrEmpty(_config.ConstItem.SrsSourceUrl)
|
var srsUrl = string.IsNullOrEmpty(config.ConstItem.SrsSourceUrl)
|
||||||
? Global.SingboxRulesetUrl
|
? Global.SingboxRulesetUrl
|
||||||
: _config.ConstItem.SrsSourceUrl;
|
: config.ConstItem.SrsSourceUrl;
|
||||||
|
|
||||||
var fileName = $"{type}-{srsName}.srs";
|
var fileName = $"{type}-{srsName}.srs";
|
||||||
var targetPath = Path.Combine(Utils.GetBinPath("srss"), fileName);
|
var targetPath = Path.Combine(Utils.GetBinPath("srss"), fileName);
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
private const string _geo = "GeoFiles";
|
private const string _geo = "GeoFiles";
|
||||||
private string _v2rayN = ECoreType.v2rayN.ToString();
|
private string _v2rayN = ECoreType.v2rayN.ToString();
|
||||||
private List<CheckUpdateItem> _lstUpdated = [];
|
private List<CheckUpdateModel> _lstUpdated = [];
|
||||||
|
|
||||||
private IObservableCollection<CheckUpdateItem> _checkUpdateItem = new ObservableCollectionExtended<CheckUpdateItem>();
|
private IObservableCollection<CheckUpdateModel> _checkUpdateModel = new ObservableCollectionExtended<CheckUpdateModel>();
|
||||||
public IObservableCollection<CheckUpdateItem> CheckUpdateItems => _checkUpdateItem;
|
public IObservableCollection<CheckUpdateModel> CheckUpdateModels => _checkUpdateModel;
|
||||||
public ReactiveCommand<Unit, Unit> CheckUpdateCmd { get; }
|
public ReactiveCommand<Unit, Unit> CheckUpdateCmd { get; }
|
||||||
[Reactive] public bool EnableCheckPreReleaseUpdate { get; set; }
|
[Reactive] public bool EnableCheckPreReleaseUpdate { get; set; }
|
||||||
|
|
||||||
@@ -29,69 +29,56 @@ namespace ServiceLib.ViewModels
|
|||||||
await CheckUpdate();
|
await CheckUpdate();
|
||||||
});
|
});
|
||||||
|
|
||||||
EnableCheckPreReleaseUpdate = _config.GuiItem.CheckPreReleaseUpdate;
|
EnableCheckPreReleaseUpdate = _config.CheckUpdateItem.CheckPreReleaseUpdate;
|
||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.EnableCheckPreReleaseUpdate,
|
x => x.EnableCheckPreReleaseUpdate,
|
||||||
y => y == true)
|
y => y == true)
|
||||||
.Subscribe(c => { _config.GuiItem.CheckPreReleaseUpdate = EnableCheckPreReleaseUpdate; });
|
.Subscribe(c => { _config.CheckUpdateItem.CheckPreReleaseUpdate = EnableCheckPreReleaseUpdate; });
|
||||||
|
|
||||||
RefreshSubItems();
|
RefreshCheckUpdateItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshSubItems()
|
private void RefreshCheckUpdateItems()
|
||||||
{
|
{
|
||||||
_checkUpdateItem.Clear();
|
_checkUpdateModel.Clear();
|
||||||
|
|
||||||
if (RuntimeInformation.ProcessArchitecture != Architecture.X86)
|
if (RuntimeInformation.ProcessArchitecture != Architecture.X86)
|
||||||
{
|
{
|
||||||
if (Utils.IsWindows())
|
_checkUpdateModel.Add(GetCheckUpdateModel(_v2rayN));
|
||||||
{
|
_checkUpdateModel.Add(GetCheckUpdateModel(ECoreType.Xray.ToString()));
|
||||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
_checkUpdateModel.Add(GetCheckUpdateModel(ECoreType.mihomo.ToString()));
|
||||||
{
|
_checkUpdateModel.Add(GetCheckUpdateModel(ECoreType.sing_box.ToString()));
|
||||||
IsSelected = false,
|
}
|
||||||
CoreType = _v2rayN,
|
_checkUpdateModel.Add(GetCheckUpdateModel(_geo));
|
||||||
Remarks = ResUI.menuCheckUpdate,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
private CheckUpdateModel GetCheckUpdateModel(string coreType)
|
||||||
{
|
{
|
||||||
IsSelected = true,
|
return new()
|
||||||
CoreType = ECoreType.Xray.ToString(),
|
|
||||||
Remarks = ResUI.menuCheckUpdate,
|
|
||||||
});
|
|
||||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
|
||||||
{
|
{
|
||||||
IsSelected = true,
|
IsSelected = _config.CheckUpdateItem.SelectedCoreTypes?.Contains(coreType) ?? true,
|
||||||
CoreType = ECoreType.mihomo.ToString(),
|
CoreType = coreType,
|
||||||
Remarks = ResUI.menuCheckUpdate,
|
Remarks = ResUI.menuCheckUpdate,
|
||||||
});
|
};
|
||||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
|
||||||
{
|
|
||||||
IsSelected = true,
|
|
||||||
CoreType = ECoreType.sing_box.ToString(),
|
|
||||||
Remarks = ResUI.menuCheckUpdate,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
private async Task SaveSelectedCoreTypes()
|
||||||
{
|
{
|
||||||
IsSelected = true,
|
_config.CheckUpdateItem.SelectedCoreTypes = _checkUpdateModel.Where(t => t.IsSelected == true).Select(t => t.CoreType ?? "").ToList();
|
||||||
CoreType = _geo,
|
await ConfigHandler.SaveConfig(_config);
|
||||||
Remarks = ResUI.menuCheckUpdate,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CheckUpdate()
|
private async Task CheckUpdate()
|
||||||
{
|
{
|
||||||
_lstUpdated.Clear();
|
_lstUpdated.Clear();
|
||||||
_lstUpdated = _checkUpdateItem.Where(x => x.IsSelected == true)
|
_lstUpdated = _checkUpdateModel.Where(x => x.IsSelected == true)
|
||||||
.Select(x => new CheckUpdateItem() { CoreType = x.CoreType }).ToList();
|
.Select(x => new CheckUpdateModel() { CoreType = x.CoreType }).ToList();
|
||||||
|
await SaveSelectedCoreTypes();
|
||||||
|
|
||||||
for (var k = _checkUpdateItem.Count - 1; k >= 0; k--)
|
for (var k = _checkUpdateModel.Count - 1; k >= 0; k--)
|
||||||
{
|
{
|
||||||
var item = _checkUpdateItem[k];
|
var item = _checkUpdateModel[k];
|
||||||
if (item.IsSelected != true) continue;
|
if (item.IsSelected != true) continue;
|
||||||
|
|
||||||
UpdateView(item.CoreType, "...");
|
UpdateView(item.CoreType, "...");
|
||||||
@@ -103,13 +90,13 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
await CheckUpdateN(EnableCheckPreReleaseUpdate);
|
await CheckUpdateN(EnableCheckPreReleaseUpdate);
|
||||||
}
|
}
|
||||||
else if (item.CoreType == ECoreType.mihomo.ToString())
|
else if (item.CoreType == ECoreType.Xray.ToString())
|
||||||
{
|
{
|
||||||
await CheckUpdateCore(item, false);
|
await CheckUpdateCore(item, EnableCheckPreReleaseUpdate);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await CheckUpdateCore(item, EnableCheckPreReleaseUpdate);
|
await CheckUpdateCore(item, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,23 +152,23 @@ namespace ServiceLib.ViewModels
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CheckUpdateCore(CheckUpdateItem item, bool preRelease)
|
private async Task CheckUpdateCore(CheckUpdateModel model, bool preRelease)
|
||||||
{
|
{
|
||||||
void _updateUI(bool success, string msg)
|
void _updateUI(bool success, string msg)
|
||||||
{
|
{
|
||||||
UpdateView(item.CoreType, msg);
|
UpdateView(model.CoreType, msg);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
UpdateView(item.CoreType, ResUI.MsgUpdateV2rayCoreSuccessfullyMore);
|
UpdateView(model.CoreType, ResUI.MsgUpdateV2rayCoreSuccessfullyMore);
|
||||||
|
|
||||||
UpdatedPlusPlus(item.CoreType, msg);
|
UpdatedPlusPlus(model.CoreType, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var type = (ECoreType)Enum.Parse(typeof(ECoreType), item.CoreType);
|
var type = (ECoreType)Enum.Parse(typeof(ECoreType), model.CoreType);
|
||||||
await (new UpdateService()).CheckUpdateCore(type, _config, _updateUI, preRelease)
|
await (new UpdateService()).CheckUpdateCore(type, _config, _updateUI, preRelease)
|
||||||
.ContinueWith(t =>
|
.ContinueWith(t =>
|
||||||
{
|
{
|
||||||
UpdatedPlusPlus(item.CoreType, "");
|
UpdatedPlusPlus(model.CoreType, "");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +282,7 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private void UpdateView(string coreType, string msg)
|
private void UpdateView(string coreType, string msg)
|
||||||
{
|
{
|
||||||
var item = new CheckUpdateItem()
|
var item = new CheckUpdateModel()
|
||||||
{
|
{
|
||||||
CoreType = coreType,
|
CoreType = coreType,
|
||||||
Remarks = msg,
|
Remarks = msg,
|
||||||
@@ -303,13 +290,13 @@ namespace ServiceLib.ViewModels
|
|||||||
_updateView?.Invoke(EViewAction.DispatcherCheckUpdate, item);
|
_updateView?.Invoke(EViewAction.DispatcherCheckUpdate, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateViewResult(CheckUpdateItem item)
|
public void UpdateViewResult(CheckUpdateModel model)
|
||||||
{
|
{
|
||||||
var found = _checkUpdateItem.FirstOrDefault(t => t.CoreType == item.CoreType);
|
var found = _checkUpdateModel.FirstOrDefault(t => t.CoreType == model.CoreType);
|
||||||
if (found == null) return;
|
if (found == null) return;
|
||||||
var itemCopy = JsonUtils.DeepCopy(found);
|
var itemCopy = JsonUtils.DeepCopy(found);
|
||||||
itemCopy.Remarks = item.Remarks;
|
itemCopy.Remarks = model.Remarks;
|
||||||
_checkUpdateItem.Replace(found, itemCopy);
|
_checkUpdateModel.Replace(found, itemCopy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ namespace ServiceLib.ViewModels
|
|||||||
item2.DomainStrategy4Freedom = domainStrategy4Freedom2;
|
item2.DomainStrategy4Freedom = domainStrategy4Freedom2;
|
||||||
item2.DomainDNSAddress = domainDNSAddress2;
|
item2.DomainDNSAddress = domainDNSAddress2;
|
||||||
item2.NormalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2));
|
item2.NormalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2));
|
||||||
item2.TunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2)); ;
|
item2.TunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2));
|
||||||
await ConfigHandler.SaveDNSItems(_config, item2);
|
await ConfigHandler.SaveDNSItems(_config, item2);
|
||||||
|
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
await Reload();
|
await Reload();
|
||||||
await AutoHideStartup();
|
await AutoHideStartup();
|
||||||
|
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Init
|
#endregion Init
|
||||||
@@ -266,7 +267,7 @@ namespace ServiceLib.ViewModels
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<StatusBarViewModel>()?.UpdateStatistics(update);
|
Locator.Current.GetService<StatusBarViewModel>()?.UpdateStatistics(update);
|
||||||
if ((update.ProxyUp + update.ProxyDown) > 0 && DateTime.Now.Second % 3 == 0)
|
if ((update.ProxyUp + update.ProxyDown) > 0 && DateTime.Now.Second % 9 == 0)
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
|
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
|
||||||
}
|
}
|
||||||
@@ -289,7 +290,7 @@ namespace ServiceLib.ViewModels
|
|||||||
await ProfileExHandler.Instance.SaveTo();
|
await ProfileExHandler.Instance.SaveTo();
|
||||||
await StatisticsHandler.Instance.SaveTo();
|
await StatisticsHandler.Instance.SaveTo();
|
||||||
StatisticsHandler.Instance.Close();
|
StatisticsHandler.Instance.Close();
|
||||||
CoreHandler.Instance.CoreStop();
|
await CoreHandler.Instance.CoreStop();
|
||||||
|
|
||||||
Logging.SaveLog("MyAppExit End");
|
Logging.SaveLog("MyAppExit End");
|
||||||
}
|
}
|
||||||
@@ -313,6 +314,7 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
StartInfo = new ProcessStartInfo
|
StartInfo = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
|
UseShellExecute = true,
|
||||||
FileName = fileName,
|
FileName = fileName,
|
||||||
Arguments = arg.AppendQuotes(),
|
Arguments = arg.AppendQuotes(),
|
||||||
WorkingDirectory = Utils.StartupPath()
|
WorkingDirectory = Utils.StartupPath()
|
||||||
@@ -530,6 +532,10 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
Utils.ProcessStart("nautilus", Utils.GetConfigPath());
|
Utils.ProcessStart("nautilus", Utils.GetConfigPath());
|
||||||
}
|
}
|
||||||
|
else if (Utils.IsOSX())
|
||||||
|
{
|
||||||
|
Utils.ProcessStart("open", Utils.GetConfigPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Setting
|
#endregion Setting
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ namespace ServiceLib.ViewModels
|
|||||||
[Reactive] public bool EnableUpdateSubOnlyRemarksExist { get; set; }
|
[Reactive] public bool EnableUpdateSubOnlyRemarksExist { get; set; }
|
||||||
[Reactive] public bool EnableSecurityProtocolTls13 { get; set; }
|
[Reactive] public bool EnableSecurityProtocolTls13 { get; set; }
|
||||||
[Reactive] public bool AutoHideStartup { get; set; }
|
[Reactive] public bool AutoHideStartup { get; set; }
|
||||||
[Reactive] public bool EnableCheckPreReleaseUpdate { get; set; }
|
|
||||||
[Reactive] public bool EnableDragDropSort { get; set; }
|
[Reactive] public bool EnableDragDropSort { get; set; }
|
||||||
[Reactive] public bool DoubleClick2Activate { get; set; }
|
[Reactive] public bool DoubleClick2Activate { get; set; }
|
||||||
[Reactive] public int AutoUpdateInterval { get; set; }
|
[Reactive] public int AutoUpdateInterval { get; set; }
|
||||||
@@ -86,6 +85,7 @@ namespace ServiceLib.ViewModels
|
|||||||
[Reactive] public int TunMtu { get; set; }
|
[Reactive] public int TunMtu { get; set; }
|
||||||
[Reactive] public bool TunEnableExInbound { get; set; }
|
[Reactive] public bool TunEnableExInbound { get; set; }
|
||||||
[Reactive] public bool TunEnableIPv6Address { get; set; }
|
[Reactive] public bool TunEnableIPv6Address { get; set; }
|
||||||
|
[Reactive] public string TunLinuxSudoPassword { get; set; }
|
||||||
|
|
||||||
#endregion Tun mode
|
#endregion Tun mode
|
||||||
|
|
||||||
@@ -117,6 +117,8 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task Init()
|
private async Task Init()
|
||||||
{
|
{
|
||||||
|
await _updateView?.Invoke(EViewAction.InitSettingFont, null);
|
||||||
|
|
||||||
#region Core
|
#region Core
|
||||||
|
|
||||||
var inbound = _config.Inbound[0];
|
var inbound = _config.Inbound[0];
|
||||||
@@ -164,7 +166,6 @@ namespace ServiceLib.ViewModels
|
|||||||
EnableUpdateSubOnlyRemarksExist = _config.UiItem.EnableUpdateSubOnlyRemarksExist;
|
EnableUpdateSubOnlyRemarksExist = _config.UiItem.EnableUpdateSubOnlyRemarksExist;
|
||||||
EnableSecurityProtocolTls13 = _config.GuiItem.EnableSecurityProtocolTls13;
|
EnableSecurityProtocolTls13 = _config.GuiItem.EnableSecurityProtocolTls13;
|
||||||
AutoHideStartup = _config.UiItem.AutoHideStartup;
|
AutoHideStartup = _config.UiItem.AutoHideStartup;
|
||||||
EnableCheckPreReleaseUpdate = _config.GuiItem.CheckPreReleaseUpdate;
|
|
||||||
EnableDragDropSort = _config.UiItem.EnableDragDropSort;
|
EnableDragDropSort = _config.UiItem.EnableDragDropSort;
|
||||||
DoubleClick2Activate = _config.UiItem.DoubleClick2Activate;
|
DoubleClick2Activate = _config.UiItem.DoubleClick2Activate;
|
||||||
AutoUpdateInterval = _config.GuiItem.AutoUpdateInterval;
|
AutoUpdateInterval = _config.GuiItem.AutoUpdateInterval;
|
||||||
@@ -197,6 +198,7 @@ namespace ServiceLib.ViewModels
|
|||||||
TunMtu = _config.TunModeItem.Mtu;
|
TunMtu = _config.TunModeItem.Mtu;
|
||||||
TunEnableExInbound = _config.TunModeItem.EnableExInbound;
|
TunEnableExInbound = _config.TunModeItem.EnableExInbound;
|
||||||
TunEnableIPv6Address = _config.TunModeItem.EnableIPv6Address;
|
TunEnableIPv6Address = _config.TunModeItem.EnableIPv6Address;
|
||||||
|
TunLinuxSudoPassword = _config.TunModeItem.LinuxSudoPwd;
|
||||||
|
|
||||||
#endregion Tun mode
|
#endregion Tun mode
|
||||||
|
|
||||||
@@ -315,7 +317,6 @@ namespace ServiceLib.ViewModels
|
|||||||
_config.GuiItem.EnableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
|
_config.GuiItem.EnableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
|
||||||
_config.UiItem.AutoHideStartup = AutoHideStartup;
|
_config.UiItem.AutoHideStartup = AutoHideStartup;
|
||||||
_config.GuiItem.AutoUpdateInterval = AutoUpdateInterval;
|
_config.GuiItem.AutoUpdateInterval = AutoUpdateInterval;
|
||||||
_config.GuiItem.CheckPreReleaseUpdate = EnableCheckPreReleaseUpdate;
|
|
||||||
_config.UiItem.EnableDragDropSort = EnableDragDropSort;
|
_config.UiItem.EnableDragDropSort = EnableDragDropSort;
|
||||||
_config.UiItem.DoubleClick2Activate = DoubleClick2Activate;
|
_config.UiItem.DoubleClick2Activate = DoubleClick2Activate;
|
||||||
_config.GuiItem.TrayMenuServersLimit = TrayMenuServersLimit;
|
_config.GuiItem.TrayMenuServersLimit = TrayMenuServersLimit;
|
||||||
@@ -341,20 +342,19 @@ namespace ServiceLib.ViewModels
|
|||||||
_config.TunModeItem.Mtu = TunMtu;
|
_config.TunModeItem.Mtu = TunMtu;
|
||||||
_config.TunModeItem.EnableExInbound = TunEnableExInbound;
|
_config.TunModeItem.EnableExInbound = TunEnableExInbound;
|
||||||
_config.TunModeItem.EnableIPv6Address = TunEnableIPv6Address;
|
_config.TunModeItem.EnableIPv6Address = TunEnableIPv6Address;
|
||||||
|
if (TunLinuxSudoPassword != _config.TunModeItem.LinuxSudoPwd)
|
||||||
|
{
|
||||||
|
_config.TunModeItem.LinuxSudoPwd = DesUtils.Encrypt(TunLinuxSudoPassword);
|
||||||
|
}
|
||||||
|
|
||||||
//coreType
|
//coreType
|
||||||
await SaveCoreType();
|
await SaveCoreType();
|
||||||
|
|
||||||
if (await ConfigHandler.SaveConfig(_config) == 0)
|
if (await ConfigHandler.SaveConfig(_config) == 0)
|
||||||
{
|
{
|
||||||
if (needReboot)
|
await AutoStartupHandler.UpdateTask(_config);
|
||||||
{
|
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.NeedRebootTips);
|
NoticeHandler.Instance.Enqueue(needReboot ? ResUI.NeedRebootTips : ResUI.OperationSuccess);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
|
||||||
}
|
|
||||||
_updateView?.Invoke(EViewAction.CloseWindow, null);
|
_updateView?.Invoke(EViewAction.CloseWindow, null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ namespace ServiceLib.ViewModels
|
|||||||
private List<ProfileItem> _lstProfile;
|
private List<ProfileItem> _lstProfile;
|
||||||
private string _serverFilter = string.Empty;
|
private string _serverFilter = string.Empty;
|
||||||
private Dictionary<string, bool> _dicHeaderSort = new();
|
private Dictionary<string, bool> _dicHeaderSort = new();
|
||||||
private SpeedtestService? _speedtestHandler;
|
|
||||||
|
|
||||||
#endregion private prop
|
#endregion private prop
|
||||||
|
|
||||||
@@ -480,7 +479,10 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
await ConfigHandler.RemoveServer(_config, lstSelecteds);
|
await ConfigHandler.RemoveServer(_config, lstSelecteds);
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
||||||
|
if (lstSelecteds.Count == _profileItems.Count)
|
||||||
|
{
|
||||||
|
_profileItems.Clear();
|
||||||
|
}
|
||||||
RefreshServers();
|
RefreshServers();
|
||||||
if (exists)
|
if (exists)
|
||||||
{
|
{
|
||||||
@@ -686,12 +688,12 @@ namespace ServiceLib.ViewModels
|
|||||||
}
|
}
|
||||||
//ClearTestResult();
|
//ClearTestResult();
|
||||||
|
|
||||||
_speedtestHandler = new SpeedtestService(_config, lstSelecteds, actionType, UpdateSpeedtestHandler);
|
_ = new SpeedtestService(_config, lstSelecteds, actionType, UpdateSpeedtestHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ServerSpeedtestStop()
|
public void ServerSpeedtestStop()
|
||||||
{
|
{
|
||||||
_speedtestHandler?.ExitLoop();
|
MessageBus.Current.SendMessage("", EMsgCommand.StopSpeedtest.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Export2ClientConfigAsync(bool blClipboard)
|
private async Task Export2ClientConfigAsync(bool blClipboard)
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ namespace ServiceLib.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
//NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
||||||
_updateView?.Invoke(EViewAction.CloseWindow, null);
|
await _updateView?.Invoke(EViewAction.CloseWindow, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ namespace ServiceLib.ViewModels
|
|||||||
SelectedServer = new();
|
SelectedServer = new();
|
||||||
RunningServerToolTipText = "-";
|
RunningServerToolTipText = "-";
|
||||||
|
|
||||||
if (_config.TunModeItem.EnableTun && AppHandler.Instance.IsAdministrator)
|
if (_config.TunModeItem.EnableTun && AllowEnableTun())
|
||||||
{
|
{
|
||||||
EnableTun = true;
|
EnableTun = true;
|
||||||
}
|
}
|
||||||
@@ -414,10 +414,17 @@ namespace ServiceLib.ViewModels
|
|||||||
{
|
{
|
||||||
_config.TunModeItem.EnableTun = EnableTun;
|
_config.TunModeItem.EnableTun = EnableTun;
|
||||||
// When running as a non-administrator, reboot to administrator mode
|
// When running as a non-administrator, reboot to administrator mode
|
||||||
if (EnableTun && !AppHandler.Instance.IsAdministrator)
|
if (EnableTun && AllowEnableTun() == false)
|
||||||
{
|
{
|
||||||
_config.TunModeItem.EnableTun = false;
|
_config.TunModeItem.EnableTun = false;
|
||||||
|
if (Utils.IsWindows())
|
||||||
|
{
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
|
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
|
||||||
|
}
|
||||||
|
else if (Utils.IsLinux())
|
||||||
|
{
|
||||||
|
NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordIsEmpty);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await ConfigHandler.SaveConfig(_config);
|
await ConfigHandler.SaveConfig(_config);
|
||||||
@@ -425,6 +432,19 @@ namespace ServiceLib.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool AllowEnableTun()
|
||||||
|
{
|
||||||
|
if (Utils.IsWindows())
|
||||||
|
{
|
||||||
|
return AppHandler.Instance.IsAdministrator;
|
||||||
|
}
|
||||||
|
else if (Utils.IsLinux())
|
||||||
|
{
|
||||||
|
return _config.TunModeItem.LinuxSudoPwd.IsNotEmpty();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion System proxy and Routings
|
#endregion System proxy and Routings
|
||||||
|
|
||||||
#region UI
|
#region UI
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ namespace v2rayN.Desktop;
|
|||||||
|
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
//public static EventWaitHandle ProgramStarted;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
if (!AppHandler.Instance.InitApp())
|
if (!AppHandler.Instance.InitApp())
|
||||||
@@ -32,7 +30,7 @@ public partial class App : Application
|
|||||||
{
|
{
|
||||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
{
|
{
|
||||||
OnStartup(desktop.Args);
|
AppHandler.Instance.InitComponents();
|
||||||
|
|
||||||
desktop.Exit += OnExit;
|
desktop.Exit += OnExit;
|
||||||
desktop.MainWindow = new MainWindow();
|
desktop.MainWindow = new MainWindow();
|
||||||
@@ -41,22 +39,6 @@ public partial class App : Application
|
|||||||
base.OnFrameworkInitializationCompleted();
|
base.OnFrameworkInitializationCompleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStartup(string[]? Args)
|
|
||||||
{
|
|
||||||
var exePathKey = Utils.GetMd5(Utils.GetExePath());
|
|
||||||
|
|
||||||
var rebootas = (Args ?? new string[] { }).Any(t => t == Global.RebootAs);
|
|
||||||
//ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, exePathKey, out bool bCreatedNew);
|
|
||||||
//if (!rebootas && !bCreatedNew)
|
|
||||||
//{
|
|
||||||
// ProgramStarted.Set();
|
|
||||||
// Environment.Exit(0);
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
AppHandler.Instance.InitComponents();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.ExceptionObject != null)
|
if (e.ExceptionObject != null)
|
||||||
@@ -87,11 +69,12 @@ public partial class App : Application
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MenuExit_Click(object? sender, EventArgs e)
|
private async void MenuExit_Click(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.MyAppExitAsync(false);
|
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||||
|
if (service != null) await service.MyAppExitAsync(false);
|
||||||
|
|
||||||
desktop.Shutdown();
|
desktop.Shutdown();
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
v2rayN/v2rayN.Desktop/Assets/Fonts/NotoSansSC-Regular.ttf
Normal file
BIN
v2rayN/v2rayN.Desktop/Assets/Fonts/NotoSansSC-Regular.ttf
Normal file
Binary file not shown.
19
v2rayN/v2rayN.Desktop/Common/AppBuilderExtension.cs
Normal file
19
v2rayN/v2rayN.Desktop/Common/AppBuilderExtension.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Media;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace v2rayN.Desktop.Common
|
||||||
|
{
|
||||||
|
public static class AppBuilderExtension
|
||||||
|
{
|
||||||
|
public static AppBuilder WithFontByDefault(this AppBuilder appBuilder)
|
||||||
|
{
|
||||||
|
var uri = $"avares://{Assembly.GetExecutingAssembly().GetName().Name}/Assets/Fonts#Noto Sans SC";
|
||||||
|
return appBuilder.With(new FontManagerOptions()
|
||||||
|
{
|
||||||
|
DefaultFamilyName = uri,
|
||||||
|
FontFallbacks = new[] { new FontFallback { FontFamily = new FontFamily(uri) } }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +1,56 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.ReactiveUI;
|
using Avalonia.ReactiveUI;
|
||||||
|
using v2rayN.Desktop.Common;
|
||||||
|
|
||||||
namespace v2rayN.Desktop;
|
namespace v2rayN.Desktop;
|
||||||
|
|
||||||
internal class Program
|
internal class Program
|
||||||
{
|
{
|
||||||
|
public static EventWaitHandle ProgramStarted;
|
||||||
|
|
||||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||||
// yet and stuff might break.
|
// yet and stuff might break.
|
||||||
[STAThread]
|
[STAThread]
|
||||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
OnStartup(args);
|
||||||
|
|
||||||
|
BuildAvaloniaApp()
|
||||||
.StartWithClassicDesktopLifetime(args);
|
.StartWithClassicDesktopLifetime(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnStartup(string[]? Args)
|
||||||
|
{
|
||||||
|
if (Utils.IsWindows())
|
||||||
|
{
|
||||||
|
var exePathKey = Utils.GetMd5(Utils.GetExePath());
|
||||||
|
var rebootas = (Args ?? Array.Empty<string>()).Any(t => t == Global.RebootAs);
|
||||||
|
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, exePathKey, out bool bCreatedNew);
|
||||||
|
if (!rebootas && !bCreatedNew)
|
||||||
|
{
|
||||||
|
ProgramStarted.Set();
|
||||||
|
Environment.Exit(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_ = new Mutex(true, "v2rayN", out var bOnlyOneInstance);
|
||||||
|
if (!bOnlyOneInstance)
|
||||||
|
{
|
||||||
|
Environment.Exit(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Avalonia configuration, don't remove; also used by visual designer.
|
// Avalonia configuration, don't remove; also used by visual designer.
|
||||||
public static AppBuilder BuildAvaloniaApp()
|
public static AppBuilder BuildAvaloniaApp()
|
||||||
=> AppBuilder.Configure<App>()
|
=> AppBuilder.Configure<App>()
|
||||||
.UsePlatformDetect()
|
.UsePlatformDetect()
|
||||||
.WithInterFont()
|
//.WithInterFont()
|
||||||
|
.WithFontByDefault()
|
||||||
.LogToTrace()
|
.LogToTrace()
|
||||||
.UseReactiveUI();
|
.UseReactiveUI();
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Notifications;
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Media;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
@@ -9,14 +12,11 @@ namespace v2rayN.Desktop.ViewModels
|
|||||||
{
|
{
|
||||||
public class ThemeSettingViewModel : MyReactiveObject
|
public class ThemeSettingViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
[Reactive]
|
[Reactive] public bool ColorModeDark { get; set; }
|
||||||
public bool ColorModeDark { get; set; }
|
|
||||||
|
|
||||||
[Reactive]
|
[Reactive] public int CurrentFontSize { get; set; }
|
||||||
public int CurrentFontSize { get; set; }
|
|
||||||
|
|
||||||
[Reactive]
|
[Reactive] public string CurrentLanguage { get; set; }
|
||||||
public string CurrentLanguage { get; set; }
|
|
||||||
|
|
||||||
public ThemeSettingViewModel()
|
public ThemeSettingViewModel()
|
||||||
{
|
{
|
||||||
@@ -29,6 +29,7 @@ namespace v2rayN.Desktop.ViewModels
|
|||||||
private void RestoreUI()
|
private void RestoreUI()
|
||||||
{
|
{
|
||||||
ModifyTheme(_config.UiItem.ColorModeDark);
|
ModifyTheme(_config.UiItem.ColorModeDark);
|
||||||
|
ModifyFontFamily();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BindingUI()
|
private void BindingUI()
|
||||||
@@ -89,53 +90,54 @@ namespace v2rayN.Desktop.ViewModels
|
|||||||
|
|
||||||
private void ModifyFontSize(double size)
|
private void ModifyFontSize(double size)
|
||||||
{
|
{
|
||||||
Style buttonStyle = new(x => x.OfType<Button>());
|
Style style = new(x => Selectors.Or(
|
||||||
buttonStyle.Add(new Setter()
|
x.OfType<Button>(),
|
||||||
|
x.OfType<TextBox>(),
|
||||||
|
x.OfType<TextBlock>(),
|
||||||
|
x.OfType<Menu>(),
|
||||||
|
x.OfType<ContextMenu>(),
|
||||||
|
x.OfType<DataGridRow>(),
|
||||||
|
x.OfType<ListBoxItem>()
|
||||||
|
));
|
||||||
|
style.Add(new Setter()
|
||||||
{
|
{
|
||||||
Property = Button.FontSizeProperty,
|
Property = TemplatedControl.FontSizeProperty,
|
||||||
Value = size,
|
Value = size,
|
||||||
});
|
});
|
||||||
Application.Current?.Styles.Add(buttonStyle);
|
Application.Current?.Styles.Add(style);
|
||||||
|
}
|
||||||
|
|
||||||
Style textStyle = new(x => x.OfType<TextBox>());
|
private void ModifyFontFamily()
|
||||||
textStyle.Add(new Setter()
|
|
||||||
{
|
{
|
||||||
Property = TextBox.FontSizeProperty,
|
var currentFontFamily = _config.UiItem.CurrentFontFamily;
|
||||||
Value = size,
|
if (currentFontFamily.IsNullOrEmpty())
|
||||||
});
|
{
|
||||||
Application.Current?.Styles.Add(textStyle);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Style textBlockStyle = new(x => x.OfType<TextBlock>());
|
try
|
||||||
textBlockStyle.Add(new Setter()
|
|
||||||
{
|
{
|
||||||
Property = TextBlock.FontSizeProperty,
|
Style style = new(x => Selectors.Or(
|
||||||
Value = size,
|
x.OfType<Button>(),
|
||||||
});
|
x.OfType<TextBox>(),
|
||||||
Application.Current?.Styles.Add(textBlockStyle);
|
x.OfType<TextBlock>(),
|
||||||
|
x.OfType<Menu>(),
|
||||||
Style menuStyle = new(x => x.OfType<Menu>());
|
x.OfType<ContextMenu>(),
|
||||||
menuStyle.Add(new Setter()
|
x.OfType<DataGridRow>(),
|
||||||
|
x.OfType<ListBoxItem>(),
|
||||||
|
x.OfType<WindowNotificationManager>()
|
||||||
|
));
|
||||||
|
style.Add(new Setter()
|
||||||
{
|
{
|
||||||
Property = Menu.FontSizeProperty,
|
Property = TemplatedControl.FontFamilyProperty,
|
||||||
Value = size,
|
Value = new FontFamily(currentFontFamily),
|
||||||
});
|
});
|
||||||
Application.Current?.Styles.Add(menuStyle);
|
Application.Current?.Styles.Add(style);
|
||||||
|
}
|
||||||
Style dataStyle = new(x => x.OfType<DataGridRow>());
|
catch (Exception ex)
|
||||||
dataStyle.Add(new Setter()
|
|
||||||
{
|
{
|
||||||
Property = DataGridRow.FontSizeProperty,
|
Logging.SaveLog("ModifyFontFamily", ex);
|
||||||
Value = size,
|
}
|
||||||
});
|
|
||||||
Application.Current?.Styles.Add(dataStyle);
|
|
||||||
|
|
||||||
Style listStyle = new(x => x.OfType<ListBoxItem>());
|
|
||||||
listStyle.Add(new Setter()
|
|
||||||
{
|
|
||||||
Property = ListBoxItem.FontSizeProperty,
|
|
||||||
Value = size,
|
|
||||||
});
|
|
||||||
Application.Current?.Styles.Add(listStyle);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
x:Name="txtPort"
|
x:Name="txtPort"
|
||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Classes="Margin8" />
|
Classes="Margin8" />
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
x:Name="txtAlterId"
|
x:Name="txtAlterId"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Classes="Margin8" />
|
Classes="Margin8" />
|
||||||
|
|
||||||
@@ -458,7 +458,7 @@
|
|||||||
x:Name="cmbHeaderType8"
|
x:Name="cmbHeaderType8"
|
||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
Classes="Margin8" />
|
Classes="Margin8" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
<Grid
|
||||||
@@ -541,7 +541,7 @@
|
|||||||
x:Name="txtShortId9"
|
x:Name="txtShortId9"
|
||||||
Grid.Row="5"
|
Grid.Row="5"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Classes="Margin8" />
|
Classes="Margin8" />
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -584,7 +584,7 @@
|
|||||||
x:Name="cmbNetwork"
|
x:Name="cmbNetwork"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
Classes="Margin8" />
|
Classes="Margin8" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
@@ -600,12 +600,50 @@
|
|||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Classes="Margin8"
|
Classes="Margin8"
|
||||||
Text="{x:Static resx:ResUI.TbHeaderType}" />
|
Text="{x:Static resx:ResUI.TbHeaderType}" />
|
||||||
<ComboBox
|
<StackPanel
|
||||||
x:Name="cmbHeaderType"
|
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
VerticalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbHeaderType"
|
||||||
|
Width="200"
|
||||||
Classes="Margin8" />
|
Classes="Margin8" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
x:Name="btnExtra"
|
||||||
|
Width="30"
|
||||||
|
Height="30"
|
||||||
|
Margin="10,0"
|
||||||
|
Theme="{DynamicResource BorderlessButton}">
|
||||||
|
<Button.Content>
|
||||||
|
<PathIcon
|
||||||
|
Width="20"
|
||||||
|
Height="20"
|
||||||
|
Data="{StaticResource building_more}"
|
||||||
|
Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
||||||
|
</Button.Content>
|
||||||
|
<Button.Flyout>
|
||||||
|
<Flyout>
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Classes="Margin8"
|
||||||
|
Text="{x:Static resx:ResUI.TransportExtraTip}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtExtra"
|
||||||
|
Width="400"
|
||||||
|
MinHeight="100"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Classes="TextArea Margin8"
|
||||||
|
MinLines="6"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</StackPanel>
|
||||||
|
</Flyout>
|
||||||
|
</Button.Flyout>
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
x:Name="tipHeaderType"
|
x:Name="tipHeaderType"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
@@ -680,7 +718,7 @@
|
|||||||
x:Name="cmbStreamSecurity"
|
x:Name="cmbStreamSecurity"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
Classes="Margin8" />
|
Classes="Margin8" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
<Grid
|
||||||
@@ -749,7 +787,7 @@
|
|||||||
x:Name="cmbAllowInsecure"
|
x:Name="cmbAllowInsecure"
|
||||||
Grid.Row="4"
|
Grid.Row="4"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
Classes="Margin8" />
|
Classes="Margin8" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
<Grid
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.SelectedValue).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Extra, v => v.txtExtra.Text).DisposeWith(disposables);
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.StreamSecurity, v => v.cmbStreamSecurity.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.StreamSecurity, v => v.cmbStreamSecurity.SelectedValue).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Sni, v => v.txtSNI.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Sni, v => v.txtSNI.Text).DisposeWith(disposables);
|
||||||
@@ -299,6 +300,13 @@ namespace v2rayN.Desktop.Views
|
|||||||
cmbHeaderType.Items.Add(it);
|
cmbHeaderType.Items.Add(it);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (network is nameof(ETransport.splithttp) or nameof(ETransport.xhttp))
|
||||||
|
{
|
||||||
|
Global.XhttpMode.ForEach(it =>
|
||||||
|
{
|
||||||
|
cmbHeaderType.Items.Add(it);
|
||||||
|
});
|
||||||
|
}
|
||||||
else if (network == nameof(ETransport.grpc))
|
else if (network == nameof(ETransport.grpc))
|
||||||
{
|
{
|
||||||
cmbHeaderType.Items.Add(Global.GrpcGunMode);
|
cmbHeaderType.Items.Add(Global.GrpcGunMode);
|
||||||
@@ -319,6 +327,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
network = Global.DefaultNetwork;
|
network = Global.DefaultNetwork;
|
||||||
}
|
}
|
||||||
labHeaderType.IsVisible = true;
|
labHeaderType.IsVisible = true;
|
||||||
|
btnExtra.IsVisible = false;
|
||||||
tipRequestHost.Text =
|
tipRequestHost.Text =
|
||||||
tipPath.Text =
|
tipPath.Text =
|
||||||
tipHeaderType.Text = string.Empty;
|
tipHeaderType.Text = string.Empty;
|
||||||
@@ -337,11 +346,19 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
case nameof(ETransport.ws):
|
case nameof(ETransport.ws):
|
||||||
case nameof(ETransport.httpupgrade):
|
case nameof(ETransport.httpupgrade):
|
||||||
case nameof(ETransport.splithttp):
|
|
||||||
tipRequestHost.Text = ResUI.TransportRequestHostTip2;
|
tipRequestHost.Text = ResUI.TransportRequestHostTip2;
|
||||||
tipPath.Text = ResUI.TransportPathTip1;
|
tipPath.Text = ResUI.TransportPathTip1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nameof(ETransport.splithttp):
|
||||||
|
case nameof(ETransport.xhttp):
|
||||||
|
tipRequestHost.Text = ResUI.TransportRequestHostTip2;
|
||||||
|
tipPath.Text = ResUI.TransportPathTip1;
|
||||||
|
tipHeaderType.Text = ResUI.TransportHeaderTypeTip5;
|
||||||
|
labHeaderType.IsVisible = false;
|
||||||
|
btnExtra.IsVisible = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.h2):
|
case nameof(ETransport.h2):
|
||||||
tipRequestHost.Text = ResUI.TransportRequestHostTip3;
|
tipRequestHost.Text = ResUI.TransportRequestHostTip3;
|
||||||
tipPath.Text = ResUI.TransportPathTip2;
|
tipPath.Text = ResUI.TransportPathTip2;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
<ListBox
|
<ListBox
|
||||||
x:Name="lstCheckUpdates"
|
x:Name="lstCheckUpdates"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
ItemsSource="{Binding CheckUpdateItems}">
|
ItemsSource="{Binding CheckUpdateModels}">
|
||||||
<ItemsControl.ItemsPanel>
|
<ItemsControl.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<StackPanel Orientation="Vertical" />
|
<StackPanel Orientation="Vertical" />
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
this.WhenActivated(disposables =>
|
this.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
this.OneWayBind(ViewModel, vm => vm.CheckUpdateItems, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables);
|
this.OneWayBind(ViewModel, vm => vm.CheckUpdateModels, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables);
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
|
||||||
@@ -29,7 +29,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
case EViewAction.DispatcherCheckUpdate:
|
case EViewAction.DispatcherCheckUpdate:
|
||||||
if (obj is null) return false;
|
if (obj is null) return false;
|
||||||
Dispatcher.UIThread.Post(() =>
|
Dispatcher.UIThread.Post(() =>
|
||||||
ViewModel?.UpdateViewResult((CheckUpdateItem)obj),
|
ViewModel?.UpdateViewResult((CheckUpdateModel)obj),
|
||||||
DispatcherPriority.Default);
|
DispatcherPriority.Default);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@
|
|||||||
<MenuItem x:Name="menuClose" Padding="8,0">
|
<MenuItem x:Name="menuClose" Padding="8,0">
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="{x:Static resx:ResUI.menuClose}" />
|
<TextBlock Text="{x:Static resx:ResUI.menuExit}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</MenuItem.Header>
|
</MenuItem.Header>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ using Avalonia.Interactivity;
|
|||||||
using Avalonia.ReactiveUI;
|
using Avalonia.ReactiveUI;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using DialogHostAvalonia;
|
using DialogHostAvalonia;
|
||||||
|
using MsBox.Avalonia.Enums;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using v2rayN.Desktop.Common;
|
using v2rayN.Desktop.Common;
|
||||||
|
|
||||||
@@ -29,15 +29,12 @@ namespace v2rayN.Desktop.Views
|
|||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
_manager = new WindowNotificationManager(TopLevel.GetTopLevel(this)) { MaxItems = 3, Position = NotificationPosition.BottomRight };
|
_manager = new WindowNotificationManager(TopLevel.GetTopLevel(this)) { MaxItems = 3, Position = NotificationPosition.BottomRight };
|
||||||
|
|
||||||
//ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
|
||||||
|
|
||||||
this.Closing += MainWindow_Closing;
|
|
||||||
this.KeyDown += MainWindow_KeyDown;
|
this.KeyDown += MainWindow_KeyDown;
|
||||||
menuSettingsSetUWP.Click += menuSettingsSetUWP_Click;
|
menuSettingsSetUWP.Click += menuSettingsSetUWP_Click;
|
||||||
menuPromotion.Click += menuPromotion_Click;
|
menuPromotion.Click += menuPromotion_Click;
|
||||||
menuClose.Click += menuClose_Click;
|
|
||||||
menuCheckUpdate.Click += MenuCheckUpdate_Click;
|
menuCheckUpdate.Click += MenuCheckUpdate_Click;
|
||||||
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
||||||
|
menuClose.Click += MenuClose_Click;
|
||||||
|
|
||||||
MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(DelegateSnackMsg);
|
MessageBus.Current.Listen<string>(EMsgCommand.SendSnackMsg.ToString()).Subscribe(DelegateSnackMsg);
|
||||||
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
||||||
@@ -114,10 +111,17 @@ namespace v2rayN.Desktop.Views
|
|||||||
this.Title = $"{Utils.GetVersion()} - {(AppHandler.Instance.IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
this.Title = $"{Utils.GetVersion()} - {(AppHandler.Instance.IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||||
if (Utils.IsWindows())
|
if (Utils.IsWindows())
|
||||||
{
|
{
|
||||||
|
ThreadPool.RegisterWaitForSingleObject(Program.ProgramStarted, OnProgramStarted, null, -1, false);
|
||||||
|
|
||||||
menuGlobalHotkeySetting.IsVisible = false;
|
menuGlobalHotkeySetting.IsVisible = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (AppHandler.Instance.IsAdministrator)
|
||||||
|
{
|
||||||
|
this.Title = $"{Utils.GetVersion()} - {ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp}";
|
||||||
|
NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp);
|
||||||
|
}
|
||||||
menuRebootAsAdmin.IsVisible = false;
|
menuRebootAsAdmin.IsVisible = false;
|
||||||
menuSettingsSetUWP.IsVisible = false;
|
menuSettingsSetUWP.IsVisible = false;
|
||||||
menuGlobalHotkeySetting.IsVisible = false;
|
menuGlobalHotkeySetting.IsVisible = false;
|
||||||
@@ -158,7 +162,9 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void OnProgramStarted(object state, bool timeout)
|
private void OnProgramStarted(object state, bool timeout)
|
||||||
{
|
{
|
||||||
ShowHideWindow(true);
|
Dispatcher.UIThread.Post(() =>
|
||||||
|
ShowHideWindow(true),
|
||||||
|
DispatcherPriority.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DelegateSnackMsg(string content)
|
private void DelegateSnackMsg(string content)
|
||||||
@@ -271,10 +277,23 @@ namespace v2rayN.Desktop.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MainWindow_Closing(object? sender, CancelEventArgs e)
|
protected override async void OnClosing(WindowClosingEventArgs e)
|
||||||
{
|
{
|
||||||
|
Logging.SaveLog("OnClosing -> " + e.CloseReason.ToString());
|
||||||
|
|
||||||
|
switch (e.CloseReason)
|
||||||
|
{
|
||||||
|
case WindowCloseReason.OwnerWindowClosing or WindowCloseReason.WindowClosing:
|
||||||
e.Cancel = true;
|
e.Cancel = true;
|
||||||
ShowHideWindow(false);
|
ShowHideWindow(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WindowCloseReason.ApplicationShutdown or WindowCloseReason.OSShutdown:
|
||||||
|
await ViewModel?.MyAppExitAsync(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnClosing(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void MainWindow_KeyDown(object? sender, KeyEventArgs e)
|
private async void MainWindow_KeyDown(object? sender, KeyEventArgs e)
|
||||||
@@ -302,12 +321,6 @@ namespace v2rayN.Desktop.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void menuClose_Click(object? sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
StorageUI();
|
|
||||||
ShowHideWindow(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void menuPromotion_Click(object? sender, RoutedEventArgs e)
|
private void menuPromotion_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
|
Utils.ProcessStart($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}");
|
||||||
@@ -355,6 +368,17 @@ namespace v2rayN.Desktop.Views
|
|||||||
DialogHost.Show(_backupAndRestoreView);
|
DialogHost.Show(_backupAndRestoreView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void MenuClose_Click(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (await UI.ShowYesNo(this, ResUI.menuExitTips) == ButtonResult.No)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StorageUI();
|
||||||
|
|
||||||
|
await ViewModel?.MyAppExitAsync(false);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Event
|
#endregion Event
|
||||||
|
|
||||||
#region UI
|
#region UI
|
||||||
@@ -373,9 +397,17 @@ namespace v2rayN.Desktop.Views
|
|||||||
this.Focus();
|
this.Focus();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (Utils.IsWindows())
|
||||||
{
|
{
|
||||||
this.Hide();
|
this.Hide();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.WindowState = WindowState.Minimized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_config.UiItem.ShowInTaskbar = bl;
|
_config.UiItem.ShowInTaskbar = bl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,7 @@
|
|||||||
Classes="TextArea"
|
Classes="TextArea"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
TextAlignment="Left"
|
TextAlignment="Left"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
TextWrapping="Wrap">
|
TextWrapping="Wrap">
|
||||||
<TextBox.ContextMenu>
|
<TextBox.ContextMenu>
|
||||||
<ContextMenu>
|
<ContextMenu>
|
||||||
|
|||||||
@@ -377,7 +377,7 @@
|
|||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<!--
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
@@ -390,6 +390,7 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Classes="Margin8" />
|
Classes="Margin8" />
|
||||||
|
<!--
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
@@ -488,18 +489,7 @@
|
|||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Classes="Margin8" />
|
Classes="Margin8" />
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Grid.Row="9"
|
|
||||||
Grid.Column="0"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Classes="Margin8"
|
|
||||||
Text="{x:Static resx:ResUI.TbSettingsEnableCheckPreReleaseUpdate}" />
|
|
||||||
<ToggleSwitch
|
|
||||||
x:Name="togEnableCheckPreReleaseUpdate"
|
|
||||||
Grid.Row="9"
|
|
||||||
Grid.Column="1"
|
|
||||||
HorizontalAlignment="Left"
|
|
||||||
Classes="Margin8" />
|
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="11"
|
Grid.Row="11"
|
||||||
@@ -533,7 +523,6 @@
|
|||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Classes="Margin8"
|
Classes="Margin8"
|
||||||
IsVisible="False"
|
|
||||||
Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamily}" />
|
Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamily}" />
|
||||||
<ComboBox
|
<ComboBox
|
||||||
x:Name="cmbcurrentFontFamily"
|
x:Name="cmbcurrentFontFamily"
|
||||||
@@ -541,15 +530,13 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="200"
|
Width="200"
|
||||||
Classes="Margin8"
|
Classes="Margin8"
|
||||||
IsVisible="False"
|
|
||||||
MaxDropDownHeight="1000" />
|
MaxDropDownHeight="1000" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="16"
|
Grid.Row="16"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Classes="Margin8"
|
Classes="Margin8"
|
||||||
IsVisible="False"
|
Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamilyLinuxTip}"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsCurrentFontFamilyTip}"
|
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -677,7 +664,6 @@
|
|||||||
Classes="Margin8"
|
Classes="Margin8"
|
||||||
Text="{x:Static resx:ResUI.TbSettingsChinaUserTip}"
|
Text="{x:Static resx:ResUI.TbSettingsChinaUserTip}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
@@ -735,6 +721,7 @@
|
|||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
@@ -808,6 +795,27 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Classes="Margin8" />
|
Classes="Margin8" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="7"
|
||||||
|
Grid.Column="0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Classes="Margin8"
|
||||||
|
Text="{x:Static resx:ResUI.TbSettingsLinuxSudoPassword}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtLinuxSudoPassword"
|
||||||
|
Grid.Row="7"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Classes="Margin8" />
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="7"
|
||||||
|
Grid.Column="2"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Classes="Margin8"
|
||||||
|
Text="{x:Static resx:ResUI.TbSettingsLinuxSudoPasswordTip}"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
btnCancel.Click += (s, e) => this.Close();
|
btnCancel.Click += (s, e) => this.Close();
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
// var lstFonts = GetFonts(Utils.GetFontsPath());
|
|
||||||
|
|
||||||
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
|
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
@@ -100,9 +99,6 @@ namespace v2rayN.Desktop.Views
|
|||||||
cmbMainGirdOrientation.Items.Add(it.ToString());
|
cmbMainGirdOrientation.Items.Add(it.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
//lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); });
|
|
||||||
//cmbcurrentFontFamily.Items.Add(string.Empty);
|
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
this.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
this.Bind(ViewModel, vm => vm.localPort, v => v.txtlocalPort.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.localPort, v => v.txtlocalPort.Text).DisposeWith(disposables);
|
||||||
@@ -127,7 +123,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
this.Bind(ViewModel, vm => vm.hyDownMbps, v => v.txtDownMbps.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.hyDownMbps, v => v.txtDownMbps.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.enableFragment, v => v.togenableFragment.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.enableFragment, v => v.togenableFragment.IsChecked).DisposeWith(disposables);
|
||||||
|
|
||||||
//this.Bind(ViewModel, vm => vm.AutoRun, v => v.togAutoRun.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.AutoRun, v => v.togAutoRun.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.EnableStatistics, v => v.togEnableStatistics.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableStatistics, v => v.togEnableStatistics.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.KeepOlderDedupl, v => v.togKeepOlderDedupl.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.KeepOlderDedupl, v => v.togKeepOlderDedupl.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.IgnoreGeoUpdateCore, v => v.togIgnoreGeoUpdateCore.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.IgnoreGeoUpdateCore, v => v.togIgnoreGeoUpdateCore.IsChecked).DisposeWith(disposables);
|
||||||
@@ -135,7 +131,6 @@ namespace v2rayN.Desktop.Views
|
|||||||
this.Bind(ViewModel, vm => vm.EnableUpdateSubOnlyRemarksExist, v => v.togEnableUpdateSubOnlyRemarksExist.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableUpdateSubOnlyRemarksExist, v => v.togEnableUpdateSubOnlyRemarksExist.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.DoubleClick2Activate, v => v.togDoubleClick2Activate.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.DoubleClick2Activate, v => v.togDoubleClick2Activate.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.AutoUpdateInterval, v => v.txtautoUpdateInterval.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.AutoUpdateInterval, v => v.txtautoUpdateInterval.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CurrentFontFamily, v => v.cmbcurrentFontFamily.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CurrentFontFamily, v => v.cmbcurrentFontFamily.SelectedValue).DisposeWith(disposables);
|
||||||
@@ -157,6 +152,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.SelectedValue).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.TunEnableExInbound, v => v.togEnableExInbound.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunEnableExInbound, v => v.togEnableExInbound.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.TunLinuxSudoPassword, v => v.txtLinuxSudoPassword.Text).DisposeWith(disposables);
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.SelectedValue).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.SelectedValue).DisposeWith(disposables);
|
||||||
@@ -179,61 +175,55 @@ namespace v2rayN.Desktop.Views
|
|||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case EViewAction.CloseWindow:
|
case EViewAction.CloseWindow:
|
||||||
// WindowsUtils.SetAutoRun(Global.AutoRunRegPath, Global.AutoRunName, togAutoRun.IsChecked ?? false);
|
|
||||||
this.Close(true);
|
this.Close(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EViewAction.InitSettingFont:
|
||||||
|
await InitSettingFont();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return await Task.FromResult(true);
|
return await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//private List<string> GetFonts(string path)
|
private async Task InitSettingFont()
|
||||||
//{
|
{
|
||||||
// var lstFonts = new List<string>();
|
var lstFonts = await GetFonts();
|
||||||
// try
|
lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); });
|
||||||
// {
|
cmbcurrentFontFamily.Items.Add(string.Empty);
|
||||||
// string[] searchPatterns = { "*.ttf", "*.ttc" };
|
}
|
||||||
// var files = new List<string>();
|
|
||||||
// foreach (var pattern in searchPatterns)
|
private async Task<List<string>> GetFonts()
|
||||||
// {
|
{
|
||||||
// files.AddRange(Directory.GetFiles(path, pattern));
|
var lstFonts = new List<string>();
|
||||||
// }
|
try
|
||||||
// var culture = _config.uiItem.currentLanguage == Global.Languages[0] ? "zh-cn" : "en-us";
|
{
|
||||||
// var culture2 = "en-us";
|
if (Utils.IsWindows())
|
||||||
// foreach (var ttf in files)
|
{
|
||||||
// {
|
return lstFonts;
|
||||||
// var families = Fonts.GetFontFamilies(Utils.GetFontsPath(ttf));
|
}
|
||||||
// foreach (FontFamily family in families)
|
else if (Utils.IsLinux())
|
||||||
// {
|
{
|
||||||
// var typefaces = family.GetTypefaces();
|
var result = await Utils.GetLinuxFontFamily("zh");
|
||||||
// foreach (Typeface typeface in typefaces)
|
if (result.IsNullOrEmpty())
|
||||||
// {
|
{
|
||||||
// typeface.TryGetGlyphTypeface(out GlyphTypeface glyph);
|
return lstFonts;
|
||||||
// //var fontFace = glyph.Win32FaceNames[new CultureInfo("en-us")];
|
}
|
||||||
// //if (!fontFace.Equals("Regular") && !fontFace.Equals("Normal"))
|
|
||||||
// //{
|
var lst = result.Split(Environment.NewLine)
|
||||||
// // continue;
|
.Where(t => t.IsNotEmpty())
|
||||||
// //}
|
.ToList()
|
||||||
// var fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture)];
|
.Select(t => t.Split(",").FirstOrDefault() ?? "")
|
||||||
// if (Utils.IsNullOrEmpty(fontFamily))
|
.OrderBy(t => t)
|
||||||
// {
|
.ToList();
|
||||||
// fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture2)];
|
return lst;
|
||||||
// if (Utils.IsNullOrEmpty(fontFamily))
|
}
|
||||||
// {
|
}
|
||||||
// continue;
|
catch (Exception ex)
|
||||||
// }
|
{
|
||||||
// }
|
Logging.SaveLog("fill fonts error", ex);
|
||||||
// lstFonts.Add(fontFamily);
|
}
|
||||||
// break;
|
return lstFonts;
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// catch (Exception ex)
|
|
||||||
// {
|
|
||||||
// Logging.SaveLog("fill fonts error", ex);
|
|
||||||
// }
|
|
||||||
// return lstFonts;
|
|
||||||
//}
|
|
||||||
|
|
||||||
private void ClbdestOverride_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
private void ClbdestOverride_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -204,7 +204,7 @@
|
|||||||
Binding="{Binding SubRemarks}"
|
Binding="{Binding SubRemarks}"
|
||||||
Header="{x:Static resx:ResUI.LvSubscription}"
|
Header="{x:Static resx:ResUI.LvSubscription}"
|
||||||
Tag="SubRemarks" />
|
Tag="SubRemarks" />
|
||||||
<DataGridTemplateColumn SortMemberPath="Delay" Tag="Delay">
|
<DataGridTemplateColumn SortMemberPath="Delay" Tag="DelayVal">
|
||||||
<DataGridTemplateColumn.Header>
|
<DataGridTemplateColumn.Header>
|
||||||
<TextBlock Text="{x:Static resx:ResUI.LvTestDelay}" />
|
<TextBlock Text="{x:Static resx:ResUI.LvTestDelay}" />
|
||||||
</DataGridTemplateColumn.Header>
|
</DataGridTemplateColumn.Header>
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
|
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
|
||||||
lstProfiles.DoubleTapped += LstProfiles_DoubleTapped;
|
lstProfiles.DoubleTapped += LstProfiles_DoubleTapped;
|
||||||
lstProfiles.LoadingRow += LstProfiles_LoadingRow;
|
lstProfiles.LoadingRow += LstProfiles_LoadingRow;
|
||||||
|
lstProfiles.Sorting += LstProfiles_Sorting;
|
||||||
//if (_config.uiItem.enableDragDropSort)
|
//if (_config.uiItem.enableDragDropSort)
|
||||||
//{
|
//{
|
||||||
// lstProfiles.AllowDrop = true;
|
// lstProfiles.AllowDrop = true;
|
||||||
@@ -92,6 +93,13 @@ namespace v2rayN.Desktop.Views
|
|||||||
ViewModel?.RefreshServers();
|
ViewModel?.RefreshServers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void LstProfiles_Sorting(object? sender, DataGridColumnEventArgs e)
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
await ViewModel?.SortServer(e.Column.Tag.ToString());
|
||||||
|
e.Handled = false;
|
||||||
|
}
|
||||||
|
|
||||||
//#region Event
|
//#region Event
|
||||||
|
|
||||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||||
@@ -189,6 +197,8 @@ namespace v2rayN.Desktop.Views
|
|||||||
|
|
||||||
private void LstProfiles_DoubleTapped(object? sender, Avalonia.Input.TappedEventArgs e)
|
private void LstProfiles_DoubleTapped(object? sender, Avalonia.Input.TappedEventArgs e)
|
||||||
{
|
{
|
||||||
|
var source = e.Source as Border;
|
||||||
|
if (source?.Name == "HeaderBackground") return;
|
||||||
if (_config.UiItem.DoubleClick2Activate)
|
if (_config.UiItem.DoubleClick2Activate)
|
||||||
{
|
{
|
||||||
ViewModel?.SetDefaultServer();
|
ViewModel?.SetDefaultServer();
|
||||||
@@ -343,7 +353,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item2.Width = new DataGridLength(item.Width, DataGridLengthUnitType.Pixel); ;
|
item2.Width = new DataGridLength(item.Width, DataGridLengthUnitType.Pixel);
|
||||||
item2.DisplayIndex = displayIndex++;
|
item2.DisplayIndex = displayIndex++;
|
||||||
}
|
}
|
||||||
if (item.Name.StartsWith("to"))
|
if (item.Name.StartsWith("to"))
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ namespace v2rayN.Desktop.Views
|
|||||||
{
|
{
|
||||||
rulesItem.Protocol?.ForEach(it =>
|
rulesItem.Protocol?.ForEach(it =>
|
||||||
{
|
{
|
||||||
clbProtocol.SelectedItems.Add(it);
|
clbProtocol?.SelectedItems?.Add(it);
|
||||||
});
|
});
|
||||||
rulesItem.InboundTag?.ForEach(it =>
|
rulesItem.InboundTag?.ForEach(it =>
|
||||||
{
|
{
|
||||||
clbInboundTag.SelectedItems.Add(it);
|
clbInboundTag?.SelectedItems?.Add(it);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings2.SelectedItem).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings2.SelectedItem).DisposeWith(disposables);
|
||||||
});
|
});
|
||||||
|
|
||||||
spEnableTun.IsVisible = (Utils.IsWindows() || AppHandler.Instance.IsAdministrator);
|
//spEnableTun.IsVisible = (Utils.IsWindows() || AppHandler.Instance.IsAdministrator);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
@@ -94,6 +95,41 @@
|
|||||||
Classes="Margin8"
|
Classes="Margin8"
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
Watermark="{x:Static resx:ResUI.SubUrlTips}" />
|
Watermark="{x:Static resx:ResUI.SubUrlTips}" />
|
||||||
|
<Button
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="2"
|
||||||
|
Width="30"
|
||||||
|
Height="30"
|
||||||
|
Margin="10,0"
|
||||||
|
Theme="{DynamicResource BorderlessButton}">
|
||||||
|
<Button.Content>
|
||||||
|
<PathIcon
|
||||||
|
Width="20"
|
||||||
|
Height="20"
|
||||||
|
Data="{StaticResource building_more}"
|
||||||
|
Foreground="{DynamicResource ButtonDefaultTertiaryForeground}" />
|
||||||
|
</Button.Content>
|
||||||
|
<Button.Flyout>
|
||||||
|
<Flyout>
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Classes="Margin8"
|
||||||
|
Text="{x:Static resx:ResUI.LvMoreUrl}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtMoreUrl"
|
||||||
|
Width="400"
|
||||||
|
MinHeight="100"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Classes="TextArea Margin8"
|
||||||
|
MinLines="4"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Watermark="{x:Static resx:ResUI.SubUrlTips}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Flyout>
|
||||||
|
</Button.Flyout>
|
||||||
|
</Button>
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
@@ -114,7 +150,7 @@
|
|||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txtAutoUpdateInterval"
|
x:Name="txtAutoUpdateInterval"
|
||||||
Width="200"
|
Width="100"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Classes="Margin8"
|
Classes="Margin8"
|
||||||
DockPanel.Dock="Right"
|
DockPanel.Dock="Right"
|
||||||
@@ -233,21 +269,17 @@
|
|||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="12"
|
Grid.Row="12"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Grid.ColumnSpan="2"
|
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Classes="Margin8"
|
Classes="Margin8"
|
||||||
Text="{x:Static resx:ResUI.LvMoreUrl}" />
|
Text="{x:Static resx:ResUI.LvMemo}" />
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txtMoreUrl"
|
x:Name="txtMemo"
|
||||||
Grid.Row="13"
|
Grid.Row="12"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
MinHeight="100"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Classes="TextArea Margin8"
|
Classes="Margin8"
|
||||||
MinLines="4"
|
TextWrapping="Wrap" />
|
||||||
TextWrapping="Wrap"
|
|
||||||
Watermark="{x:Static resx:ResUI.SubUrlTips}" />
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
this.Bind(ViewModel, vm => vm.SelectedSource.PrevProfile, v => v.txtPrevProfile.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.PrevProfile, v => v.txtPrevProfile.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.NextProfile, v => v.txtNextProfile.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.NextProfile, v => v.txtNextProfile.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.PreSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.PreSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Memo, v => v.txtMemo.Text).DisposeWith(disposables);
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,16 +20,16 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Avalonia" Version="11.1.4" />
|
<PackageReference Include="Avalonia" Version="11.2.0" />
|
||||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.1.4" />
|
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.2.0" />
|
||||||
<PackageReference Include="Avalonia.Desktop" Version="11.1.4" />
|
<PackageReference Include="Avalonia.Desktop" Version="11.2.0" />
|
||||||
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.1.4" />
|
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.0" />
|
||||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.1.4" />
|
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.2.0" />
|
||||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.1.4" />
|
<PackageReference Include="Avalonia.ReactiveUI" Version="11.2.0" />
|
||||||
<PackageReference Include="DialogHost.Avalonia" Version="0.8.1" />
|
<PackageReference Include="DialogHost.Avalonia" Version="0.8.1" />
|
||||||
<PackageReference Include="MessageBox.Avalonia" Version="3.1.6.13" />
|
<PackageReference Include="MessageBox.Avalonia" Version="3.2.0" />
|
||||||
<PackageReference Include="Semi.Avalonia" Version="11.1.0.4" />
|
<PackageReference Include="Semi.Avalonia" Version="11.2.0" />
|
||||||
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.1.0.4" />
|
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.2.0" />
|
||||||
<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>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<Application
|
<Application
|
||||||
x:Class="v2rayN.App"
|
x:Class="v2rayN.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
ShutdownMode="OnExplicitShutdown"
|
ShutdownMode="OnExplicitShutdown"
|
||||||
StartupUri="Views/MainWindow.xaml">
|
StartupUri="Views/MainWindow.xaml">
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
@@ -211,6 +211,11 @@
|
|||||||
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
|
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
|
||||||
<Setter Property="TextOptions.TextRenderingMode" Value="ClearType" />
|
<Setter Property="TextOptions.TextRenderingMode" Value="ClearType" />
|
||||||
<Setter Property="TextOptions.TextHintingMode" Value="Fixed" />
|
<Setter Property="TextOptions.TextHintingMode" Value="Fixed" />
|
||||||
|
<Setter Property="TextElement.Foreground" Value="{DynamicResource MaterialDesignBody}" />
|
||||||
|
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}" />
|
||||||
|
<Setter Property="TextElement.FontFamily" Value="{x:Static conv:MaterialDesignFonts.MyFont}" />
|
||||||
|
<Setter Property="FontFamily" Value="{x:Static conv:MaterialDesignFonts.MyFont}" />
|
||||||
|
<Setter Property="ResizeMode" Value="NoResize" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style
|
<Style
|
||||||
x:Key="ViewGlobal"
|
x:Key="ViewGlobal"
|
||||||
@@ -219,6 +224,10 @@
|
|||||||
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
|
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
|
||||||
<Setter Property="TextOptions.TextRenderingMode" Value="ClearType" />
|
<Setter Property="TextOptions.TextRenderingMode" Value="ClearType" />
|
||||||
<Setter Property="TextOptions.TextHintingMode" Value="Fixed" />
|
<Setter Property="TextOptions.TextHintingMode" Value="Fixed" />
|
||||||
|
<Setter Property="TextElement.Foreground" Value="{DynamicResource MaterialDesignBody}" />
|
||||||
|
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}" />
|
||||||
|
<Setter Property="TextElement.FontFamily" Value="{x:Static conv:MaterialDesignFonts.MyFont}" />
|
||||||
|
<Setter Property="FontFamily" Value="{x:Static conv:MaterialDesignFonts.MyFont}" />
|
||||||
</Style>
|
</Style>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ namespace v2rayN
|
|||||||
{
|
{
|
||||||
var exePathKey = Utils.GetMd5(Utils.GetExePath());
|
var exePathKey = Utils.GetMd5(Utils.GetExePath());
|
||||||
|
|
||||||
var rebootas = (e.Args ?? new string[] { }).Any(t => t == Global.RebootAs);
|
var rebootas = (e.Args ?? Array.Empty<string>()).Any(t => t == Global.RebootAs);
|
||||||
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, exePathKey, out bool bCreatedNew);
|
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, exePathKey, out bool bCreatedNew);
|
||||||
if (!rebootas && !bCreatedNew)
|
if (!rebootas && !bCreatedNew)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using Microsoft.Win32.TaskScheduler;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Security.Principal;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
@@ -55,49 +51,6 @@ namespace v2rayN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Auto Start via TaskService
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="taskName"></param>
|
|
||||||
/// <param name="fileName"></param>
|
|
||||||
/// <param name="description"></param>
|
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
|
||||||
public static void AutoStart(string taskName, string fileName, string description)
|
|
||||||
{
|
|
||||||
if (Utils.IsNullOrEmpty(taskName))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
string TaskName = taskName;
|
|
||||||
var logonUser = WindowsIdentity.GetCurrent().Name;
|
|
||||||
string taskDescription = description;
|
|
||||||
string deamonFileName = fileName;
|
|
||||||
|
|
||||||
using var taskService = new TaskService();
|
|
||||||
var tasks = taskService.RootFolder.GetTasks(new Regex(TaskName));
|
|
||||||
foreach (var t in tasks)
|
|
||||||
{
|
|
||||||
taskService.RootFolder.DeleteTask(t.Name);
|
|
||||||
}
|
|
||||||
if (Utils.IsNullOrEmpty(fileName))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var task = taskService.NewTask();
|
|
||||||
task.RegistrationInfo.Description = taskDescription;
|
|
||||||
task.Settings.DisallowStartIfOnBatteries = false;
|
|
||||||
task.Settings.StopIfGoingOnBatteries = false;
|
|
||||||
task.Settings.RunOnlyIfIdle = false;
|
|
||||||
task.Settings.IdleSettings.StopOnIdleEnd = false;
|
|
||||||
task.Settings.ExecutionTimeLimit = TimeSpan.Zero;
|
|
||||||
task.Triggers.Add(new LogonTrigger { UserId = logonUser, Delay = TimeSpan.FromSeconds(10) });
|
|
||||||
task.Principal.RunLevel = TaskRunLevel.Highest;
|
|
||||||
task.Actions.Add(new ExecAction(deamonFileName.AppendQuotes(), null, Path.GetDirectoryName(deamonFileName)));
|
|
||||||
|
|
||||||
taskService.RootFolder.RegisterTaskDefinition(TaskName, task);
|
|
||||||
}
|
|
||||||
|
|
||||||
[DllImport("dwmapi.dll")]
|
[DllImport("dwmapi.dll")]
|
||||||
public static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attribute, ref int attributeValue, uint attributeSize);
|
public static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attribute, ref int attributeValue, uint attributeSize);
|
||||||
|
|
||||||
@@ -116,58 +69,6 @@ namespace v2rayN
|
|||||||
return value is int i && i > 0;
|
return value is int i && i > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string? RegReadValue(string path, string name, string def)
|
|
||||||
{
|
|
||||||
RegistryKey? regKey = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
regKey = Registry.CurrentUser.OpenSubKey(path, false);
|
|
||||||
string? value = regKey?.GetValue(name) as string;
|
|
||||||
if (Utils.IsNullOrEmpty(value))
|
|
||||||
{
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
regKey?.Close();
|
|
||||||
}
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RegWriteValue(string path, string name, object value)
|
|
||||||
{
|
|
||||||
RegistryKey? regKey = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
regKey = Registry.CurrentUser.CreateSubKey(path);
|
|
||||||
if (Utils.IsNullOrEmpty(value.ToString()))
|
|
||||||
{
|
|
||||||
regKey?.DeleteValue(name, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
regKey?.SetValue(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
regKey?.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RemoveTunDevice()
|
public static void RemoveTunDevice()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -209,42 +110,6 @@ namespace v2rayN
|
|||||||
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref attribute, attributeSize);
|
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref attribute, attributeSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开机自动启动
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="run"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static void SetAutoRun(string AutoRunRegPath, string AutoRunName, bool run)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var autoRunName = $"{AutoRunName}_{Utils.GetMd5(Utils.StartupPath())}";
|
|
||||||
//delete first
|
|
||||||
RegWriteValue(AutoRunRegPath, autoRunName, "");
|
|
||||||
if (Utils.IsAdministrator())
|
|
||||||
{
|
|
||||||
AutoStart(autoRunName, "", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (run)
|
|
||||||
{
|
|
||||||
string exePath = Utils.GetExePath();
|
|
||||||
if (Utils.IsAdministrator())
|
|
||||||
{
|
|
||||||
AutoStart(autoRunName, exePath, "");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RegWriteValue(AutoRunRegPath, autoRunName, exePath.AppendQuotes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(ex.Message, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Windows API
|
#region Windows API
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
x:Class="v2rayN.Views.AddServer2Window"
|
x:Class="v2rayN.Views.AddServer2Window"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@@ -13,13 +12,8 @@
|
|||||||
Width="700"
|
Width="700"
|
||||||
Height="500"
|
Height="500"
|
||||||
x:TypeArguments="vms:AddServer2ViewModel"
|
x:TypeArguments="vms:AddServer2ViewModel"
|
||||||
Background="{DynamicResource MaterialDesignPaper}"
|
|
||||||
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
ResizeMode="NoResize"
|
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
Style="{StaticResource WindowGlobal}"
|
Style="{StaticResource WindowGlobal}"
|
||||||
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
x:Class="v2rayN.Views.AddServerWindow"
|
x:Class="v2rayN.Views.AddServerWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@@ -13,15 +12,18 @@
|
|||||||
Width="900"
|
Width="900"
|
||||||
Height="700"
|
Height="700"
|
||||||
x:TypeArguments="vms:AddServerViewModel"
|
x:TypeArguments="vms:AddServerViewModel"
|
||||||
Background="{DynamicResource MaterialDesignPaper}"
|
|
||||||
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
ResizeMode="CanResize"
|
ResizeMode="CanResize"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
Style="{StaticResource WindowGlobal}"
|
Style="{StaticResource WindowGlobal}"
|
||||||
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
<Window.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Popupbox.xaml" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</Window.Resources>
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
@@ -133,7 +135,7 @@
|
|||||||
x:Name="txtPort"
|
x:Name="txtPort"
|
||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
@@ -193,7 +195,7 @@
|
|||||||
x:Name="txtAlterId"
|
x:Name="txtAlterId"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
@@ -518,7 +520,7 @@
|
|||||||
x:Name="cmbHeaderType8"
|
x:Name="cmbHeaderType8"
|
||||||
Grid.Row="3"
|
Grid.Row="3"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Style="{StaticResource DefComboBox}" />
|
Style="{StaticResource DefComboBox}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -611,7 +613,7 @@
|
|||||||
x:Name="txtShortId9"
|
x:Name="txtShortId9"
|
||||||
Grid.Row="5"
|
Grid.Row="5"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
@@ -658,7 +660,7 @@
|
|||||||
x:Name="cmbNetwork"
|
x:Name="cmbNetwork"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Style="{StaticResource DefComboBox}" />
|
Style="{StaticResource DefComboBox}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -677,13 +679,40 @@
|
|||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbHeaderType}" />
|
Text="{x:Static resx:ResUI.TbHeaderType}" />
|
||||||
<ComboBox
|
<StackPanel
|
||||||
x:Name="cmbHeaderType"
|
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
VerticalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbHeaderType"
|
||||||
|
Width="200"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Style="{StaticResource DefComboBox}" />
|
Style="{StaticResource DefComboBox}" />
|
||||||
|
|
||||||
|
<materialDesign:PopupBox
|
||||||
|
x:Name="popExtra"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
StaysOpen="True"
|
||||||
|
Style="{StaticResource MaterialDesignToolForegroundPopupBox}">
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TransportExtraTip}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtExtra"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
AcceptsReturn="True"
|
||||||
|
MinLines="6"
|
||||||
|
Style="{StaticResource MyOutlinedTextBox}"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</StackPanel>
|
||||||
|
</materialDesign:PopupBox>
|
||||||
|
</StackPanel>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
x:Name="tipHeaderType"
|
x:Name="tipHeaderType"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
@@ -769,7 +798,7 @@
|
|||||||
x:Name="cmbStreamSecurity"
|
x:Name="cmbStreamSecurity"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Style="{StaticResource DefComboBox}" />
|
Style="{StaticResource DefComboBox}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -847,7 +876,7 @@
|
|||||||
x:Name="cmbAllowInsecure"
|
x:Name="cmbAllowInsecure"
|
||||||
Grid.Row="4"
|
Grid.Row="4"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="100"
|
Width="200"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Style="{StaticResource DefComboBox}" />
|
Style="{StaticResource DefComboBox}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ namespace v2rayN.Views
|
|||||||
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Extra, v => v.txtExtra.Text).DisposeWith(disposables);
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.StreamSecurity, v => v.cmbStreamSecurity.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.StreamSecurity, v => v.cmbStreamSecurity.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Sni, v => v.txtSNI.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Sni, v => v.txtSNI.Text).DisposeWith(disposables);
|
||||||
@@ -294,6 +295,13 @@ namespace v2rayN.Views
|
|||||||
cmbHeaderType.Items.Add(it);
|
cmbHeaderType.Items.Add(it);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (network is nameof(ETransport.splithttp) or nameof(ETransport.xhttp))
|
||||||
|
{
|
||||||
|
Global.XhttpMode.ForEach(it =>
|
||||||
|
{
|
||||||
|
cmbHeaderType.Items.Add(it);
|
||||||
|
});
|
||||||
|
}
|
||||||
else if (network == nameof(ETransport.grpc))
|
else if (network == nameof(ETransport.grpc))
|
||||||
{
|
{
|
||||||
cmbHeaderType.Items.Add(Global.GrpcGunMode);
|
cmbHeaderType.Items.Add(Global.GrpcGunMode);
|
||||||
@@ -314,6 +322,7 @@ namespace v2rayN.Views
|
|||||||
network = Global.DefaultNetwork;
|
network = Global.DefaultNetwork;
|
||||||
}
|
}
|
||||||
labHeaderType.Visibility = Visibility.Visible;
|
labHeaderType.Visibility = Visibility.Visible;
|
||||||
|
popExtra.Visibility = Visibility.Hidden;
|
||||||
tipRequestHost.Text =
|
tipRequestHost.Text =
|
||||||
tipPath.Text =
|
tipPath.Text =
|
||||||
tipHeaderType.Text = string.Empty;
|
tipHeaderType.Text = string.Empty;
|
||||||
@@ -332,11 +341,19 @@ namespace v2rayN.Views
|
|||||||
|
|
||||||
case nameof(ETransport.ws):
|
case nameof(ETransport.ws):
|
||||||
case nameof(ETransport.httpupgrade):
|
case nameof(ETransport.httpupgrade):
|
||||||
case nameof(ETransport.splithttp):
|
|
||||||
tipRequestHost.Text = ResUI.TransportRequestHostTip2;
|
tipRequestHost.Text = ResUI.TransportRequestHostTip2;
|
||||||
tipPath.Text = ResUI.TransportPathTip1;
|
tipPath.Text = ResUI.TransportPathTip1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nameof(ETransport.splithttp):
|
||||||
|
case nameof(ETransport.xhttp):
|
||||||
|
tipRequestHost.Text = ResUI.TransportRequestHostTip2;
|
||||||
|
tipPath.Text = ResUI.TransportPathTip1;
|
||||||
|
tipHeaderType.Text = ResUI.TransportHeaderTypeTip5;
|
||||||
|
labHeaderType.Visibility = Visibility.Hidden;
|
||||||
|
popExtra.Visibility = Visibility.Visible;
|
||||||
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.h2):
|
case nameof(ETransport.h2):
|
||||||
tipRequestHost.Text = ResUI.TransportRequestHostTip3;
|
tipRequestHost.Text = ResUI.TransportRequestHostTip3;
|
||||||
tipPath.Text = ResUI.TransportPathTip2;
|
tipPath.Text = ResUI.TransportPathTip2;
|
||||||
|
|||||||
@@ -119,7 +119,6 @@
|
|||||||
Text="{x:Static resx:ResUI.menuRemoteBackupAndRestore}" />
|
Text="{x:Static resx:ResUI.menuRemoteBackupAndRestore}" />
|
||||||
|
|
||||||
<materialDesign:PopupBox
|
<materialDesign:PopupBox
|
||||||
Padding="8,0"
|
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
StaysOpen="True"
|
StaysOpen="True"
|
||||||
Style="{StaticResource MaterialDesignToolForegroundPopupBox}">
|
Style="{StaticResource MaterialDesignToolForegroundPopupBox}">
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace v2rayN.Views
|
|||||||
|
|
||||||
this.WhenActivated(disposables =>
|
this.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
this.OneWayBind(ViewModel, vm => vm.CheckUpdateItems, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables);
|
this.OneWayBind(ViewModel, vm => vm.CheckUpdateModels, v => v.lstCheckUpdates.ItemsSource).DisposeWith(disposables);
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables);
|
||||||
@@ -30,7 +30,7 @@ namespace v2rayN.Views
|
|||||||
if (obj is null) return false;
|
if (obj is null) return false;
|
||||||
Application.Current?.Dispatcher.Invoke((() =>
|
Application.Current?.Dispatcher.Invoke((() =>
|
||||||
{
|
{
|
||||||
ViewModel?.UpdateViewResult((CheckUpdateItem)obj);
|
ViewModel?.UpdateViewResult((CheckUpdateModel)obj);
|
||||||
}), DispatcherPriority.Normal);
|
}), DispatcherPriority.Normal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<reactiveui:ReactiveUserControl
|
<reactiveui:ReactiveUserControl
|
||||||
x:Class="v2rayN.Views.ClashConnectionsView"
|
x:Class="v2rayN.Views.ClashConnectionsView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
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"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<reactiveui:ReactiveUserControl
|
<reactiveui:ReactiveUserControl
|
||||||
x:Class="v2rayN.Views.ClashProxiesView"
|
x:Class="v2rayN.Views.ClashProxiesView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:converters="clr-namespace:v2rayN.Converters"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
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"
|
||||||
xmlns:converters="clr-namespace:v2rayN.Converters"
|
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
x:TypeArguments="vms:ClashProxiesViewModel"
|
x:TypeArguments="vms:ClashProxiesViewModel"
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
x:Class="v2rayN.Views.DNSSettingWindow"
|
x:Class="v2rayN.Views.DNSSettingWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@@ -13,13 +12,8 @@
|
|||||||
Width="1000"
|
Width="1000"
|
||||||
Height="700"
|
Height="700"
|
||||||
x:TypeArguments="vms:DNSSettingViewModel"
|
x:TypeArguments="vms:DNSSettingViewModel"
|
||||||
Background="{DynamicResource MaterialDesignPaper}"
|
|
||||||
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
ResizeMode="NoResize"
|
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
Style="{StaticResource WindowGlobal}"
|
Style="{StaticResource WindowGlobal}"
|
||||||
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
x:Class="v2rayN.Views.GlobalHotkeySettingWindow"
|
x:Class="v2rayN.Views.GlobalHotkeySettingWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@@ -13,14 +12,9 @@
|
|||||||
Width="700"
|
Width="700"
|
||||||
Height="500"
|
Height="500"
|
||||||
x:TypeArguments="vms:SubEditViewModel"
|
x:TypeArguments="vms:SubEditViewModel"
|
||||||
Background="{DynamicResource MaterialDesignPaper}"
|
|
||||||
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
KeyDown="GlobalHotkeySettingWindow_KeyDown"
|
KeyDown="GlobalHotkeySettingWindow_KeyDown"
|
||||||
ResizeMode="NoResize"
|
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
Style="{StaticResource WindowGlobal}"
|
Style="{StaticResource WindowGlobal}"
|
||||||
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
x:Class="v2rayN.Views.MainWindow"
|
x:Class="v2rayN.Views.MainWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@@ -15,12 +14,9 @@
|
|||||||
Height="700"
|
Height="700"
|
||||||
MinWidth="900"
|
MinWidth="900"
|
||||||
x:TypeArguments="vms:MainWindowViewModel"
|
x:TypeArguments="vms:MainWindowViewModel"
|
||||||
Background="{DynamicResource MaterialDesignPaper}"
|
ResizeMode="CanResizeWithGrip"
|
||||||
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
ShowInTaskbar="True"
|
ShowInTaskbar="True"
|
||||||
Style="{StaticResource WindowGlobal}"
|
Style="{StaticResource WindowGlobal}"
|
||||||
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
@@ -281,7 +277,7 @@
|
|||||||
</Menu>
|
</Menu>
|
||||||
|
|
||||||
<materialDesign:PopupBox
|
<materialDesign:PopupBox
|
||||||
Padding="8,0"
|
Padding="-2"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
StaysOpen="True"
|
StaysOpen="True"
|
||||||
Style="{StaticResource MaterialDesignToolForegroundPopupBox}">
|
Style="{StaticResource MaterialDesignToolForegroundPopupBox}">
|
||||||
|
|||||||
@@ -270,11 +270,11 @@ namespace v2rayN.Views
|
|||||||
StorageUI();
|
StorageUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Current_SessionEnding(object sender, SessionEndingCancelEventArgs e)
|
private async void Current_SessionEnding(object sender, SessionEndingCancelEventArgs e)
|
||||||
{
|
{
|
||||||
Logging.SaveLog("Current_SessionEnding");
|
Logging.SaveLog("Current_SessionEnding");
|
||||||
StorageUI();
|
StorageUI();
|
||||||
ViewModel?.MyAppExitAsync(true);
|
await ViewModel?.MyAppExitAsync(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
|
private void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||||
@@ -367,17 +367,17 @@ namespace v2rayN.Views
|
|||||||
var bl = blShow ?? !_config.UiItem.ShowInTaskbar;
|
var bl = blShow ?? !_config.UiItem.ShowInTaskbar;
|
||||||
if (bl)
|
if (bl)
|
||||||
{
|
{
|
||||||
Application.Current.MainWindow.Show();
|
this?.Show();
|
||||||
if (Application.Current.MainWindow.WindowState == WindowState.Minimized)
|
if (this?.WindowState == WindowState.Minimized)
|
||||||
{
|
{
|
||||||
Application.Current.MainWindow.WindowState = WindowState.Normal;
|
this.WindowState = WindowState.Normal;
|
||||||
}
|
}
|
||||||
Application.Current.MainWindow.Activate();
|
this?.Activate();
|
||||||
Application.Current.MainWindow.Focus();
|
this?.Focus();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Application.Current.MainWindow.Hide();
|
this?.Hide();
|
||||||
}
|
}
|
||||||
_config.UiItem.ShowInTaskbar = bl;
|
_config.UiItem.ShowInTaskbar = bl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,8 @@
|
|||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<TextBox
|
<TextBox
|
||||||
Name="txtMsg"
|
Name="txtMsg"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
AcceptsReturn="True"
|
||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
FontSize="{DynamicResource StdFontSize-1}"
|
FontSize="{DynamicResource StdFontSize-1}"
|
||||||
HorizontalScrollBarVisibility="Auto"
|
HorizontalScrollBarVisibility="Auto"
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
x:Class="v2rayN.Views.OptionSettingWindow"
|
x:Class="v2rayN.Views.OptionSettingWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@@ -13,13 +12,8 @@
|
|||||||
Width="1000"
|
Width="1000"
|
||||||
Height="700"
|
Height="700"
|
||||||
x:TypeArguments="vms:OptionSettingViewModel"
|
x:TypeArguments="vms:OptionSettingViewModel"
|
||||||
Background="{DynamicResource MaterialDesignPaper}"
|
|
||||||
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
ResizeMode="NoResize"
|
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
Style="{StaticResource WindowGlobal}"
|
Style="{StaticResource WindowGlobal}"
|
||||||
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
@@ -661,20 +655,6 @@
|
|||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Grid.Row="9"
|
|
||||||
Grid.Column="0"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
|
||||||
Text="{x:Static resx:ResUI.TbSettingsEnableCheckPreReleaseUpdate}" />
|
|
||||||
<ToggleButton
|
|
||||||
x:Name="togEnableCheckPreReleaseUpdate"
|
|
||||||
Grid.Row="9"
|
|
||||||
Grid.Column="1"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
HorizontalAlignment="Left" />
|
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="10"
|
Grid.Row="10"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ namespace v2rayN.Views
|
|||||||
|
|
||||||
this.Owner = Application.Current.MainWindow;
|
this.Owner = Application.Current.MainWindow;
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
var lstFonts = GetFonts(Utils.GetFontsPath());
|
|
||||||
|
|
||||||
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
|
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
@@ -102,9 +101,6 @@ namespace v2rayN.Views
|
|||||||
cmbMainGirdOrientation.Items.Add(it.ToString());
|
cmbMainGirdOrientation.Items.Add(it.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); });
|
|
||||||
cmbcurrentFontFamily.Items.Add(string.Empty);
|
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
this.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
this.Bind(ViewModel, vm => vm.localPort, v => v.txtlocalPort.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.localPort, v => v.txtlocalPort.Text).DisposeWith(disposables);
|
||||||
@@ -145,7 +141,6 @@ namespace v2rayN.Views
|
|||||||
this.Bind(ViewModel, vm => vm.EnableUpdateSubOnlyRemarksExist, v => v.togEnableUpdateSubOnlyRemarksExist.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableUpdateSubOnlyRemarksExist, v => v.togEnableUpdateSubOnlyRemarksExist.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.EnableDragDropSort, v => v.togEnableDragDropSort.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.EnableDragDropSort, v => v.togEnableDragDropSort.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.DoubleClick2Activate, v => v.togDoubleClick2Activate.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.DoubleClick2Activate, v => v.togDoubleClick2Activate.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.AutoUpdateInterval, v => v.txtautoUpdateInterval.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.AutoUpdateInterval, v => v.txtautoUpdateInterval.Text).DisposeWith(disposables);
|
||||||
@@ -188,14 +183,24 @@ namespace v2rayN.Views
|
|||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case EViewAction.CloseWindow:
|
case EViewAction.CloseWindow:
|
||||||
WindowsUtils.SetAutoRun(Global.AutoRunRegPath, Global.AutoRunName, togAutoRun.IsChecked ?? false);
|
|
||||||
this.DialogResult = true;
|
this.DialogResult = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EViewAction.InitSettingFont:
|
||||||
|
await InitSettingFont();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return await Task.FromResult(true);
|
return await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<string> GetFonts(string path)
|
private async Task InitSettingFont()
|
||||||
|
{
|
||||||
|
var lstFonts = await GetFonts(Utils.GetFontsPath());
|
||||||
|
lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); });
|
||||||
|
cmbcurrentFontFamily.Items.Add(string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<List<string>> GetFonts(string path)
|
||||||
{
|
{
|
||||||
var lstFonts = new List<string>();
|
var lstFonts = new List<string>();
|
||||||
try
|
try
|
||||||
@@ -241,7 +246,7 @@ namespace v2rayN.Views
|
|||||||
{
|
{
|
||||||
Logging.SaveLog("fill fonts error", ex);
|
Logging.SaveLog("fill fonts error", ex);
|
||||||
}
|
}
|
||||||
return lstFonts;
|
return lstFonts.OrderBy(t => t).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClbdestOverride_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
private void ClbdestOverride_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
||||||
|
|||||||
@@ -1,25 +1,19 @@
|
|||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.RoutingRuleDetailsWindow"
|
x:Class="v2rayN.Views.RoutingRuleDetailsWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
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"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
|
||||||
Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}"
|
Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}"
|
||||||
Width="900"
|
Width="900"
|
||||||
Height="700"
|
Height="700"
|
||||||
x:TypeArguments="vms:RoutingRuleDetailsViewModel"
|
x:TypeArguments="vms:RoutingRuleDetailsViewModel"
|
||||||
Background="{DynamicResource MaterialDesignPaper}"
|
|
||||||
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
ResizeMode="NoResize"
|
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
Style="{StaticResource WindowGlobal}"
|
Style="{StaticResource WindowGlobal}"
|
||||||
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
|
|||||||
@@ -1,25 +1,19 @@
|
|||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.RoutingRuleSettingWindow"
|
x:Class="v2rayN.Views.RoutingRuleSettingWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
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"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
|
||||||
Title="{x:Static resx:ResUI.menuRoutingRuleSetting}"
|
Title="{x:Static resx:ResUI.menuRoutingRuleSetting}"
|
||||||
Width="960"
|
Width="960"
|
||||||
Height="700"
|
Height="700"
|
||||||
x:TypeArguments="vms:RoutingRuleSettingViewModel"
|
x:TypeArguments="vms:RoutingRuleSettingViewModel"
|
||||||
Background="{DynamicResource MaterialDesignPaper}"
|
|
||||||
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
ResizeMode="NoResize"
|
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
Style="{StaticResource WindowGlobal}"
|
Style="{StaticResource WindowGlobal}"
|
||||||
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
x:Class="v2rayN.Views.RoutingSettingWindow"
|
x:Class="v2rayN.Views.RoutingSettingWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@@ -13,13 +12,8 @@
|
|||||||
Width="990"
|
Width="990"
|
||||||
Height="700"
|
Height="700"
|
||||||
x:TypeArguments="vms:RoutingSettingViewModel"
|
x:TypeArguments="vms:RoutingSettingViewModel"
|
||||||
Background="{DynamicResource MaterialDesignPaper}"
|
|
||||||
FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
ResizeMode="NoResize"
|
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
Style="{StaticResource WindowGlobal}"
|
Style="{StaticResource WindowGlobal}"
|
||||||
TextElement.FontFamily="{x:Static conv:MaterialDesignFonts.MyFont}"
|
|
||||||
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
|
|||||||
@@ -100,11 +100,11 @@ namespace v2rayN.Views
|
|||||||
return await Task.FromResult(true);
|
return await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void menuExit_Click(object sender, RoutedEventArgs e)
|
private async void menuExit_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
tbNotify.Dispose();
|
tbNotify.Dispose();
|
||||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||||
if (service != null) service.MyAppExitAsync(false);
|
if (service != null) await service.MyAppExitAsync(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void txtRunningInfoDisplay_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
private void txtRunningInfoDisplay_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user