Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
9738f90970 | ||
|
|
6ed0741339 | ||
|
|
e6b1e22245 | ||
|
|
6b922be0c6 | ||
|
|
6e35a260e8 | ||
|
|
1106fd8cf1 | ||
|
|
fb92b90d5c | ||
|
|
5effbee50b | ||
|
|
9bc50a9f34 | ||
|
|
2a5a339c27 | ||
|
|
78d182fff3 | ||
|
|
0efb0b5e3e | ||
|
|
a2e8755730 | ||
|
|
06ddedbc4c | ||
|
|
fa148cdf42 |
@@ -1,6 +1,5 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace AmazTool
|
namespace AmazTool
|
||||||
@@ -12,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))
|
||||||
{
|
{
|
||||||
@@ -20,17 +19,14 @@ namespace AmazTool
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Try to end the process(尝试结束进程).");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Process[] existing = Process.GetProcessesByName(V2rayN());
|
var existing = Process.GetProcessesByName(V2rayN);
|
||||||
foreach (Process p in existing)
|
foreach (var pp in existing)
|
||||||
{
|
{
|
||||||
var path = p.MainModule?.FileName ?? "";
|
pp?.Kill();
|
||||||
if (path.StartsWith(GetPath(V2rayN())))
|
pp?.WaitForExit(1000);
|
||||||
{
|
|
||||||
p.Kill();
|
|
||||||
p.WaitForExit(100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -40,6 +36,7 @@ namespace AmazTool
|
|||||||
"Close it manually, or the upgrade may fail.(请手动关闭正在运行的v2rayN,否则可能升级失败。\n\n" + ex.StackTrace);
|
"Close it manually, or the upgrade may fail.(请手动关闭正在运行的v2rayN,否则可能升级失败。\n\n" + ex.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Start extracting files(开始解压文件).");
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -57,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]);
|
||||||
@@ -81,22 +80,22 @@ 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.\n" +
|
Console.WriteLine("Upgrade Failed(升级失败)." + sb.ToString());
|
||||||
"(升级失败)." + sb.ToString());
|
//return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Start v2rayN, please wait...(正在重启,请等待)");
|
Console.WriteLine("Start v2rayN, please wait...(正在重启,请等待)");
|
||||||
Thread.Sleep(3000);
|
Thread.Sleep(9000);
|
||||||
Process process = new()
|
Process process = new()
|
||||||
{
|
{
|
||||||
StartInfo = new()
|
StartInfo = new()
|
||||||
{
|
{
|
||||||
FileName = V2rayN(),
|
UseShellExecute = true,
|
||||||
|
FileName = V2rayN,
|
||||||
WorkingDirectory = StartupPath()
|
WorkingDirectory = StartupPath()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -123,19 +122,6 @@ namespace AmazTool
|
|||||||
return Path.Combine(startupPath, fileName);
|
return Path.Combine(startupPath, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string V2rayN()
|
private static string V2rayN => "v2rayN";
|
||||||
{
|
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
||||||
{
|
|
||||||
if (File.Exists(GetPath("v2rayN.exe")))
|
|
||||||
return "v2rayN";
|
|
||||||
else
|
|
||||||
return "v2rayN.Desktop";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return "v2rayN.Desktop";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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,14 +752,16 @@ namespace ServiceLib.Common
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(tempPath);
|
Directory.CreateDirectory(tempPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coreType != null)
|
if (coreType != null)
|
||||||
{
|
{
|
||||||
tempPath = Path.Combine(tempPath, coreType.ToString());
|
tempPath = Path.Combine(tempPath, coreType.ToLower().ToString());
|
||||||
if (!Directory.Exists(tempPath))
|
if (!Directory.Exists(tempPath))
|
||||||
{
|
{
|
||||||
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
ClearMsg,
|
ClearMsg,
|
||||||
SendMsgView,
|
SendMsgView,
|
||||||
SendSnackMsg,
|
SendSnackMsg,
|
||||||
RefreshProfiles
|
RefreshProfiles,
|
||||||
|
StopSpeedtest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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();
|
||||||
@@ -159,7 +159,7 @@
|
|||||||
await ConfigHandler.SetDefaultServer(_config, lstModel);
|
await ConfigHandler.SetDefaultServer(_config, lstModel);
|
||||||
|
|
||||||
var lstServerStat = (_config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
|
var lstServerStat = (_config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
|
||||||
var lstProfileExs = ProfileExHandler.Instance.ProfileExs;
|
var lstProfileExs = await ProfileExHandler.Instance.GetProfileExs();
|
||||||
lstModel = (from t in lstModel
|
lstModel = (from t in lstModel
|
||||||
join t2 in lstServerStat on t.IndexId equals t2.IndexId into t2b
|
join t2 in lstServerStat on t.IndexId equals t2.IndexId into t2b
|
||||||
from t22 in t2b.DefaultIfEmpty()
|
from t22 in t2b.DefaultIfEmpty()
|
||||||
|
|||||||
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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ namespace ServiceLib.Handler
|
|||||||
return new Tuple<ClashProxies, ClashProviders>(clashProxies, clashProviders);
|
return new Tuple<ClashProxies, ClashProviders>(clashProxies, clashProviders);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.Delay(5000);
|
await Task.Delay(2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -465,7 +466,7 @@ namespace ServiceLib.Handler
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EMove.Position:
|
case EMove.Position:
|
||||||
sort = pos * 10 + 1;
|
sort = (pos * 10) + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -746,7 +747,7 @@ namespace ServiceLib.Handler
|
|||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
var lstProfileExs = ProfileExHandler.Instance.ProfileExs;
|
var lstProfileExs = await ProfileExHandler.Instance.GetProfileExs();
|
||||||
var lstProfile = (from t in lstModel
|
var lstProfile = (from t in lstModel
|
||||||
join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b
|
join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b
|
||||||
from t33 in t3b.DefaultIfEmpty()
|
from t33 in t3b.DefaultIfEmpty()
|
||||||
@@ -1034,14 +1035,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 +1050,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 +1074,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 +1114,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 +1198,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 +1212,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 +1251,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;
|
||||||
@@ -1340,7 +1326,9 @@ namespace ServiceLib.Handler
|
|||||||
//Do not allow http protocol
|
//Do not allow http protocol
|
||||||
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
|
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
|
||||||
{
|
{
|
||||||
return -1;
|
//TODO Temporary reminder to be removed later
|
||||||
|
NoticeHandler.Instance.Enqueue(ResUI.InsecureUrlProtocol);
|
||||||
|
//return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryVars = Utils.ParseQueryString(uri.Query);
|
var queryVars = Utils.ParseQueryString(uri.Query);
|
||||||
@@ -1371,6 +1359,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))
|
||||||
|
|||||||
@@ -12,18 +12,12 @@
|
|||||||
|
|
||||||
if (node.ConfigType == EConfigType.Custom)
|
if (node.ConfigType == EConfigType.Custom)
|
||||||
{
|
{
|
||||||
if (node.CoreType is ECoreType.mihomo)
|
result = node.CoreType switch
|
||||||
{
|
{
|
||||||
result = await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName);
|
ECoreType.mihomo => await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName),
|
||||||
}
|
ECoreType.sing_box => await new CoreConfigSingboxService(config).GenerateClientCustomConfig(node, fileName),
|
||||||
if (node.CoreType is ECoreType.sing_box)
|
_ => await GenerateClientCustomConfig(node, fileName)
|
||||||
{
|
};
|
||||||
result = await new CoreConfigSingboxService(config).GenerateClientCustomConfig(node, fileName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = await GenerateClientCustomConfig(node, fileName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (AppHandler.Instance.GetCoreType(node, node.ConfigType) == ECoreType.sing_box)
|
else if (AppHandler.Instance.GetCoreType(node, node.ConfigType) == ECoreType.sing_box)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,13 +15,38 @@ namespace ServiceLib.Handler
|
|||||||
private Process? _processPre;
|
private Process? _processPre;
|
||||||
private Action<bool, string>? _updateFunc;
|
private Action<bool, string>? _updateFunc;
|
||||||
|
|
||||||
public void Init(Config config, Action<bool, string> updateFunc)
|
public async Task Init(Config config, Action<bool, string> updateFunc)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
_updateFunc = updateFunc;
|
_updateFunc = updateFunc;
|
||||||
|
|
||||||
Environment.SetEnvironmentVariable("v2ray.location.asset", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
Environment.SetEnvironmentVariable("V2RAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
||||||
Environment.SetEnvironmentVariable("xray.location.asset", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
Environment.SetEnvironmentVariable("XRAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
||||||
|
|
||||||
|
if (Utils.IsLinux())
|
||||||
|
{
|
||||||
|
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
|
||||||
|
foreach (var it in coreInfo)
|
||||||
|
{
|
||||||
|
if (it.CoreType == ECoreType.v2rayN)
|
||||||
|
{
|
||||||
|
if (Utils.UpgradeAppExists(out var fileName))
|
||||||
|
{
|
||||||
|
await Utils.SetLinuxChmod(fileName);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var name in it.CoreExes)
|
||||||
|
{
|
||||||
|
var exe = Utils.GetBinPath(Utils.GetExeName(name), it.CoreType.ToString());
|
||||||
|
if (File.Exists(exe))
|
||||||
|
{
|
||||||
|
await Utils.SetLinuxChmod(exe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task LoadCore(ProfileItem? node)
|
public async Task LoadCore(ProfileItem? node)
|
||||||
@@ -83,13 +108,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)
|
||||||
@@ -97,31 +120,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)
|
||||||
@@ -148,10 +146,9 @@ namespace ServiceLib.Handler
|
|||||||
private string CoreFindExe(CoreInfo coreInfo)
|
private string CoreFindExe(CoreInfo coreInfo)
|
||||||
{
|
{
|
||||||
string fileName = string.Empty;
|
string 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;
|
||||||
|
|||||||
@@ -9,27 +9,31 @@ namespace ServiceLib.Handler
|
|||||||
private static readonly Lazy<ProfileExHandler> _instance = new(() => new());
|
private static readonly Lazy<ProfileExHandler> _instance = new(() => new());
|
||||||
private ConcurrentBag<ProfileExItem> _lstProfileEx = [];
|
private ConcurrentBag<ProfileExItem> _lstProfileEx = [];
|
||||||
private Queue<string> _queIndexIds = new();
|
private Queue<string> _queIndexIds = new();
|
||||||
public ConcurrentBag<ProfileExItem> ProfileExs => _lstProfileEx;
|
|
||||||
public static ProfileExHandler Instance => _instance.Value;
|
public static ProfileExHandler Instance => _instance.Value;
|
||||||
|
|
||||||
public ProfileExHandler()
|
public ProfileExHandler()
|
||||||
{
|
{
|
||||||
Init();
|
//Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Init()
|
public async Task Init()
|
||||||
{
|
{
|
||||||
await InitData();
|
await InitData();
|
||||||
await Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
await SaveQueueIndexIds();
|
|
||||||
await Task.Delay(1000 * 600);
|
await Task.Delay(1000 * 600);
|
||||||
|
await SaveQueueIndexIds();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ConcurrentBag<ProfileExItem>> GetProfileExs()
|
||||||
|
{
|
||||||
|
return _lstProfileEx;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task InitData()
|
private async Task InitData()
|
||||||
{
|
{
|
||||||
await SQLiteHelper.Instance.ExecuteAsync($"delete from ProfileExItem where indexId not in ( select indexId from ProfileItem )");
|
await SQLiteHelper.Instance.ExecuteAsync($"delete from ProfileExItem where indexId not in ( select indexId from ProfileItem )");
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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]
|
||||||
@@ -243,4 +243,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; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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,4 +1,4 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace ServiceLib.Models
|
namespace ServiceLib.Models
|
||||||
{
|
{
|
||||||
@@ -50,7 +50,7 @@ namespace ServiceLib.Models
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class Stats4Ray
|
public class Stats4Ray
|
||||||
{ };
|
{ }
|
||||||
|
|
||||||
public class API4Ray
|
public class API4Ray
|
||||||
{
|
{
|
||||||
|
|||||||
45
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
45
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
@@ -294,6 +294,24 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Please do not use the insecure HTTP protocol subscription address 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string InsecureUrlProtocol {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("InsecureUrlProtocol", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Invalid address (Url) 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string InvalidUrlTip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("InvalidUrlTip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 {0} {1} already up to date. 的本地化字符串。
|
/// 查找类似 {0} {1} already up to date. 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -429,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>
|
||||||
@@ -852,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>
|
||||||
@@ -2842,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>
|
||||||
|
|||||||
@@ -1354,4 +1354,19 @@
|
|||||||
<data name="menuAddServerViaImage" xml:space="preserve">
|
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||||
<value>Scan QR code in the image</value>
|
<value>Scan QR code in the image</value>
|
||||||
</data>
|
</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>
|
||||||
</root>
|
</root>
|
||||||
@@ -1351,4 +1351,19 @@
|
|||||||
<data name="menuAddServerViaImage" xml:space="preserve">
|
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||||
<value>扫描图片中的二维码</value>
|
<value>扫描图片中的二维码</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="InvalidUrlTip" xml:space="preserve">
|
||||||
|
<value>地址(Url)无效</value>
|
||||||
|
</data>
|
||||||
|
<data name="InsecureUrlProtocol" xml:space="preserve">
|
||||||
|
<value>请不要使用不安全的HTTP协议订阅地址</value>
|
||||||
|
</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>
|
||||||
</root>
|
</root>
|
||||||
@@ -1231,4 +1231,19 @@
|
|||||||
<data name="menuAddServerViaImage" xml:space="preserve">
|
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||||
<value>掃描圖片中的二維碼</value>
|
<value>掃描圖片中的二維碼</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="InvalidUrlTip" xml:space="preserve">
|
||||||
|
<value>地址(Url)無效</value>
|
||||||
|
</data>
|
||||||
|
<data name="InsecureUrlProtocol" xml:space="preserve">
|
||||||
|
<value>請不要使用不安全的HTTP協定訂閱位址</value>
|
||||||
|
</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>
|
||||||
</root>
|
</root>
|
||||||
@@ -42,15 +42,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"remarks": "代理GFW",
|
"remarks": "代理IP",
|
||||||
"outboundTag": "proxy",
|
|
||||||
"domain": [
|
|
||||||
"geosite:gfw",
|
|
||||||
"geosite:greatfire"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"remarks": "代理Google等",
|
|
||||||
"outboundTag": "proxy",
|
"outboundTag": "proxy",
|
||||||
"ip": [
|
"ip": [
|
||||||
"1.0.0.1",
|
"1.0.0.1",
|
||||||
@@ -65,6 +57,14 @@
|
|||||||
"geoip:twitter"
|
"geoip:twitter"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"remarks": "代理GFW",
|
||||||
|
"outboundTag": "proxy",
|
||||||
|
"domain": [
|
||||||
|
"geosite:gfw",
|
||||||
|
"geosite:greatfire"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"remarks": "最终直连",
|
"remarks": "最终直连",
|
||||||
"port": "0-65535",
|
"port": "0-65535",
|
||||||
|
|||||||
@@ -34,19 +34,6 @@
|
|||||||
"geosite:private"
|
"geosite:private"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"remarks": "绕过中国域名",
|
|
||||||
"outboundTag": "direct",
|
|
||||||
"domain": [
|
|
||||||
"domain:dns.alidns.com",
|
|
||||||
"domain:doh.pub",
|
|
||||||
"domain:dot.pub",
|
|
||||||
"domain:doh.360.cn",
|
|
||||||
"domain:dot.360.cn",
|
|
||||||
"geosite:cn",
|
|
||||||
"geosite:geolocation-cn"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"remarks": "绕过中国IP",
|
"remarks": "绕过中国IP",
|
||||||
"outboundTag": "direct",
|
"outboundTag": "direct",
|
||||||
@@ -73,6 +60,19 @@
|
|||||||
"geoip:cn"
|
"geoip:cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"remarks": "绕过中国域名",
|
||||||
|
"outboundTag": "direct",
|
||||||
|
"domain": [
|
||||||
|
"domain:dns.alidns.com",
|
||||||
|
"domain:doh.pub",
|
||||||
|
"domain:dot.pub",
|
||||||
|
"domain:doh.360.cn",
|
||||||
|
"domain:dot.360.cn",
|
||||||
|
"geosite:cn",
|
||||||
|
"geosite:geolocation-cn"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"remarks": "最终代理",
|
"remarks": "最终代理",
|
||||||
"port": "0-65535",
|
"port": "0-65535",
|
||||||
|
|||||||
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
|
||||||
@@ -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.0</Version>
|
<Version>7.0.8</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -16,9 +16,11 @@
|
|||||||
<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.1.3" />
|
||||||
<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;
|
||||||
|
|
||||||
@@ -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()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,65 +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)
|
||||||
{
|
{
|
||||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
_checkUpdateModel.Add(GetCheckUpdateModel(_v2rayN));
|
||||||
{
|
_checkUpdateModel.Add(GetCheckUpdateModel(ECoreType.Xray.ToString()));
|
||||||
IsSelected = false,
|
_checkUpdateModel.Add(GetCheckUpdateModel(ECoreType.mihomo.ToString()));
|
||||||
CoreType = _v2rayN,
|
_checkUpdateModel.Add(GetCheckUpdateModel(ECoreType.sing_box.ToString()));
|
||||||
Remarks = ResUI.menuCheckUpdate,
|
}
|
||||||
});
|
_checkUpdateModel.Add(GetCheckUpdateModel(_geo));
|
||||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
|
||||||
{
|
|
||||||
IsSelected = true,
|
|
||||||
CoreType = ECoreType.Xray.ToString(),
|
|
||||||
Remarks = ResUI.menuCheckUpdate,
|
|
||||||
});
|
|
||||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
|
||||||
{
|
|
||||||
IsSelected = true,
|
|
||||||
CoreType = ECoreType.mihomo.ToString(),
|
|
||||||
Remarks = ResUI.menuCheckUpdate,
|
|
||||||
});
|
|
||||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
|
||||||
{
|
|
||||||
IsSelected = true,
|
|
||||||
CoreType = ECoreType.sing_box.ToString(),
|
|
||||||
Remarks = ResUI.menuCheckUpdate,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
private CheckUpdateModel GetCheckUpdateModel(string coreType)
|
||||||
{
|
{
|
||||||
IsSelected = true,
|
return new()
|
||||||
CoreType = _geo,
|
{
|
||||||
|
IsSelected = _config.CheckUpdateItem.SelectedCoreTypes?.Contains(coreType) ?? true,
|
||||||
|
CoreType = coreType,
|
||||||
Remarks = ResUI.menuCheckUpdate,
|
Remarks = ResUI.menuCheckUpdate,
|
||||||
});
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SaveSelectedCoreTypes()
|
||||||
|
{
|
||||||
|
_config.CheckUpdateItem.SelectedCoreTypes = _checkUpdateModel.Where(t => t.IsSelected == true).Select(t => t.CoreType ?? "").ToList();
|
||||||
|
await ConfigHandler.SaveConfig(_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
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, "...");
|
||||||
@@ -99,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,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, "");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,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,
|
||||||
@@ -299,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,7 @@ namespace ServiceLib.ViewModels
|
|||||||
private async Task Init()
|
private async Task Init()
|
||||||
{
|
{
|
||||||
await ProxiesReload();
|
await ProxiesReload();
|
||||||
await DelayTestTask();
|
DelayTestTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DoRulemodeSelected(bool c)
|
private async Task DoRulemodeSelected(bool c)
|
||||||
@@ -434,24 +434,28 @@ namespace ServiceLib.ViewModels
|
|||||||
public async Task DelayTestTask()
|
public async Task DelayTestTask()
|
||||||
{
|
{
|
||||||
var lastTime = DateTime.Now;
|
var lastTime = DateTime.Now;
|
||||||
|
Task.Run(async () =>
|
||||||
Observable.Interval(TimeSpan.FromSeconds(60))
|
|
||||||
.Subscribe(async x =>
|
|
||||||
{
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
await Task.Delay(1000 * 60);
|
||||||
|
|
||||||
if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box)))
|
if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box)))
|
||||||
{
|
{
|
||||||
return;
|
continue;
|
||||||
|
}
|
||||||
|
if (_config.ClashUIItem.ProxiesAutoDelayTestInterval <= 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
var dtNow = DateTime.Now;
|
var dtNow = DateTime.Now;
|
||||||
if (_config.ClashUIItem.ProxiesAutoDelayTestInterval > 0)
|
if ((dtNow - lastTime).Minutes % _config.ClashUIItem.ProxiesAutoDelayTestInterval != 0)
|
||||||
{
|
|
||||||
if ((dtNow - lastTime).Minutes % _config.ClashUIItem.ProxiesAutoDelayTestInterval == 0)
|
|
||||||
{
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
await ProxiesDelayTest();
|
await ProxiesDelayTest();
|
||||||
lastTime = dtNow;
|
lastTime = dtNow;
|
||||||
}
|
}
|
||||||
Task.Delay(1000).Wait();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -208,7 +208,8 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
await ConfigHandler.InitBuiltinRouting(_config);
|
await ConfigHandler.InitBuiltinRouting(_config);
|
||||||
await ConfigHandler.InitBuiltinDNS(_config);
|
await ConfigHandler.InitBuiltinDNS(_config);
|
||||||
CoreHandler.Instance.Init(_config, UpdateHandler);
|
await ProfileExHandler.Instance.Init();
|
||||||
|
await CoreHandler.Instance.Init(_config, UpdateHandler);
|
||||||
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
|
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
|
||||||
|
|
||||||
if (_config.GuiItem.EnableStatistics)
|
if (_config.GuiItem.EnableStatistics)
|
||||||
@@ -265,7 +266,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);
|
||||||
}
|
}
|
||||||
@@ -288,7 +289,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");
|
||||||
}
|
}
|
||||||
@@ -312,6 +313,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()
|
||||||
@@ -389,6 +391,10 @@ namespace ServiceLib.ViewModels
|
|||||||
RefreshServers();
|
RefreshServers();
|
||||||
NoticeHandler.Instance.Enqueue(string.Format(ResUI.SuccessfullyImportedServerViaClipboard, ret));
|
NoticeHandler.Instance.Enqueue(string.Format(ResUI.SuccessfullyImportedServerViaClipboard, ret));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddServerViaScanAsync()
|
public async Task AddServerViaScanAsync()
|
||||||
@@ -433,6 +439,10 @@ namespace ServiceLib.ViewModels
|
|||||||
RefreshServers();
|
RefreshServers();
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.SuccessfullyImportedServerViaScan);
|
NoticeHandler.Instance.Enqueue(ResUI.SuccessfullyImportedServerViaScan);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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; }
|
||||||
@@ -117,6 +116,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 +165,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;
|
||||||
@@ -315,7 +315,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;
|
||||||
@@ -347,14 +346,9 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
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
|
||||||
|
|
||||||
@@ -686,12 +685,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)
|
||||||
|
|||||||
@@ -176,13 +176,14 @@ namespace ServiceLib.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lst = new List<RulesItem4Ray>();
|
var lst = new List<RulesItem>();
|
||||||
foreach (var it in SelectedSources ?? [SelectedSource])
|
foreach (var it in SelectedSources ?? [SelectedSource])
|
||||||
{
|
{
|
||||||
var item = _rules.FirstOrDefault(t => t.Id == it?.Id);
|
var item = _rules.FirstOrDefault(t => t.Id == it?.Id);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
|
var item2 = JsonUtils.DeepCopy(item); //JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
|
||||||
|
item2.Id = null;
|
||||||
lst.Add(item2 ?? new());
|
lst.Add(item2 ?? new());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,18 @@ namespace ServiceLib.ViewModels
|
|||||||
public StatusBarViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
public StatusBarViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||||
{
|
{
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
|
SelectedRouting = new();
|
||||||
|
SelectedServer = new();
|
||||||
|
RunningServerToolTipText = "-";
|
||||||
|
|
||||||
|
if (_config.TunModeItem.EnableTun && AppHandler.Instance.IsAdministrator)
|
||||||
|
{
|
||||||
|
EnableTun = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_config.TunModeItem.EnableTun = EnableTun = false;
|
||||||
|
}
|
||||||
|
|
||||||
#region WhenAnyValue && ReactiveCommand
|
#region WhenAnyValue && ReactiveCommand
|
||||||
|
|
||||||
@@ -179,19 +191,6 @@ namespace ServiceLib.ViewModels
|
|||||||
|
|
||||||
private async Task Init()
|
private async Task Init()
|
||||||
{
|
{
|
||||||
SelectedRouting = new();
|
|
||||||
SelectedServer = new();
|
|
||||||
RunningServerToolTipText = "-";
|
|
||||||
|
|
||||||
if (_config.TunModeItem.EnableTun && AppHandler.Instance.IsAdministrator)
|
|
||||||
{
|
|
||||||
EnableTun = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_config.TunModeItem.EnableTun = EnableTun = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
await RefreshRoutingsMenu();
|
await RefreshRoutingsMenu();
|
||||||
await InboundDisplayStatus();
|
await InboundDisplayStatus();
|
||||||
await ChangeSystemProxyAsync(_config.SystemProxyItem.SysProxyType, true);
|
await ChangeSystemProxyAsync(_config.SystemProxyItem.SysProxyType, true);
|
||||||
|
|||||||
@@ -39,14 +39,14 @@ namespace ServiceLib.ViewModels
|
|||||||
var uri = Utils.TryUri(url);
|
var uri = Utils.TryUri(url);
|
||||||
if (uri == null)
|
if (uri == null)
|
||||||
{
|
{
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.LvUrl);
|
NoticeHandler.Instance.Enqueue(ResUI.InvalidUrlTip);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Do not allow http protocol
|
//Do not allow http protocol
|
||||||
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
|
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
|
||||||
{
|
{
|
||||||
NoticeHandler.Instance.Enqueue(ResUI.LvUrl);
|
NoticeHandler.Instance.Enqueue(ResUI.InsecureUrlProtocol);
|
||||||
return;
|
//return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -161,10 +161,7 @@
|
|||||||
<RowDefinition Height="8" />
|
<RowDefinition Height="8" />
|
||||||
<RowDefinition Height="1*" />
|
<RowDefinition Height="1*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<TextBlock
|
<TextBlock Grid.Row="0" Text="{Binding Name}" />
|
||||||
Grid.Row="0"
|
|
||||||
Text="{Binding Name}"
|
|
||||||
TextWrapping="WrapWithOverflow" />
|
|
||||||
<DockPanel Grid.Row="2">
|
<DockPanel Grid.Row="2">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
DockPanel.Dock="Right"
|
DockPanel.Dock="Right"
|
||||||
|
|||||||
@@ -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,6 +111,8 @@ 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
|
||||||
@@ -158,7 +157,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 +272,22 @@ 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 +315,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 +362,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 +391,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>
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -179,61 +174,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 == null || source.Name != "CellBorder") 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"))
|
||||||
|
|||||||
@@ -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" />
|
||||||
@@ -114,7 +115,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,13 +234,27 @@
|
|||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="12"
|
Grid.Row="12"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Classes="Margin8"
|
||||||
|
Text="{x:Static resx:ResUI.LvMemo}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtMemo"
|
||||||
|
Grid.Row="12"
|
||||||
|
Grid.Column="1"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Classes="Margin8"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="13"
|
||||||
|
Grid.Column="0"
|
||||||
Grid.ColumnSpan="2"
|
Grid.ColumnSpan="2"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Classes="Margin8"
|
Classes="Margin8"
|
||||||
Text="{x:Static resx:ResUI.LvMoreUrl}" />
|
Text="{x:Static resx:ResUI.LvMoreUrl}" />
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txtMoreUrl"
|
x:Name="txtMoreUrl"
|
||||||
Grid.Row="13"
|
Grid.Row="14"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
MinHeight="100"
|
MinHeight="100"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
|
|||||||
@@ -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);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||||
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright>
|
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright>
|
||||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||||
|
<AssemblyName>v2rayN</AssemblyName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -19,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,13 +12,9 @@
|
|||||||
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">
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
|
|||||||
@@ -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,8 @@
|
|||||||
Height="700"
|
Height="700"
|
||||||
MinWidth="900"
|
MinWidth="900"
|
||||||
x:TypeArguments="vms:MainWindowViewModel"
|
x:TypeArguments="vms:MainWindowViewModel"
|
||||||
Background="{DynamicResource MaterialDesignPaper}"
|
|
||||||
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>
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -284,6 +284,8 @@ namespace v2rayN.Views
|
|||||||
switch (e.Key)
|
switch (e.Key)
|
||||||
{
|
{
|
||||||
case Key.V:
|
case Key.V:
|
||||||
|
if (_backupAndRestoreView?.IsVisible == true) return;
|
||||||
|
|
||||||
var clipboardData = WindowsUtils.GetClipboardData();
|
var clipboardData = WindowsUtils.GetClipboardData();
|
||||||
ViewModel?.AddServerViaClipboardAsync(clipboardData);
|
ViewModel?.AddServerViaClipboardAsync(clipboardData);
|
||||||
break;
|
break;
|
||||||
@@ -365,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)
|
||||||
|
|||||||
@@ -1,25 +1,19 @@
|
|||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.SubEditWindow"
|
x:Class="v2rayN.Views.SubEditWindow"
|
||||||
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.menuSubSetting}"
|
Title="{x:Static resx:ResUI.menuSubSetting}"
|
||||||
Width="700"
|
Width="700"
|
||||||
Height="600"
|
Height="600"
|
||||||
x:TypeArguments="vms:SubEditViewModel"
|
x:TypeArguments="vms:SubEditViewModel"
|
||||||
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>
|
||||||
@@ -70,6 +64,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" />
|
||||||
@@ -165,7 +160,7 @@
|
|||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txtAutoUpdateInterval"
|
x:Name="txtAutoUpdateInterval"
|
||||||
Width="200"
|
Width="100"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.SubUrlTips}"
|
||||||
@@ -300,6 +295,23 @@
|
|||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
Style="{StaticResource MyOutlinedTextBox}"
|
Style="{StaticResource MyOutlinedTextBox}"
|
||||||
ToolTip="{x:Static resx:ResUI.TipPreSocksPort}" />
|
ToolTip="{x:Static resx:ResUI.TipPreSocksPort}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="12"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.LvMemo}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtMemo"
|
||||||
|
Grid.Row="12"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
AcceptsReturn="True"
|
||||||
|
Style="{StaticResource MyOutlinedTextBox}"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ namespace v2rayN.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);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
x:Class="v2rayN.Views.SubSettingWindow"
|
x:Class="v2rayN.Views.SubSettingWindow"
|
||||||
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="800"
|
Width="800"
|
||||||
Height="600"
|
Height="600"
|
||||||
x:TypeArguments="vms:SubSettingViewModel"
|
x:TypeArguments="vms:SubSettingViewModel"
|
||||||
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">
|
||||||
<materialDesign:DialogHost
|
<materialDesign:DialogHost
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MaterialDesignThemes" Version="5.1.0" />
|
<PackageReference Include="MaterialDesignThemes" Version="5.1.0" />
|
||||||
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.1.4" />
|
<PackageReference Include="H.NotifyIcon.Wpf" Version="2.1.4" />
|
||||||
<PackageReference Include="TaskScheduler" Version="2.11.0" />
|
|
||||||
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
|
||||||
<PackageReference Include="ReactiveUI.WPF" Version="20.1.63" />
|
<PackageReference Include="ReactiveUI.WPF" Version="20.1.63" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user