Compare commits

...

56 Commits
7.5.2 ... 7.6.2

Author SHA1 Message Date
2dust
43c95422b7 up 7.6.2 2025-01-15 19:49:14 +08:00
esmaiel777
2662243641 Update dns_singbox_normal (#6511) 2025-01-15 19:47:45 +08:00
esmaiel777
060a35e091 Update tun_singbox_dns (#6510) 2025-01-15 19:47:34 +08:00
2dust
de1132c2df Added option to display real-time speed 2025-01-15 19:45:53 +08:00
2dust
f19edc9370 Improvements and Adjustments
InitCoreInfo()
2025-01-15 17:31:13 +08:00
2dust
f1601c463b Improvements and Adjustments
await Task.CompletedTask;
return await Task.FromResult(0);
2025-01-15 17:26:15 +08:00
2dust
77b15cd530 Add a prompt for not setting a password when open Tun on macos 2025-01-15 11:02:49 +08:00
2dust
a6479fe0d0 Update build-windows.yml 2025-01-14 18:15:45 +08:00
2dust
4ad4e27dc1 Improve reload function 2025-01-14 17:05:13 +08:00
2dust
7370684985 Improve delete expired files 2025-01-14 17:04:43 +08:00
2dust
5ae58e6a98 Improve reload function 2025-01-14 14:49:17 +08:00
2dust
780ccb1932 Improved ProfileItemsEx 2025-01-14 11:48:02 +08:00
2dust
6b4076be10 up 7.6.1 2025-01-12 19:36:19 +08:00
alphax-hue3682
d7a04a15ae Update Persian translate (#6487) 2025-01-12 19:33:57 +08:00
2dust
2ae43f8bdb Revert "Remove rules custom Icon"
This reverts commit d3ebc17a10.
2025-01-12 19:33:23 +08:00
2dust
d3ebc17a10 Remove rules custom Icon 2025-01-12 14:35:59 +08:00
2dust
7a8680711e Improvements and Adjustments 2025-01-12 14:30:49 +08:00
2dust
649e89e7af Added Copy Terminal proxy command to clipboard in tray menu
https://github.com/2dust/v2rayN/issues/6482
2025-01-12 11:07:34 +08:00
2dust
cb94d64395 Bug fix 2025-01-11 19:35:32 +08:00
2dust
2440dc2440 Remove deprecated DefIEProxyExceptions 2025-01-11 19:34:04 +08:00
Little丶Dreams
364a24c580 CloneServerStatItem 时检查indexId和toIndexId是否相同 (#6478) 2025-01-11 14:44:09 +08:00
2dust
8f3e0dbd82 up 7.6.0 2025-01-11 11:48:57 +08:00
alphax-hue3682
596234df26 Update Persian translate (#6465)
* Update ResUI.fa-Ir.resx

e0ae101ff4

* Update ResUI.fa-Ir.resx
2025-01-11 11:30:06 +08:00
2dust
c38aec50dc Delete unused resources 2025-01-11 11:28:35 +08:00
2dust
40915b5f98 Adjust theme options for windows 2025-01-11 11:23:40 +08:00
2dust
a176613119 Bug fix for ProcUtils 2025-01-11 10:44:34 +08:00
2dust
6c6de1ae7f Improvements and Adjustments 2025-01-10 20:12:42 +08:00
2dust
edbd168dcf Add theme options for desktop 2025-01-10 15:53:06 +08:00
2dust
127858d582 Adjust UI for desktop 2025-01-10 14:23:03 +08:00
2dust
baf90cfbdd Sing-box cache file specified path
https://github.com/2dust/v2rayN/issues/6460
2025-01-10 10:00:00 +08:00
2dust
1a5eeb9401 Adjust UI for desktop 2025-01-09 21:03:17 +08:00
2dust
e0ae101ff4 Adjust UI for desktop 2025-01-09 15:14:03 +08:00
Long Yixing
8b4a07dfe8 Modify the macos build script (#6461)
No longer generate AppIcon.icns
2025-01-09 10:21:07 +08:00
2dust
db934e70cb The icon of the system proxy can be customized
https://github.com/2dust/v2rayN/issues/6459
2025-01-08 20:35:33 +08:00
2dust
b770048f05 The exported routing rules are compatible with the import function of v2rayNG 2025-01-08 17:57:23 +08:00
2dust
27c53be209 up 7.5.6 2025-01-08 14:16:30 +08:00
2dust
d93c12b354 Add more options to xray fragment 2025-01-08 13:52:21 +08:00
2dust
98d4a47efb Fix Mux for XUDP
https://github.com/2dust/v2rayN/issues/6446
2025-01-07 20:16:05 +08:00
2dust
8ab04c65b5 Update README.md 2025-01-07 14:33:15 +08:00
2dust
1b2dab1388 Bug fix
https://github.com/2dust/v2rayN/issues/6448
2025-01-07 11:28:46 +08:00
2dust
4f8dae7fa0 Add the mixed option in Stack in Tun mode settings
https://github.com/2dust/v2rayN/issues/6441
2025-01-06 20:46:07 +08:00
Harry Huang
cdc23e32c4 Fix zh-Hans and zh-Hant translation style (#6443)
* Fix zh-Hans i10n translation style

* Fix zh-Hant i10n translation style
2025-01-06 19:05:43 +08:00
2dust
20457e9e63 up 7.5.5 2025-01-05 19:10:57 +08:00
2dust
e63042af84 Bug fix for fontsize 2025-01-05 19:10:12 +08:00
2dust
c35b4d3c1b up 7.5.4 2025-01-05 17:58:55 +08:00
2dust
64a83a5d64 down PackageReference 2025-01-05 17:58:23 +08:00
2dust
01039d0b47 up 7.5.3 2025-01-05 17:31:32 +08:00
2dust
7c1e5a3cba Fixed possible crash issues 2025-01-05 17:12:51 +08:00
2dust
038161527f Buf fix for CurrentFontSize 2025-01-05 17:11:32 +08:00
2dust
b12b7a17e6 Fix possible issues with load balancing 2025-01-05 16:31:32 +08:00
2dust
37cf23d5fe up PackageReference 2025-01-05 15:01:15 +08:00
2dust
ed7fb4f6e3 Code clean 2025-01-05 14:50:31 +08:00
2dust
5d4bd2fee6 Fix possible issues with load balancing
https://github.com/2dust/v2rayN/issues/6429
2025-01-05 14:49:53 +08:00
2dust
aae5906311 Fix GetListNetworkServices 2025-01-05 12:24:14 +08:00
2dust
4a7bafd011 Fix Linux restore backup function
Fixed the issue that the guiNConfig.json file cannot be restored in the backup and restore function
2025-01-05 10:22:18 +08:00
2dust
626ebfe65d Improved ModifyFontSize 2025-01-04 20:42:42 +08:00
104 changed files with 1274 additions and 1257 deletions

View File

@@ -29,6 +29,11 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Setup
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Build
run: |
cd v2rayN

View File

@@ -22,7 +22,7 @@ Fedora 30+
### macOS
- `chmod +x v2rayN` Run `./v2rayN` under user permissions
```
macOS 10.14+
macOS 11+
```
## Requirements

View File

@@ -7,22 +7,10 @@ Version="$3"
PackagePath="v2rayN-Package-${Arch}"
mkdir -p "$PackagePath/v2rayN.app/Contents/Resources"
cp -rf "$OutputPath" "$PackagePath/v2rayN.app/Contents/MacOS"
cp -f "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN.icns" "$PackagePath/v2rayN.app/Contents/Resources/AppIcon.icns"
echo "When this file exists, app will not store configs under this folder" > "$PackagePath/v2rayN.app/Contents/MacOS/NotStoreConfigHere.txt"
chmod +x "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN"
mkdir -p "$PackagePath/icons.iconset"
sips -z 16 16 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_16x16.png"
sips -z 32 32 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_16x16@2x.png"
sips -z 32 32 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_32x32.png"
sips -z 64 64 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_32x32@2x.png"
sips -z 128 128 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_128x128.png"
sips -z 256 256 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_128x128@2x.png"
sips -z 256 256 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_256x256.png"
sips -z 512 512 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_256x256@2x.png"
sips -z 512 512 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_512x512.png"
sips -z 1024 1024 "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN2.png" --out "$PackagePath/icons.iconset/icon_512x512@2x.png"
iconutil -c icns "$PackagePath/icons.iconset" -o "$PackagePath/v2rayN.app/Contents/Resources/AppIcon.icns"
cat >"$PackagePath/v2rayN.app/Contents/Info.plist" <<-EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

View File

@@ -5,7 +5,7 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright>
<Copyright>Copyright © 2017-2025 (GPLv3)</Copyright>
<FileVersion>1.3.1</FileVersion>
</PropertyGroup>

View File

@@ -10,7 +10,7 @@ namespace AmazTool
{
Console.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}");
Waiting(3);
Waiting(5);
if (!File.Exists(fileName))
{

View File

@@ -196,5 +196,26 @@ namespace ServiceLib.Common
}
}
}
public static void DeleteExpiredFiles(string sourceDir, DateTime dtLine)
{
try
{
var files = Directory.GetFiles(sourceDir, "*.*");
foreach (var filePath in files)
{
var file = new FileInfo(filePath);
if (file.CreationTime >= dtLine)
{
continue;
}
file.Delete();
}
}
catch
{
// ignored
}
}
}
}

View File

@@ -97,6 +97,30 @@ namespace ServiceLib.Common
return result;
}
/// <summary>
/// Serialize Object to Json string
/// </summary>
/// <param name="obj"></param>
/// <param name="options"></param>
/// <returns></returns>
public static string Serialize(object? obj, JsonSerializerOptions options)
{
var result = string.Empty;
try
{
if (obj == null)
{
return result;
}
result = JsonSerializer.Serialize(obj, options);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return result;
}
/// <summary>
/// SerializeToNode
/// </summary>

View File

@@ -25,36 +25,6 @@ namespace ServiceLib.Common
}
}
public static void ClearLogs()
{
Task.Run(() =>
{
try
{
var now = DateTime.Now.AddMonths(-1);
var dir = Utils.GetLogPath();
var files = Directory.GetFiles(dir, "*.txt");
foreach (var filePath in files)
{
var file = new FileInfo(filePath);
if (file.CreationTime >= now) continue;
try
{
file.Delete();
}
catch
{
// ignored
}
}
}
catch
{
// ignored
}
});
}
public static void SaveLog(string strContent)
{
if (!LogManager.IsLoggingEnabled()) return;

View File

@@ -81,8 +81,7 @@ public static class ProcUtils
return;
}
var fileName = review ? proc?.MainModule?.FileName : null;
var processName = review ? proc?.ProcessName : null;
GetProcessKeyInfo(proc, review, out var procId, out var fileName, out var processName);
try { proc?.Kill(true); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Kill(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
@@ -90,15 +89,50 @@ public static class ProcUtils
try { proc?.Dispose(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
await Task.Delay(300);
if (review && fileName != null)
await ProcessKillByKeyInfo(review, procId, fileName, processName);
}
private static void GetProcessKeyInfo(Process? proc, bool review, out int? procId, out string? fileName, out string? processName)
{
procId = null;
fileName = null;
processName = null;
if (!review) return;
try
{
var proc2 = Process.GetProcessesByName(processName)
.FirstOrDefault(t => t.MainModule?.FileName == fileName);
if (proc2 != null)
procId = proc?.Id;
fileName = proc?.MainModule?.FileName;
processName = proc?.ProcessName;
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
}
private static async Task ProcessKillByKeyInfo(bool review, int? procId, string? fileName, string? processName)
{
if (review && procId != null && fileName != null)
{
try
{
Logging.SaveLog($"{_tag}, KillProcess not completing the job");
await ProcessKill(proc2, false);
proc2 = null;
var lstProc = Process.GetProcessesByName(processName);
foreach (var proc2 in lstProc)
{
if (proc2.Id == procId)
{
Logging.SaveLog($"{_tag}, KillProcess not completing the job, procId");
await ProcessKill(proc2, false);
}
if (proc2.MainModule != null && proc2.MainModule?.FileName == fileName)
{
Logging.SaveLog($"{_tag}, KillProcess not completing the job, fileName");
}
}
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
}
}

View File

@@ -558,7 +558,7 @@ namespace ServiceLib.Common
public static string GetRuntimeInfo()
{
return $"{Utils.GetVersion()} | {Utils.StartupPath()} | {Utils.GetExePath()} | {Environment.OSVersion} | {(Environment.Is64BitOperatingSystem ? 64 : 32)}";
return $"{Utils.GetVersion()} | {Utils.StartupPath()} | {Utils.GetExePath()} | {Environment.OSVersion}";
}
/// <summary>

View File

@@ -5,6 +5,7 @@ namespace ServiceLib.Common
internal static class WindowsUtils
{
private static readonly string _tag = "WindowsUtils";
public static string? RegReadValue(string path, string name, string def)
{
RegistryKey? regKey = null;

View File

@@ -0,0 +1,13 @@
namespace ServiceLib.Enums
{
public enum ETheme
{
FollowSystem,
Dark,
Light,
Aquatic,
Desert,
Dusk,
NightSky
}
}

View File

@@ -63,13 +63,14 @@
public const string HttpProtocol = "http://";
public const string HttpsProtocol = "https://";
public const string SocksProtocol = "socks://";
public const string Socks5Protocol = "socks5://";
public const string UserEMail = "t@t.tt";
public const string AutoRunRegPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
public const string AutoRunName = "v2rayNAutoRun";
public const string CustomIconName = "v2rayN.ico";
public const string SystemProxyExceptionsWindows = "localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*";
public const string SystemProxyExceptionsLinux = "localhost, 127.0.0.0/8, ::1";
public const string SystemProxyExceptionsLinux = "localhost,127.0.0.0/8,::1";
public const string RoutingRuleComma = "<COMMA>";
public const string GrpcGunMode = "gun";
public const string GrpcMultiMode = "multi";
@@ -209,7 +210,7 @@
public static readonly List<string> RuleNetworks = new() { "", "tcp", "udp", "tcp,udp" };
public static readonly List<string> destOverrideProtocols = ["http", "tls", "quic", "fakedns", "fakedns+others"];
public static readonly List<string> TunMtus = new() { "1280", "1408", "1500", "9000" };
public static readonly List<string> TunStacks = new() { "gvisor", "system" };
public static readonly List<string> TunStacks = new() { "gvisor", "system", "mixed" };
public static readonly List<string> PresetMsgFilters = new() { "proxy", "direct", "block", "" };
public static readonly List<string> SingboxMuxs = new() { "h2mux", "smux", "yamux", "" };
public static readonly List<string> TuicCongestionControls = new() { "cubic", "new_reno", "bbr" };

View File

@@ -79,7 +79,8 @@
{
Logging.SaveLog($"v2rayN start up | {Utils.GetRuntimeInfo()}");
Logging.LoggingEnabled(_config.GuiItem.EnableLog);
Logging.ClearLogs();
ClearExpiredFiles();
return true;
}
@@ -91,6 +92,15 @@
return true;
}
private void ClearExpiredFiles()
{
Task.Run(() =>
{
FileManager.DeleteExpiredFiles(Utils.GetLogPath(), DateTime.Now.AddMonths(-1));
FileManager.DeleteExpiredFiles(Utils.GetTempPath(), DateTime.Now.AddMonths(-1));
});
}
#endregion Init
#region Config
@@ -106,7 +116,13 @@
if (Utils.IsWindows())
{
_processJob ??= new();
_processJob?.AddProcess(processHandle);
try
{
_processJob?.AddProcess(processHandle);
}
catch
{
}
}
}
@@ -119,7 +135,7 @@
return await SQLiteHelper.Instance.TableAsync<SubItem>().OrderBy(t => t.Sort).ToListAsync();
}
public async Task<SubItem?> GetSubItem(string subid)
public async Task<SubItem?> GetSubItem(string? subid)
{
return await SQLiteHelper.Instance.TableAsync<SubItem>().FirstOrDefaultAsync(t => t.Id == subid);
}
@@ -164,45 +180,6 @@
return await SQLiteHelper.Instance.QueryAsync<ProfileItemModel>(sql);
}
public async Task<List<ProfileItemModel>?> ProfileItemsEx(string subid, string filter)
{
var lstModel = await ProfileItems(_config.SubIndexId, filter);
await ConfigHandler.SetDefaultServer(_config, lstModel);
var lstServerStat = (_config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
var lstProfileExs = await ProfileExHandler.Instance.GetProfileExs();
lstModel = (from t in lstModel
join t2 in lstServerStat on t.IndexId equals t2.IndexId into t2b
from t22 in t2b.DefaultIfEmpty()
join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b
from t33 in t3b.DefaultIfEmpty()
select new ProfileItemModel
{
IndexId = t.IndexId,
ConfigType = t.ConfigType,
Remarks = t.Remarks,
Address = t.Address,
Port = t.Port,
Security = t.Security,
Network = t.Network,
StreamSecurity = t.StreamSecurity,
Subid = t.Subid,
SubRemarks = t.SubRemarks,
IsActive = t.IndexId == _config.IndexId,
Sort = t33 == null ? 0 : t33.Sort,
Delay = t33 == null ? 0 : t33.Delay,
DelayVal = t33?.Delay != 0 ? $"{t33?.Delay} {Global.DelayUnit}" : string.Empty,
SpeedVal = t33?.Speed != 0 ? $"{t33?.Speed} {Global.SpeedUnit}" : string.Empty,
TodayDown = t22 == null ? "" : Utils.HumanFy(t22.TodayDown),
TodayUp = t22 == null ? "" : Utils.HumanFy(t22.TodayUp),
TotalDown = t22 == null ? "" : Utils.HumanFy(t22.TotalDown),
TotalUp = t22 == null ? "" : Utils.HumanFy(t22.TotalUp)
}).OrderBy(t => t.Sort).ToList();
return lstModel;
}
public async Task<ProfileItem?> GetProfileItem(string indexId)
{
if (Utils.IsNullOrEmpty(indexId))

View File

@@ -45,6 +45,8 @@ namespace ServiceLib.Handler
{
AutoStartTaskService(autoRunName, "", "");
}
await Task.CompletedTask;
}
private static async Task SetTaskWindows()
@@ -66,6 +68,7 @@ namespace ServiceLib.Handler
{
Logging.SaveLog(_tag, ex);
}
await Task.CompletedTask;
}
/// <summary>
@@ -127,6 +130,7 @@ namespace ServiceLib.Handler
{
Logging.SaveLog(_tag, ex);
}
await Task.CompletedTask;
}
private static async Task SetTaskLinux()

View File

@@ -94,10 +94,7 @@ namespace ServiceLib.Handler
EnableTun = false,
Mtu = 9000,
};
config.GuiItem ??= new()
{
EnableStatistics = false,
};
config.GuiItem ??= new();
config.MsgUIItem ??= new();
config.UiItem ??= new UIItem()
@@ -156,12 +153,13 @@ namespace ServiceLib.Handler
config.SystemProxyItem ??= new();
config.WebDavItem ??= new();
config.CheckUpdateItem ??= new();
if (Utils.IsNotEmpty(config.ConstItem.DefIEProxyExceptions))
config.Fragment4RayItem ??= new()
{
config.SystemProxyItem.SystemProxyExceptions = $"{config.ConstItem.DefIEProxyExceptions};{config.SystemProxyItem.SystemProxyExceptions}";
config.ConstItem.DefIEProxyExceptions = string.Empty;
}
Packets = "tlshello",
Length = "100-200",
Interval = "10-20"
};
if (config.SystemProxyItem.SystemProxyExceptions.IsNullOrEmpty())
{
config.SystemProxyItem.SystemProxyExceptions = Utils.IsWindows() ? Global.SystemProxyExceptionsWindows : Global.SystemProxyExceptionsLinux;
@@ -471,7 +469,7 @@ namespace ServiceLib.Handler
}
ProfileExHandler.Instance.SetSort(lstProfile[index].IndexId, sort);
return 0;
return await Task.FromResult(0);
}
/// <summary>
@@ -1049,7 +1047,7 @@ namespace ServiceLib.Handler
Port = node.PreSocksPort.Value,
};
}
await Task.CompletedTask;
return itemSocks;
}
@@ -1619,7 +1617,7 @@ namespace ServiceLib.Handler
break;
}
}
return 0;
return await Task.FromResult(0);
}
public static async Task<int> SetDefaultRouting(Config config, RoutingItem routingItem)
@@ -1870,7 +1868,7 @@ namespace ServiceLib.Handler
await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[1] + "sing_box.json"));
return true;
case EPresetType.Iran:
config.ConstItem.GeoSourceUrl = Global.GeoFilesSources[2];
config.ConstItem.SrsSourceUrl = Global.SingboxRulesetSources[2];

View File

@@ -1,6 +1,4 @@
using YamlDotNet.Core.Tokens;
namespace ServiceLib.Handler
namespace ServiceLib.Handler
{
/// <summary>
/// Core configuration file processing class
@@ -82,7 +80,7 @@ namespace ServiceLib.Handler
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
ret.Success = true;
return ret;
return await Task.FromResult(ret);
}
catch (Exception ex)
{

View File

@@ -67,13 +67,17 @@ namespace ServiceLib.Handler
return;
}
UpdateFunc(true, $"{node.GetSummary()}");
UpdateFunc(false, $"{node.GetSummary()}");
UpdateFunc(false, $"{Utils.GetRuntimeInfo()}");
UpdateFunc(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
await CoreStop();
await Task.Delay(100);
await CoreStart(node);
await CoreStartPreService(node);
if (_process != null)
{
UpdateFunc(true, $"{node.GetSummary()}");
}
}
public async Task<int> LoadCoreConfigSpeedtest(List<ServerTestItem> selecteds)
@@ -220,8 +224,6 @@ namespace ServiceLib.Handler
await RunProcessAsLinuxSudo(proc, fileName, coreInfo, configPath);
}
var startUpErrorMessage = new StringBuilder();
var startUpSuccessful = false;
if (displayLog)
{
proc.OutputDataReceived += (sender, e) =>
@@ -233,11 +235,6 @@ namespace ServiceLib.Handler
{
if (Utils.IsNullOrEmpty(e.Data)) return;
UpdateFunc(false, e.Data + Environment.NewLine);
if (!startUpSuccessful)
{
startUpErrorMessage.Append(e.Data + Environment.NewLine);
}
};
}
proc.Start();
@@ -258,17 +255,12 @@ namespace ServiceLib.Handler
proc.BeginErrorReadLine();
}
if (proc.WaitForExit(1000))
{
proc.CancelErrorRead();
throw new Exception(displayLog ? startUpErrorMessage.ToString() : "启动进程失败并退出 (Failed to start the process and exited)");
}
else
{
startUpSuccessful = true;
}
await Task.Delay(500);
AppHandler.Instance.AddProcess(proc.Handle);
if (proc is null or { HasExited: true })
{
throw new Exception(ResUI.FailedToRunCore);
}
return proc;
}
catch (Exception ex)

View File

@@ -52,144 +52,146 @@
private void InitCoreInfo()
{
_coreInfo = [];
_coreInfo =
[
new CoreInfo
{
CoreType = ECoreType.v2rayN,
Url = Global.NUrl,
ReleaseApiUrl = Global.NUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
DownloadUrlWin64 = Global.NUrl + "/download/{0}/v2rayN-windows-64.zip",
DownloadUrlWinArm64 = Global.NUrl + "/download/{0}/v2rayN-windows-arm64.zip",
DownloadUrlLinux64 = Global.NUrl + "/download/{0}/v2rayN-linux-64.zip",
DownloadUrlLinuxArm64 = Global.NUrl + "/download/{0}/v2rayN-linux-arm64.zip",
DownloadUrlOSX64 = Global.NUrl + "/download/{0}/v2rayN-macos-64.zip",
DownloadUrlOSXArm64 = Global.NUrl + "/download/{0}/v2rayN-macos-arm64.zip",
},
_coreInfo.Add(new CoreInfo
{
CoreType = ECoreType.v2rayN,
Url = Global.NUrl,
ReleaseApiUrl = Global.NUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
DownloadUrlWin64 = Global.NUrl + "/download/{0}/v2rayN-windows-64.zip",
DownloadUrlWinArm64 = Global.NUrl + "/download/{0}/v2rayN-windows-arm64.zip",
DownloadUrlLinux64 = Global.NUrl + "/download/{0}/v2rayN-linux-64.zip",
DownloadUrlLinuxArm64 = Global.NUrl + "/download/{0}/v2rayN-linux-arm64.zip",
DownloadUrlOSX64 = Global.NUrl + "/download/{0}/v2rayN-macos-64.zip",
DownloadUrlOSXArm64 = Global.NUrl + "/download/{0}/v2rayN-macos-arm64.zip",
});
new CoreInfo
{
CoreType = ECoreType.v2fly,
CoreExes = ["wv2ray", "v2ray"],
Arguments = "",
Url = Global.V2flyCoreUrl,
ReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
Match = "V2Ray",
VersionArg = "-version",
RedirectInfo = true,
},
_coreInfo.Add(new CoreInfo
{
CoreType = ECoreType.v2fly,
CoreExes = new List<string> { "wv2ray", "v2ray" },
Arguments = "",
Url = Global.V2flyCoreUrl,
ReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
Match = "V2Ray",
VersionArg = "-version",
RedirectInfo = true,
});
new CoreInfo
{
CoreType = ECoreType.v2fly_v5,
CoreExes = ["v2ray"],
Arguments = "run -c config.json -format jsonv5",
Url = Global.V2flyCoreUrl,
ReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
Match = "V2Ray",
VersionArg = "version",
RedirectInfo = true,
},
_coreInfo.Add(new CoreInfo
{
CoreType = ECoreType.v2fly_v5,
CoreExes = new List<string> { "v2ray" },
Arguments = "run -c config.json -format jsonv5",
Url = Global.V2flyCoreUrl,
ReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
Match = "V2Ray",
VersionArg = "version",
RedirectInfo = true,
});
new CoreInfo
{
CoreType = ECoreType.Xray,
CoreExes = ["xray", "wxray"],
Arguments = "run -c {0}",
Url = Global.XrayCoreUrl,
ReleaseApiUrl = Global.XrayCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
DownloadUrlWin64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-64.zip",
DownloadUrlWinArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-arm64-v8a.zip",
DownloadUrlLinux64 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-64.zip",
DownloadUrlLinuxArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-arm64-v8a.zip",
DownloadUrlOSX64 = Global.XrayCoreUrl + "/download/{0}/Xray-macos-64.zip",
DownloadUrlOSXArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-macos-arm64-v8a.zip",
Match = "Xray",
VersionArg = "-version",
RedirectInfo = true,
},
_coreInfo.Add(new CoreInfo
{
CoreType = ECoreType.Xray,
CoreExes = new List<string> { "xray", "wxray" },
Arguments = "run -c {0}",
Url = Global.XrayCoreUrl,
ReleaseApiUrl = Global.XrayCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
DownloadUrlWin64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-64.zip",
DownloadUrlWinArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-arm64-v8a.zip",
DownloadUrlLinux64 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-64.zip",
DownloadUrlLinuxArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-arm64-v8a.zip",
DownloadUrlOSX64 = Global.XrayCoreUrl + "/download/{0}/Xray-macos-64.zip",
DownloadUrlOSXArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-macos-arm64-v8a.zip",
Match = "Xray",
VersionArg = "-version",
RedirectInfo = true,
});
new CoreInfo
{
CoreType = ECoreType.mihomo,
CoreExes = ["mihomo-windows-amd64-compatible", "mihomo-windows-amd64", "mihomo-linux-amd64", "mihomo", "clash"],
Arguments = "-f config.json" + PortableMode(),
Url = Global.MihomoCoreUrl,
ReleaseApiUrl = Global.MihomoCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
DownloadUrlWin64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-windows-amd64-compatible-{0}.zip",
DownloadUrlWinArm64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-windows-arm64-{0}.zip",
DownloadUrlLinux64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-linux-amd64-compatible-{0}.gz",
DownloadUrlLinuxArm64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-linux-arm64-{0}.gz",
DownloadUrlOSX64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-darwin-amd64-compatible-{0}.gz",
DownloadUrlOSXArm64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-darwin-arm64-{0}.gz",
Match = "Mihomo",
VersionArg = "-v",
RedirectInfo = true,
},
_coreInfo.Add(new CoreInfo
{
CoreType = ECoreType.mihomo,
CoreExes = new List<string> { "mihomo-windows-amd64-compatible", "mihomo-windows-amd64", "mihomo-linux-amd64", "mihomo", "clash" },
Arguments = "-f config.json" + PortableMode(),
Url = Global.MihomoCoreUrl,
ReleaseApiUrl = Global.MihomoCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
DownloadUrlWin64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-windows-amd64-compatible-{0}.zip",
DownloadUrlWinArm64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-windows-arm64-{0}.zip",
DownloadUrlLinux64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-linux-amd64-compatible-{0}.gz",
DownloadUrlLinuxArm64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-linux-arm64-{0}.gz",
DownloadUrlOSX64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-darwin-amd64-compatible-{0}.gz",
DownloadUrlOSXArm64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-darwin-arm64-{0}.gz",
Match = "Mihomo",
VersionArg = "-v",
RedirectInfo = true,
});
new CoreInfo
{
CoreType = ECoreType.hysteria,
CoreExes = ["hysteria-windows-amd64", "hysteria"],
Arguments = "",
Url = Global.HysteriaCoreUrl,
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
RedirectInfo = true,
},
_coreInfo.Add(new CoreInfo
{
CoreType = ECoreType.hysteria,
CoreExes = new List<string> { "hysteria-windows-amd64", "hysteria" },
Arguments = "",
Url = Global.HysteriaCoreUrl,
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
RedirectInfo = true,
});
new CoreInfo
{
CoreType = ECoreType.naiveproxy,
CoreExes = ["naiveproxy", "naive"],
Arguments = "config.json",
Url = Global.NaiveproxyCoreUrl,
RedirectInfo = false,
},
_coreInfo.Add(new CoreInfo
{
CoreType = ECoreType.naiveproxy,
CoreExes = new List<string> { "naiveproxy", "naive" },
Arguments = "config.json",
Url = Global.NaiveproxyCoreUrl,
RedirectInfo = false,
});
new CoreInfo
{
CoreType = ECoreType.tuic,
CoreExes = ["tuic-client", "tuic"],
Arguments = "-c config.json",
Url = Global.TuicCoreUrl,
RedirectInfo = true,
},
_coreInfo.Add(new CoreInfo
{
CoreType = ECoreType.tuic,
CoreExes = new List<string> { "tuic-client", "tuic" },
Arguments = "-c config.json",
Url = Global.TuicCoreUrl,
RedirectInfo = true,
});
new CoreInfo
{
CoreType = ECoreType.sing_box,
CoreExes = ["sing-box-client", "sing-box"],
Arguments = "run -c {0} --disable-color",
Url = Global.SingboxCoreUrl,
RedirectInfo = true,
ReleaseApiUrl = Global.SingboxCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
DownloadUrlWin64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-amd64.zip",
DownloadUrlWinArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-arm64.zip",
DownloadUrlLinux64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-amd64.tar.gz",
DownloadUrlLinuxArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-arm64.tar.gz",
DownloadUrlOSX64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-darwin-amd64.tar.gz",
DownloadUrlOSXArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-darwin-arm64.tar.gz",
Match = "sing-box",
VersionArg = "version",
},
_coreInfo.Add(new CoreInfo
{
CoreType = ECoreType.sing_box,
CoreExes = new List<string> { "sing-box-client", "sing-box" },
Arguments = "run -c {0} --disable-color",
Url = Global.SingboxCoreUrl,
RedirectInfo = true,
ReleaseApiUrl = Global.SingboxCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
DownloadUrlWin64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-amd64.zip",
DownloadUrlWinArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-arm64.zip",
DownloadUrlLinux64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-amd64.tar.gz",
DownloadUrlLinuxArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-arm64.tar.gz",
DownloadUrlOSX64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-darwin-amd64.tar.gz",
DownloadUrlOSXArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-darwin-arm64.tar.gz",
Match = "sing-box",
VersionArg = "version",
});
new CoreInfo
{
CoreType = ECoreType.juicity,
CoreExes = ["juicity-client", "juicity"],
Arguments = "run -c config.json",
Url = Global.JuicityCoreUrl
},
_coreInfo.Add(new CoreInfo
{
CoreType = ECoreType.juicity,
CoreExes = new List<string> { "juicity-client", "juicity" },
Arguments = "run -c config.json",
Url = Global.JuicityCoreUrl
});
new CoreInfo
{
CoreType = ECoreType.hysteria2,
CoreExes = ["hysteria-windows-amd64", "hysteria-linux-amd64", "hysteria"],
Arguments = "",
Url = Global.HysteriaCoreUrl,
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
RedirectInfo = true,
}
_coreInfo.Add(new CoreInfo
{
CoreType = ECoreType.hysteria2,
CoreExes = new List<string> { "hysteria-windows-amd64", "hysteria-linux-amd64", "hysteria" },
Arguments = "",
Url = Global.HysteriaCoreUrl,
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
RedirectInfo = true,
});
];
}
private string PortableMode()

View File

@@ -20,7 +20,7 @@ namespace ServiceLib.Handler
public async Task Init()
{
await InitData();
Task.Run(async () =>
_ = Task.Run(async () =>
{
while (true)
{
@@ -32,7 +32,7 @@ namespace ServiceLib.Handler
public async Task<ConcurrentBag<ProfileExItem>> GetProfileExs()
{
return _lstProfileEx;
return await Task.FromResult(_lstProfileEx);
}
private async Task InitData()

View File

@@ -19,15 +19,13 @@
{
_config = config;
_updateFunc = updateFunc;
if (!config.GuiItem.EnableStatistics)
if (config.GuiItem.EnableStatistics || _config.GuiItem.DisplayRealTimeSpeed)
{
return;
await InitData();
_statisticsXray = new StatisticsXrayService(config, UpdateServerStatHandler);
_statisticsSingbox = new StatisticsSingboxService(config, UpdateServerStatHandler);
}
await InitData();
_statisticsXray = new StatisticsXrayService(config, UpdateServerStatHandler);
_statisticsSingbox = new StatisticsSingboxService(config, UpdateServerStatHandler);
}
public void Close()
@@ -72,6 +70,11 @@
return;
}
if (indexId == toIndexId)
{
return;
}
var stat = _lstServerStat.FirstOrDefault(t => t.IndexId == indexId);
if (stat == null)
{
@@ -96,7 +99,7 @@
private void UpdateServerStatHandler(ServerSpeedItem server)
{
UpdateServerStat(server);
_ = UpdateServerStat(server);
}
private async Task UpdateServerStat(ServerSpeedItem server)

View File

@@ -93,8 +93,9 @@
{
return LstInterface;
}
var lst = services.Split(Environment.NewLine);
return lst.Length > 0 ? LstInterface.Intersect(lst).ToList() : LstInterface;
var lst = services.Split(Environment.NewLine).Where(t => t.Length > 0 && t.Contains('*') == false);
return lst.ToList();
}
}
}

View File

@@ -3,6 +3,7 @@
public static class SysProxyHandler
{
private static readonly string _tag = "SysProxyHandler";
public static async Task<bool> UpdateSysProxy(Config config, bool forceDisable)
{
var type = config.SystemProxyItem.SysProxyType;
@@ -15,7 +16,7 @@
try
{
var port = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks);
var exceptions = config.SystemProxyItem.SystemProxyExceptions;
var exceptions = config.SystemProxyItem.SystemProxyExceptions.Replace(" ", "");
if (port <= 0)
{
return false;
@@ -67,7 +68,7 @@
private static void GetWindowsProxyString(Config config, int port, out string strProxy, out string strExceptions)
{
strExceptions = config.SystemProxyItem.SystemProxyExceptions;
strExceptions = config.SystemProxyItem.SystemProxyExceptions.Replace(" ", "");
if (config.SystemProxyItem.NotProxyLocalAddress)
{
strExceptions = $"<local>;{strExceptions}";

View File

@@ -14,7 +14,6 @@ namespace ServiceLib.Handler
private string _webDir = Global.AppName + "_backup";
private readonly string _webFileName = "backup.zip";
private readonly string _tag = "WebDav--";
public WebDavHandler()
{

View File

@@ -29,7 +29,7 @@
public string? destinationPort { get; set; }
public string? host { get; set; }
public string? nsMode { get; set; }
public object uid { get; set; }
public object? uid { get; set; }
public string? process { get; set; }
public string? processPath { get; set; }
public string? remoteDestination { get; set; }

View File

@@ -47,6 +47,7 @@
public SystemProxyItem SystemProxyItem { get; set; }
public WebDavItem WebDavItem { get; set; }
public CheckUpdateItem CheckUpdateItem { get; set; }
public Fragment4RayItem? Fragment4RayItem { get; set; }
public List<InItem> Inbound { get; set; }
public List<KeyEventItem> GlobalHotkeys { get; set; }
public List<CoreTypeItem> CoreTypeItem { get; set; }

View File

@@ -67,21 +67,13 @@
public class GUIItem
{
public bool AutoRun { get; set; }
public bool EnableStatistics { get; set; }
public bool DisplayRealTimeSpeed { get; set; }
public bool KeepOlderDedupl { get; set; }
public bool IgnoreGeoUpdateCore { get; set; } = true;
public int AutoUpdateInterval { get; set; }
public bool EnableSecurityProtocolTls13 { get; set; }
public int TrayMenuServersLimit { get; set; } = 20;
public bool EnableHWA { get; set; } = false;
public bool EnableLog { get; set; } = true;
}
@@ -102,9 +94,8 @@
public double MainGirdHeight1 { get; set; }
public double MainGirdHeight2 { get; set; }
public EGirdOrientation MainGirdOrientation { get; set; } = EGirdOrientation.Vertical;
public bool ColorModeDark { get; set; }
public bool FollowSystemTheme { get; set; }
public string? ColorPrimaryName { get; set; }
public string? CurrentTheme { get; set; }
public string CurrentLanguage { get; set; }
public string CurrentFontFamily { get; set; }
public int CurrentFontSize { get; set; }
@@ -119,8 +110,7 @@
[Serializable]
public class ConstItem
{
public string DefIEProxyExceptions { get; set; }
public string SubConvertUrl { get; set; } = string.Empty;
public string? SubConvertUrl { get; set; }
public string? GeoSourceUrl { get; set; }
public string? SrsSourceUrl { get; set; }
public string? RouteRulesTemplateSourceUrl { get; set; }
@@ -246,4 +236,12 @@
public bool CheckPreReleaseUpdate { get; set; }
public List<string>? SelectedCoreTypes { get; set; }
}
[Serializable]
public class Fragment4RayItem
{
public string? Packets { get; set; }
public string? Length { get; set; }
public string? Interval { get; set; }
}
}

View File

@@ -843,6 +843,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Copy proxy command to clipboard 的本地化字符串。
/// </summary>
public static string menuCopyProxyCmdToClipboard {
get {
return ResourceManager.GetString("menuCopyProxyCmdToClipboard", resourceCulture);
}
}
/// <summary>
/// 查找类似 Clone selected server 的本地化字符串。
/// </summary>
@@ -942,15 +951,6 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Import old config (guiNConfig) 的本地化字符串。
/// </summary>
public static string menuImportOldGuiConfig {
get {
return ResourceManager.GetString("menuImportOldGuiConfig", resourceCulture);
}
}
/// <summary>
/// 查找类似 Import Rules From Clipboard 的本地化字符串。
/// </summary>
@@ -1348,7 +1348,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Import Advanced Rules 的本地化字符串。
/// 查找类似 Import Rules 的本地化字符串。
/// </summary>
public static string menuRoutingAdvancedImportRules {
get {
@@ -1536,15 +1536,6 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Save Interface Layout 的本地化字符串。
/// </summary>
public static string menuStorageUI {
get {
return ResourceManager.GetString("menuStorageUI", resourceCulture);
}
}
/// <summary>
/// 查找类似 Add 的本地化字符串。
/// </summary>
@@ -2356,15 +2347,6 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Enable advanced function 的本地化字符串。
/// </summary>
public static string TbenableRoutingAdvanced {
get {
return ResourceManager.GetString("TbenableRoutingAdvanced", resourceCulture);
}
}
/// <summary>
/// 查找类似 Enable Tun 的本地化字符串。
/// </summary>
@@ -2815,15 +2797,6 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Dark Mode 的本地化字符串。
/// </summary>
public static string TbSettingsColorMode {
get {
return ResourceManager.GetString("TbSettingsColorMode", resourceCulture);
}
}
/// <summary>
/// 查找类似 Core: basic settings 的本地化字符串。
/// </summary>
@@ -2941,6 +2914,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Display real-time speed 的本地化字符串。
/// </summary>
public static string TbSettingsDisplayRealTimeSpeed {
get {
return ResourceManager.GetString("TbSettingsDisplayRealTimeSpeed", resourceCulture);
}
}
/// <summary>
/// 查找类似 Outbound DNS address 的本地化字符串。
/// </summary>
@@ -3094,15 +3076,6 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Follow System Theme 的本地化字符串。
/// </summary>
public static string TbSettingsFollowSystemTheme {
get {
return ResourceManager.GetString("TbSettingsFollowSystemTheme", resourceCulture);
}
}
/// <summary>
/// 查找类似 Font Size 的本地化字符串。
/// </summary>
@@ -3148,15 +3121,6 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Ignore Geo files when updating core 的本地化字符串。
/// </summary>
public static string TbSettingsIgnoreGeoUpdateCore {
get {
return ResourceManager.GetString("TbSettingsIgnoreGeoUpdateCore", resourceCulture);
}
}
/// <summary>
/// 查找类似 Keep older when deduplication 的本地化字符串。
/// </summary>
@@ -3437,7 +3401,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Enable Statistics (Require restart) 的本地化字符串。
/// 查找类似 Enable traffic statistics (Require restart) 的本地化字符串。
/// </summary>
public static string TbSettingsStatistics {
get {
@@ -3463,6 +3427,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Theme 的本地化字符串。
/// </summary>
public static string TbSettingsTheme {
get {
return ResourceManager.GetString("TbSettingsTheme", resourceCulture);
}
}
/// <summary>
/// 查找类似 Enable Security Protocol TLS v1.3 (subscription/update) 的本地化字符串。
/// </summary>

View File

@@ -481,9 +481,6 @@
<data name="TbSettingsColor" xml:space="preserve">
<value>رنگ</value>
</data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>حالت تاریک</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve">
<value>زبان</value>
</data>
@@ -721,8 +718,8 @@
<data name="TbSettingsHttpPort" xml:space="preserve">
<value>پورت Http</value>
</data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve">
<value>هنگام به‌روزرسانی هسته، فایل‌های Geo را نادیده بگیرید</value>
<data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>Display real-time speed</value>
</data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>هنگام کپی برداری، نگه داری قدیمی تر ها</value>
@@ -839,7 +836,7 @@
<value>اضافه کردن</value>
</data>
<data name="menuRoutingAdvancedImportRules" xml:space="preserve">
<value>وارد کردن قوانین پیشرفته</value>
<value>وارد کردن مجموعه قوانین</value>
</data>
<data name="menuRoutingAdvancedRemove" xml:space="preserve">
<value>حذف انتخاب شده</value>
@@ -853,9 +850,6 @@
<data name="TbdomainStrategy" xml:space="preserve">
<value>استراتژی دامنه</value>
</data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>فعال کردن عملکرد پیشرفته</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve">
<value>3. مسدود کردن دامنه یا آیپی</value>
</data>
@@ -940,9 +934,6 @@
<data name="TbDisplayLog" xml:space="preserve">
<value>نمایش گزارش</value>
</data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>پیکربندی قدیمی guiNConfig را وارد شود</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve">
<value>فعال سازی Tun</value>
</data>
@@ -1105,9 +1096,6 @@
<data name="TipActiveServer" xml:space="preserve">
<value>فعال سازی</value>
</data>
<data name="menuStorageUI" xml:space="preserve">
<value>ذخیره طرح رابط</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>منبع فایل های جغرافیایی (اختیاری)</value>
</data>
@@ -1273,9 +1261,6 @@
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
<value>حداکتر پهنای باند هیستریا (آپلود/دانلود)</value>
</data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>دنبال کردن تم سیستم</value>
</data>
<data name="menuAddTuicServer" xml:space="preserve">
<value>افزودن سرور [TUIC]</value>
</data>
@@ -1402,4 +1387,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks:پورت محلی، socks2: پورت دوم محلی، socks3: پورت LAN</value>
</data>
</root>
<data name="TbSettingsTheme" xml:space="preserve">
<value>تم</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>کپی کردن دستور پروکسی در کلیپ بورد</value>
</data>
</root>

View File

@@ -481,12 +481,6 @@
<data name="TbSettingsColor" xml:space="preserve">
<value>Szín</value>
</data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>Sötét mód</value>
</data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>Kövesse a rendszer témáját</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve">
<value>Nyelv (Újraindítás)</value>
</data>
@@ -724,8 +718,8 @@
<data name="TbSettingsHttpPort" xml:space="preserve">
<value>HTTP Port</value>
</data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve">
<value>Geo fájlok figyelmen kívül hagyása a yalap frissítésekor</value>
<data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>Display real-time speed</value>
</data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>Régi megőrzése a deduplikáció során</value>
@@ -856,9 +850,6 @@
<data name="TbdomainStrategy" xml:space="preserve">
<value>Domain stratégia</value>
</data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>Fejlett funkció engedélyezése</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve">
<value>3. Domain vagy IP blokkolása</value>
</data>
@@ -943,9 +934,6 @@
<data name="TbDisplayLog" xml:space="preserve">
<value>Napló megjelenítése</value>
</data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>Régi konfiguráció importálása (guiNConfig)</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve">
<value>Tun engedélyezése</value>
</data>
@@ -1318,9 +1306,6 @@
<data name="TipActiveServer" xml:space="preserve">
<value>Aktív</value>
</data>
<data name="menuStorageUI" xml:space="preserve">
<value>Szoftverfelület elmentése</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Geo fájlok forrása (opcionális)</value>
</data>
@@ -1402,4 +1387,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks: local port, socks2: second local port, socks3: LAN port</value>
</data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>Theme</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>Copy proxy command to clipboard</value>
</data>
</root>

View File

@@ -481,12 +481,6 @@
<data name="TbSettingsColor" xml:space="preserve">
<value>Color</value>
</data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>Dark Mode</value>
</data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>Follow System Theme</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve">
<value>Language (Restart)</value>
</data>
@@ -724,8 +718,8 @@
<data name="TbSettingsHttpPort" xml:space="preserve">
<value>HTTP Port</value>
</data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve">
<value>Ignore Geo files when updating core</value>
<data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>Display real-time speed (Require restart)</value>
</data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>Keep older when deduplication</value>
@@ -761,7 +755,7 @@
<value>Start on boot</value>
</data>
<data name="TbSettingsStatistics" xml:space="preserve">
<value>Enable Statistics (Require restart)</value>
<value>Enable traffic statistics (Require restart)</value>
</data>
<data name="TbSettingsSubConvert" xml:space="preserve">
<value>Subscription conversion URL</value>
@@ -842,7 +836,7 @@
<value>Add</value>
</data>
<data name="menuRoutingAdvancedImportRules" xml:space="preserve">
<value>Import Advanced Rules</value>
<value>Import Rules</value>
</data>
<data name="menuRoutingAdvancedRemove" xml:space="preserve">
<value>Remove selected (Delete)</value>
@@ -856,9 +850,6 @@
<data name="TbdomainStrategy" xml:space="preserve">
<value>Domain strategy</value>
</data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>Enable advanced function</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve">
<value>3.Block Domain or IP</value>
</data>
@@ -943,9 +934,6 @@
<data name="TbDisplayLog" xml:space="preserve">
<value>Display Log</value>
</data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>Import old config (guiNConfig)</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve">
<value>Enable Tun</value>
</data>
@@ -1318,9 +1306,6 @@
<data name="TipActiveServer" xml:space="preserve">
<value>Active</value>
</data>
<data name="menuStorageUI" xml:space="preserve">
<value>Save Interface Layout</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Geo files source (optional)</value>
</data>
@@ -1402,4 +1387,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks: local port, socks2: second local port, socks3: LAN port</value>
</data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>Theme</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>Copy proxy command to clipboard</value>
</data>
</root>

View File

@@ -481,12 +481,6 @@
<data name="TbSettingsColor" xml:space="preserve">
<value>Цвет</value>
</data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>Тёмный режим</value>
</data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>Следить за системной темой</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve">
<value>Язык (требуется перезапуск)</value>
</data>
@@ -730,8 +724,8 @@
<data name="TbSettingsHttpPort" xml:space="preserve">
<value>HTTP порт</value>
</data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve">
<value>Игнорировать файлы Geo при обновлении ядра</value>
<data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>Display real-time speed</value>
</data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>Сохранить старые при удалении дублей</value>
@@ -862,9 +856,6 @@
<data name="TbdomainStrategy" xml:space="preserve">
<value>Доменная стратегия</value>
</data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>Включить расширенные функции</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve">
<value>3.Заблокировать домен или IP</value>
</data>
@@ -949,9 +940,6 @@
<data name="TbDisplayLog" xml:space="preserve">
<value>Показать логи</value>
</data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>Импортировать старый конфиг guiNConfig</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve">
<value>Режим VPN</value>
</data>
@@ -1270,9 +1258,6 @@
<data name="LvConvertTarget" xml:space="preserve">
<value>Convert target type</value>
</data>
<data name="menuStorageUI" xml:space="preserve">
<value>Save Interface Layout</value>
</data>
<data name="SpeedDisplayText" xml:space="preserve">
<value>{0} : {1}/s↑ | {2}/s↓</value>
</data>
@@ -1402,4 +1387,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks: local port, socks2: second local port, socks3: LAN port</value>
</data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>Theme</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>Copy proxy command to clipboard</value>
</data>
</root>

View File

@@ -127,7 +127,7 @@
<value>配置格式不正确</value>
</data>
<data name="CustomServerTips" xml:space="preserve">
<value>注意,自定义配置完全依赖您自己的配置,不能使用所有设置功能。如需使用系统代理请手动修改监听端口。</value>
<value>注意自定义配置完全依赖您自己的配置,不能使用所有设置功能。如需使用系统代理请手动修改监听端口。</value>
</data>
<data name="Downloading" xml:space="preserve">
<value>下载开始...</value>
@@ -136,7 +136,7 @@
<value>下载</value>
</data>
<data name="DownloadYesNo" xml:space="preserve">
<value>是否下载? {0}</value>
<value>是否下载{0}</value>
</data>
<data name="FailedConversionConfiguration" xml:space="preserve">
<value>转换配置文件失败</value>
@@ -154,7 +154,7 @@
<value>读取配置文件失败</value>
</data>
<data name="FillCorrectServerPort" xml:space="preserve">
<value>请填写正确格式服务器端口</value>
<value>请填写正确格式服务器端口</value>
</data>
<data name="FillLocalListeningPort" xml:space="preserve">
<value>请填写本地监听端口</value>
@@ -169,16 +169,16 @@
<value>请填写用户ID</value>
</data>
<data name="Incorrectconfiguration" xml:space="preserve">
<value>不是正确的配置,请检查</value>
<value>配置不正确,请检查</value>
</data>
<data name="InitialConfiguration" xml:space="preserve">
<value>初始化配置</value>
</data>
<data name="IsLatestCore" xml:space="preserve">
<value>{0} {1} 已是最新版本</value>
<value>{0} {1} 已是最新版本</value>
</data>
<data name="IsLatestN" xml:space="preserve">
<value>{0} {1} 已是最新版本</value>
<value>{0} {1} 已是最新版本</value>
</data>
<data name="LvAddress" xml:space="preserve">
<value>地址</value>
@@ -226,7 +226,7 @@
<value>未设置有效的订阅</value>
</data>
<data name="MsgParsingSuccessfully" xml:space="preserve">
<value>解析{0}成功</value>
<value>解析 {0} 成功</value>
</data>
<data name="MsgStartGettingSubscriptions" xml:space="preserve">
<value>开始获取订阅内容</value>
@@ -259,10 +259,10 @@
<value>在文件夹 ({0}) 下未找到Core文件 (文件名:{1}),请下载后放入文件夹,下载地址: {2}</value>
</data>
<data name="NoValidQRcodeFound" xml:space="preserve">
<value>扫描完成,未发现有效二维码</value>
<value>扫描完成未发现有效二维码</value>
</data>
<data name="OperationFailed" xml:space="preserve">
<value>操作失败,请检查重试</value>
<value>操作失败,请检查重试</value>
</data>
<data name="PleaseFillRemarks" xml:space="preserve">
<value>请填写别名</value>
@@ -280,10 +280,10 @@
<value>服务器去重完成。原数量: {0},现数量: {1}</value>
</data>
<data name="RemoveServer" xml:space="preserve">
<value>是否确定移除服务器?</value>
<value>是否确定移除服务器</value>
</data>
<data name="SaveClientConfigurationIn" xml:space="preserve">
<value>客户端配置文件保存在:{0}</value>
<value>客户端配置文件保存在{0}</value>
</data>
<data name="StartService" xml:space="preserve">
<value>启动服务({0})...</value>
@@ -311,10 +311,10 @@
<value>请先选择规则</value>
</data>
<data name="RemoveRules" xml:space="preserve">
<value>是否确定移除规则?</value>
<value>是否确定移除规则</value>
</data>
<data name="RoutingRuleDetailRequiredTips" xml:space="preserve">
<value>{0},必填其中一项.</value>
<value>{0}必填其中一项.</value>
</data>
<data name="LvRemarks" xml:space="preserve">
<value>别名</value>
@@ -329,10 +329,10 @@
<value>请填写Url</value>
</data>
<data name="AddBatchRoutingRulesYesNo" xml:space="preserve">
<value>是否追加规则?选择则追加,选择否则替换</value>
<value>是否追加规则选择“是”则追加选择“否”则全部替换</value>
</data>
<data name="MsgDownloadGeoFileSuccessfully" xml:space="preserve">
<value>下载 GeoFile: {0} 成功</value>
<value>下载 GeoFile{0} 成功</value>
</data>
<data name="MsgInformationTitle" xml:space="preserve">
<value>信息</value>
@@ -386,7 +386,7 @@
<value>*Kcp seed</value>
</data>
<data name="RegisterGlobalHotkeyFailed" xml:space="preserve">
<value>注册全局热键 {0} 失败,原因 {1}</value>
<value>注册全局热键 {0} 失败原因{1}</value>
</data>
<data name="RegisterGlobalHotkeySuccessfully" xml:space="preserve">
<value>注册全局热键 {0} 成功</value>
@@ -481,14 +481,8 @@
<data name="TbSettingsColor" xml:space="preserve">
<value>颜色</value>
</data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>暗黑模式</value>
</data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>是否跟随系统主题</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve">
<value>语言(重启)</value>
<value>语言(重启)</value>
</data>
<data name="menuAddServerViaClipboard" xml:space="preserve">
<value>从剪贴板导入分享链接 (Ctrl+V)</value>
@@ -638,7 +632,7 @@
<value>传输层安全(TLS)</value>
</data>
<data name="TipNetwork" xml:space="preserve">
<value>*默认tcp,选错会无法连接</value>
<value>*默认tcp选错会无法连接</value>
</data>
<data name="TbCoreType" xml:space="preserve">
<value>Core类型</value>
@@ -671,7 +665,7 @@
<value>Socks端口</value>
</data>
<data name="TipPreSocksPort" xml:space="preserve">
<value>* 自定义配置的Socks端口值可不设置当设置此值后将使用Xray/sing-box(Tun)额外启动一个前置Socks服务提供分流和速度显示等功能</value>
<value>*自定义配置的Socks端口值可不设置当设置此值后将使用Xray/sing-box(Tun)额外启动一个前置Socks服务提供分流和速度显示等功能</value>
</data>
<data name="TbBrowse" xml:space="preserve">
<value>浏览</value>
@@ -680,7 +674,7 @@
<value>编辑</value>
</data>
<data name="TbSettingsAdvancedProtocol" xml:space="preserve">
<value>高级代理设置, 协议选择(可选)</value>
<value>高级代理设置协议选择(可选)</value>
</data>
<data name="TbSettingsAllowLAN" xml:space="preserve">
<value>允许来自局域网的连接</value>
@@ -689,19 +683,19 @@
<value>启动后隐藏窗口</value>
</data>
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
<value>自动更新Geo文件的间隔(单位小时)</value>
<value>自动更新Geo文件的间隔(小时)</value>
</data>
<data name="TbSettingsCore" xml:space="preserve">
<value>Core: 基础设置</value>
</data>
<data name="TbSettingsCoreDns" xml:space="preserve">
<value>V2ray DNS设置</value>
<value>v2ray DNS设置</value>
</data>
<data name="TbSettingsCoreKcp" xml:space="preserve">
<value>Core: KCP设置</value>
</data>
<data name="TbSettingsCoreType" xml:space="preserve">
<value>Core类型设置</value>
<value>Core 类型设置</value>
</data>
<data name="TbSettingsDefAllowInsecure" xml:space="preserve">
<value>默认跳过证书验证(allowInsecure)</value>
@@ -719,13 +713,13 @@
<value>例外</value>
</data>
<data name="TbSettingsExceptionTip" xml:space="preserve">
<value>例外. 对于下列字符开头的地址不使用代理配置文件:使用分号(;)分隔</value>
<value>例外对于下列字符开头的地址不使用代理配置文件使用分号(;)分隔</value>
</data>
<data name="TbSettingsHttpPort" xml:space="preserve">
<value>本地http监听端口</value>
</data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve">
<value>更新Core时忽略Geo文件</value>
<data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>显示实时速度(需重启)</value>
</data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>去重时保留序号较小的项</value>
@@ -746,7 +740,7 @@
<value>认证密码</value>
</data>
<data name="TbSettingsRemoteDNS" xml:space="preserve">
<value>自定义DNS(可多个,用逗号(,)分隔)</value>
<value>自定义DNS(可多个用逗号(,)分隔)</value>
</data>
<data name="TbSettingsSetUWP" xml:space="preserve">
<value>解除Win10 UWP应用回环代理限制</value>
@@ -761,7 +755,7 @@
<value>开机启动(可能会不成功)</value>
</data>
<data name="TbSettingsStatistics" xml:space="preserve">
<value>启用统计(实时网速显示,需重启)</value>
<value>启用流量统计(需重启</value>
</data>
<data name="TbSettingsSubConvert" xml:space="preserve">
<value>订阅转换网址(可选)</value>
@@ -791,7 +785,7 @@
<value>全局热键设置</value>
</data>
<data name="TbGlobalHotkeySettingTip" xml:space="preserve">
<value>直接按键盘进行设置, 重启后生效</value>
<value>直接按键盘进行设置重启后生效</value>
</data>
<data name="TbNotChangeSystemProxy" xml:space="preserve">
<value>不改变系统代理</value>
@@ -830,7 +824,7 @@
<value>上移 (U)</value>
</data>
<data name="MsgFilterTitle" xml:space="preserve">
<value>过滤器, 支持正则</value>
<value>过滤器(支持正则)</value>
</data>
<data name="menuWebsiteItem" xml:space="preserve">
<value>{0} 官网</value>
@@ -842,7 +836,7 @@
<value>添加规则集</value>
</data>
<data name="menuRoutingAdvancedImportRules" xml:space="preserve">
<value>一键导入高级规则</value>
<value>一键导入规则</value>
</data>
<data name="menuRoutingAdvancedRemove" xml:space="preserve">
<value>移除所选规则 (Delete)</value>
@@ -856,9 +850,6 @@
<data name="TbdomainStrategy" xml:space="preserve">
<value>域名解析策略</value>
</data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>启用高级功能</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve">
<value>3.阻止的Domain或IP</value>
</data>
@@ -872,7 +863,7 @@
<value>预定义规则集列表</value>
</data>
<data name="TbRoutingTips" xml:space="preserve">
<value>*设置的路由规则,用逗号(,)分隔;正则中的逗号用&lt;COMMA&gt;替代</value>
<value>*设置的路由规则用逗号(,)分隔正则中的逗号用&lt;COMMA&gt;替代</value>
</data>
<data name="menuImportRulesFromClipboard" xml:space="preserve">
<value>从剪贴板中导入规则</value>
@@ -902,13 +893,13 @@
<value>路由规则详情设置</value>
</data>
<data name="TbAutoSort" xml:space="preserve">
<value>保存时Domain, IP, 进程名 自动排序</value>
<value>保存时 Domain, IP, 进程名 自动排序</value>
</data>
<data name="TbRuleobjectDoc" xml:space="preserve">
<value>规则详细说明文档</value>
</data>
<data name="TbDnsObjectDoc" xml:space="preserve">
<value>支持填写DnsObject,JSON格式点击查看文档</value>
<value>支持填写DnsObjectJSON格式点击查看文档</value>
</data>
<data name="SubUrlTips" xml:space="preserve">
<value>普通分组此处请留空</value>
@@ -920,7 +911,7 @@
<value>系统代理设置改变</value>
</data>
<data name="TbSettingsRouteOnly" xml:space="preserve">
<value>RouteOnly</value>
<value>仅限路由(routeOnly)</value>
</data>
<data name="TbSettingsNotProxyLocalAddress" xml:space="preserve">
<value>请勿将代理服务器用于本地Intranet地址</value>
@@ -935,7 +926,7 @@
<value>速度(M/s)</value>
</data>
<data name="FailedToRunCore" xml:space="preserve">
<value>运行Core失败请看日志</value>
<value>运行Core失败看日志</value>
</data>
<data name="LvFilter" xml:space="preserve">
<value>别名正则过滤</value>
@@ -943,9 +934,6 @@
<data name="TbDisplayLog" xml:space="preserve">
<value>显示日志</value>
</data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>导入旧的配置文件guiNConfig</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve">
<value>启用Tun</value>
</data>
@@ -953,7 +941,7 @@
<value>为局域网开启新的端口</value>
</data>
<data name="TbSettingsTunMode" xml:space="preserve">
<value>Tun模式设置</value>
<value>Tun 模式设置</value>
</data>
<data name="menuMoveToGroup" xml:space="preserve">
<value>移至订阅分组</value>
@@ -1315,9 +1303,6 @@
<data name="TipActiveServer" xml:space="preserve">
<value>活动</value>
</data>
<data name="menuStorageUI" xml:space="preserve">
<value>保存界面布局</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Geo文件来源(可选)</value>
</data>
@@ -1373,7 +1358,7 @@
<value>请先在Tun模式设置中设置sudo密码</value>
</data>
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
<value>请不要用sudo运行本app</value>
<value>请不要用sudo运行本程序</value>
</data>
<data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp 模式</value>
@@ -1388,7 +1373,7 @@
<value>测试时自动分批的每批数量最大1000</value>
</data>
<data name="TbSettingsExceptionTip2" xml:space="preserve">
<value>例外. 对于下列地址不使用代理配置文件:使用逗号(,)分隔</value>
<value>例外对于下列地址不使用代理配置文件使用逗号(,)分隔</value>
</data>
<data name="TbSettingsDestOverride" xml:space="preserve">
<value>流量探测类型</value>
@@ -1399,4 +1384,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks本地端口socks2第二个本地端口socks3局域网端口</value>
</data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>主题</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>复制终端代理命令至剪贴板</value>
</data>
</root>

View File

@@ -136,7 +136,7 @@
<value>下載</value>
</data>
<data name="DownloadYesNo" xml:space="preserve">
<value>是否下載? {0}</value>
<value>是否下載{0}</value>
</data>
<data name="FailedConversionConfiguration" xml:space="preserve">
<value>轉換設定檔失敗</value>
@@ -154,7 +154,7 @@
<value>讀取設定檔失敗</value>
</data>
<data name="FillCorrectServerPort" xml:space="preserve">
<value>請填寫正確格式伺服器埠</value>
<value>請填寫正確格式伺服器埠</value>
</data>
<data name="FillLocalListeningPort" xml:space="preserve">
<value>請填寫本機偵聽埠</value>
@@ -169,16 +169,16 @@
<value>請填寫使用者ID</value>
</data>
<data name="Incorrectconfiguration" xml:space="preserve">
<value>不是正確的設定,請檢查</value>
<value>設定不正確,請檢查</value>
</data>
<data name="InitialConfiguration" xml:space="preserve">
<value>初始化設定</value>
</data>
<data name="IsLatestCore" xml:space="preserve">
<value>{0} {1} 已是最新版本</value>
<value>{0} {1} 已是最新版本</value>
</data>
<data name="IsLatestN" xml:space="preserve">
<value>{0} {1} 已是最新版本</value>
<value>{0} {1} 已是最新版本</value>
</data>
<data name="LvAddress" xml:space="preserve">
<value>位址</value>
@@ -226,7 +226,7 @@
<value>未設定有效的訂閱</value>
</data>
<data name="MsgParsingSuccessfully" xml:space="preserve">
<value>解析{0}成功</value>
<value>解析 {0} 成功</value>
</data>
<data name="MsgStartGettingSubscriptions" xml:space="preserve">
<value>開始獲取訂閱內容</value>
@@ -259,10 +259,10 @@
<value>在資料夾 ({0}) 下未找到Core檔案 (檔案名:{1}),請下載後放入資料夾,下載網址: {2}</value>
</data>
<data name="NoValidQRcodeFound" xml:space="preserve">
<value>掃描完成,未發現有效二維碼</value>
<value>掃描完成未發現有效二維碼</value>
</data>
<data name="OperationFailed" xml:space="preserve">
<value>操作失敗,請檢查重試</value>
<value>操作失敗,請檢查重試</value>
</data>
<data name="PleaseFillRemarks" xml:space="preserve">
<value>請填寫別名</value>
@@ -280,16 +280,17 @@
<value>伺服器去重完成。原數量: {0},現數量: {1}</value>
</data>
<data name="RemoveServer" xml:space="preserve">
<value>是否確定移除伺服器?</value>
<value>是否確定移除伺服器</value>
</data>
<data name="SaveClientConfigurationIn" xml:space="preserve">
<value>用戶端設定檔儲存在:{0}</value>
<value>用戶端設定檔儲存在{0}</value>
</data>
<data name="StartService" xml:space="preserve">
<value>啟動服務({0})...</value>
</data>
<data name="SuccessfulConfiguration" xml:space="preserve">
<value>設定成功{0}</value>
<value>設定成功
{0}</value>
</data>
<data name="SuccessfullyImportedCustomServer" xml:space="preserve">
<value>成功匯入自訂設定伺服器</value>
@@ -310,10 +311,10 @@
<value>請先選擇規則</value>
</data>
<data name="RemoveRules" xml:space="preserve">
<value>是否確定移除規則?</value>
<value>是否確定移除規則</value>
</data>
<data name="RoutingRuleDetailRequiredTips" xml:space="preserve">
<value>{0},必填其中一項.</value>
<value>{0}必填其中一項.</value>
</data>
<data name="LvRemarks" xml:space="preserve">
<value>別名</value>
@@ -328,10 +329,10 @@
<value>請填寫URL</value>
</data>
<data name="AddBatchRoutingRulesYesNo" xml:space="preserve">
<value>是否追加規則?選擇則追加,選擇否則取代</value>
<value>是否追加規則選擇“是”則追加選擇“否”則完全取代</value>
</data>
<data name="MsgDownloadGeoFileSuccessfully" xml:space="preserve">
<value>下載 GeoFile: {0} 成功</value>
<value>下載 GeoFile{0} 成功</value>
</data>
<data name="MsgInformationTitle" xml:space="preserve">
<value>資訊</value>
@@ -385,7 +386,7 @@
<value>*KCP seed</value>
</data>
<data name="RegisterGlobalHotkeyFailed" xml:space="preserve">
<value>註冊全域快速鍵 {0} 失敗,原因 {1}</value>
<value>註冊全域快速鍵 {0} 失敗原因{1}</value>
</data>
<data name="RegisterGlobalHotkeySuccessfully" xml:space="preserve">
<value>註冊全域快速鍵 {0} 成功</value>
@@ -480,14 +481,8 @@
<data name="TbSettingsColor" xml:space="preserve">
<value>顏色</value>
</data>
<data name="TbSettingsColorMode" xml:space="preserve">
<value>暗黑模式</value>
</data>
<data name="TbSettingsFollowSystemTheme" xml:space="preserve">
<value>是否跟隨系統主題</value>
</data>
<data name="TbSettingsLanguage" xml:space="preserve">
<value>語言(重啟)</value>
<value>語言(重啟)</value>
</data>
<data name="menuAddServerViaClipboard" xml:space="preserve">
<value>從剪貼簿導入分享鏈接 (Ctrl+V)</value>
@@ -637,7 +632,7 @@
<value>傳輸層安全(TLS)</value>
</data>
<data name="TipNetwork" xml:space="preserve">
<value>*預設TCP,選錯會無法連接</value>
<value>*預設TCP選錯會無法連接</value>
</data>
<data name="TbCoreType" xml:space="preserve">
<value>Core類型</value>
@@ -670,7 +665,7 @@
<value>SOCKS埠</value>
</data>
<data name="TipPreSocksPort" xml:space="preserve">
<value>* 自訂設定的Socks埠值可不設定當設定此值後將使用Xray/sing-box(Tun)額外啟動一個前置Socks服務提供分流和速度顯示等功能</value>
<value>*自訂設定的Socks埠值可不設定當設定此值後將使用Xray/sing-box(Tun)額外啟動一個前置Socks服務提供分流和速度顯示等功能</value>
</data>
<!--********************************************-->
<data name="TbBrowse" xml:space="preserve">
@@ -680,7 +675,7 @@
<value>編輯</value>
</data>
<data name="TbSettingsAdvancedProtocol" xml:space="preserve">
<value>進階代理設定, 協定選擇(可選)</value>
<value>進階代理設定協定選擇(可選)</value>
</data>
<data name="TbSettingsAllowLAN" xml:space="preserve">
<value>允許來自區域網路的連線</value>
@@ -689,7 +684,7 @@
<value>啟動後隱藏視窗</value>
</data>
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
<value>自動更新Geo檔案的間隔(單位小時)</value>
<value>自動更新Geo檔案的間隔(小時)</value>
</data>
<data name="TbSettingsCore" xml:space="preserve">
<value>Core: 基礎設定</value>
@@ -701,7 +696,7 @@
<value>Core: KCP設定</value>
</data>
<data name="TbSettingsCoreType" xml:space="preserve">
<value>Core類型設定</value>
<value>Core 類型設定</value>
</data>
<data name="TbSettingsDefAllowInsecure" xml:space="preserve">
<value>預設跳過憑證驗證(allowinsecure)</value>
@@ -719,13 +714,13 @@
<value>例外</value>
</data>
<data name="TbSettingsExceptionTip" xml:space="preserve">
<value>例外. 對於下列字元開頭的位址不使用代理設定檔:使用分號(;)分隔</value>
<value>例外對於下列字元開頭的位址不使用代理設定檔使用分號(;)分隔</value>
</data>
<data name="TbSettingsHttpPort" xml:space="preserve">
<value>本機HTTP偵聽埠</value>
</data>
<data name="TbSettingsIgnoreGeoUpdateCore" xml:space="preserve">
<value>更新Core時忽略Geo檔案</value>
<data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>顯示即時速度(需重啟)</value>
</data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>去重時保留序號較小的項</value>
@@ -746,7 +741,7 @@
<value>認證密碼</value>
</data>
<data name="TbSettingsRemoteDNS" xml:space="preserve">
<value>自訂DNS(可多個,用逗號(,)分隔)</value>
<value>自訂DNS(可多個用逗號(,)分隔)</value>
</data>
<data name="TbSettingsSetUWP" xml:space="preserve">
<value>解除Win10 UWP應用回環代理限制</value>
@@ -761,7 +756,7 @@
<value>開機啟動(可能會不成功)</value>
</data>
<data name="TbSettingsStatistics" xml:space="preserve">
<value>啟用統計(即時網速顯示,需重啟)</value>
<value>啟用流量統計(需重啟</value>
</data>
<data name="TbSettingsSubConvert" xml:space="preserve">
<value>訂閱轉換網址(可選)</value>
@@ -791,7 +786,7 @@
<value>全域快速鍵設定</value>
</data>
<data name="TbGlobalHotkeySettingTip" xml:space="preserve">
<value>直接按鍵盤進行設定, 重啟後生效</value>
<value>直接按鍵盤進行設定重啟後生效</value>
</data>
<data name="TbNotChangeSystemProxy" xml:space="preserve">
<value>不改變系統代理</value>
@@ -830,7 +825,7 @@
<value>上移 (U)</value>
</data>
<data name="MsgFilterTitle" xml:space="preserve">
<value>過濾, 支援正則</value>
<value>過濾(允許正則)</value>
</data>
<data name="menuWebsiteItem" xml:space="preserve">
<value>{0} 官網</value>
@@ -842,7 +837,7 @@
<value>新增規則集</value>
</data>
<data name="menuRoutingAdvancedImportRules" xml:space="preserve">
<value>一鍵匯入進階規則</value>
<value>一鍵匯入規則</value>
</data>
<data name="menuRoutingAdvancedRemove" xml:space="preserve">
<value>移除所選規則 (Delete)</value>
@@ -856,9 +851,6 @@
<data name="TbdomainStrategy" xml:space="preserve">
<value>域名解析策略</value>
</data>
<data name="TbenableRoutingAdvanced" xml:space="preserve">
<value>啟動進階功能</value>
</data>
<data name="TbRoutingTabBlock" xml:space="preserve">
<value>3.阻止的Domain或IP</value>
</data>
@@ -872,7 +864,7 @@
<value>預定義規則集列表</value>
</data>
<data name="TbRoutingTips" xml:space="preserve">
<value>*設定的路由規則,用逗號(,)分隔;正則中的逗號用&lt;COMMA&gt;替代</value>
<value>*設定的路由規則用逗號(,)分隔正則中的逗號用&lt;COMMA&gt;替代</value>
</data>
<data name="menuImportRulesFromClipboard" xml:space="preserve">
<value>從剪貼簿中匯入規則</value>
@@ -902,13 +894,13 @@
<value>路由規則詳情設定</value>
</data>
<data name="TbAutoSort" xml:space="preserve">
<value>儲存時Domain, IP, 行程名 自動排序</value>
<value>儲存時 Domain, IP, 行程名 自動排序</value>
</data>
<data name="TbRuleobjectDoc" xml:space="preserve">
<value>規則詳細說明檔案</value>
</data>
<data name="TbDnsObjectDoc" xml:space="preserve">
<value>支援填寫DnsObject,JSON格式點擊查看檔案</value>
<value>支援填寫DnsObjectJSON格式點擊查看説明</value>
</data>
<data name="SubUrlTips" xml:space="preserve">
<value>普通分組此處請留空</value>
@@ -920,7 +912,7 @@
<value>系統代理設定已改變</value>
</data>
<data name="TbSettingsRouteOnly" xml:space="preserve">
<value>RouteOnly</value>
<value>僅限路由(routeOnly)</value>
</data>
<data name="TbSettingsNotProxyLocalAddress" xml:space="preserve">
<value>請勿將代理伺服器用於本機Intranet位址</value>
@@ -935,7 +927,7 @@
<value>速度(M/s)</value>
</data>
<data name="FailedToRunCore" xml:space="preserve">
<value>執行Core失敗日誌</value>
<value>執行Core失敗查閲日誌</value>
</data>
<data name="LvFilter" xml:space="preserve">
<value>別名正則過濾</value>
@@ -943,17 +935,14 @@
<data name="TbDisplayLog" xml:space="preserve">
<value>顯示日誌</value>
</data>
<data name="menuImportOldGuiConfig" xml:space="preserve">
<value>匯入舊的設定檔guiNConfig</value>
</data>
<data name="TbEnableTunAs" xml:space="preserve">
<value>啟用TUN</value>
<value>啟用Tun</value>
</data>
<data name="TbSettingsNewPort4LAN" xml:space="preserve">
<value>為區域網路開啟新的埠</value>
</data>
<data name="TbSettingsTunMode" xml:space="preserve">
<value>TUN模式設定</value>
<value>Tun 模式設定</value>
</data>
<data name="menuMoveToGroup" xml:space="preserve">
<value>移至訂閱分組</value>
@@ -1067,7 +1056,7 @@
<value>sing-box Mux 多路復用協定</value>
</data>
<data name="TbRoutingRuleProcess" xml:space="preserve">
<value>行程名全稱 (TUN模式)</value>
<value>行程名全稱 (Tun模式)</value>
</data>
<data name="TbRoutingRuleDomain" xml:space="preserve">
<value>Domain</value>
@@ -1195,9 +1184,6 @@
<data name="TipActiveServer" xml:space="preserve">
<value>活動</value>
</data>
<data name="menuStorageUI" xml:space="preserve">
<value>儲存介面佈局</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Geo檔案來源(可選)</value>
</data>
@@ -1373,7 +1359,7 @@
<value>請先在Tun模式設定中設定sudo密碼</value>
</data>
<data name="TbSettingsLinuxSudoPasswordNotSudoRunApp" xml:space="preserve">
<value>請不要用sudo來運行本app</value>
<value>請不要用sudo來運行此App</value>
</data>
<data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp 模式</value>
@@ -1388,7 +1374,7 @@
<value>測試時自動分批的每批數量最大1000</value>
</data>
<data name="TbSettingsExceptionTip2" xml:space="preserve">
<value>例外. 對於下列位址不使用代理設定檔:使用逗號(,)分隔</value>
<value>例外對於下列位址不使用代理設定檔使用逗號(,)分隔</value>
</data>
<data name="TbSettingsDestOverride" xml:space="preserve">
<value>流量探測類型</value>
@@ -1399,4 +1385,10 @@
<data name="TbRoutingInboundTagTips" xml:space="preserve">
<value>socks本地端口socks2第二個本地端口socks3區域網路端口</value>
</data>
<data name="TbSettingsTheme" xml:space="preserve">
<value>主題</value>
</data>
<data name="menuCopyProxyCmdToClipboard" xml:space="preserve">
<value>複製終端代理指令至剪貼簿</value>
</data>
</root>

View File

@@ -5,24 +5,25 @@
"loglevel": "warning"
},
"inbounds": [],
"outbounds": [{
"outbounds": [
{
"tag": "proxy",
"protocol": "vmess",
"settings": {
"vnext": [{
"address": "v2ray.cool",
"port": 10086,
"address": "",
"port": 0,
"users": [{
"id": "a3482e88-686a-4a58-8126-99c9df64b7bf",
"id": "",
"security": "auto"
}]
}],
"servers": [{
"address": "v2ray.cool",
"method": "chacha20",
"address": "",
"method": "",
"ota": false,
"password": "123456",
"port": 10086,
"password": "",
"port": 0,
"level": 1
}]
},
@@ -35,27 +36,23 @@
},
{
"protocol": "freedom",
"settings": {},
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block",
"settings": {
"response": {
"type": "http"
}
}
"tag": "block"
}
],
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"inboundTag": ["api"],
"outboundTag": "api",
"type": "field"
}
{
"inboundTag": [
"api"
],
"outboundTag": "api",
"type": "field"
}
]
}
}

View File

@@ -2,7 +2,7 @@
"servers": [
{
"tag": "remote",
"address": "8.8.8.8",
"address": "tcp://8.8.8.8",
"strategy": "prefer_ipv4",
"detour": "proxy"
},
@@ -32,4 +32,4 @@
}
],
"final": "remote"
}
}

View File

@@ -2,7 +2,7 @@
"servers": [
{
"tag": "remote",
"address": "8.8.8.8",
"address": "tcp://8.8.8.8",
"strategy": "prefer_ipv4",
"detour": "proxy"
},
@@ -33,4 +33,4 @@
}
],
"final": "remote"
}
}

View File

@@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>7.5.2</Version>
<Version>7.6.2</Version>
</PropertyGroup>
<ItemGroup>

View File

@@ -313,7 +313,7 @@ namespace ServiceLib.Services.CoreConfig
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
await GenOutbound(item, outbound);
outbound.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}";
singboxConfig.outbounds.Add(outbound);
singboxConfig.outbounds.Insert(0, outbound);
tagProxy.Add(outbound.tag);
}
if (tagProxy.Count <= 0)
@@ -333,7 +333,7 @@ namespace ServiceLib.Services.CoreConfig
outbounds = tagProxy,
interrupt_exist_connections = false,
};
singboxConfig.outbounds.Add(outUrltest);
singboxConfig.outbounds.Insert(0, outUrltest);
//add selector outbound
var outSelector = new Outbound4Sbox
@@ -344,7 +344,7 @@ namespace ServiceLib.Services.CoreConfig
interrupt_exist_connections = false,
};
outSelector.outbounds.Insert(0, outUrltest.tag);
singboxConfig.outbounds.Add(outSelector);
singboxConfig.outbounds.Insert(0, outSelector);
ret.Success = true;
ret.Data = JsonUtils.Serialize(singboxConfig);
@@ -476,7 +476,7 @@ namespace ServiceLib.Services.CoreConfig
{
Logging.SaveLog(_tag, ex);
}
return 0;
return await Task.FromResult(0);
}
private async Task<int> GenInbounds(SingboxConfig singboxConfig)
@@ -721,7 +721,7 @@ namespace ServiceLib.Services.CoreConfig
{
Logging.SaveLog(_tag, ex);
}
return 0;
return await Task.FromResult(0);
}
private async Task<int> GenOutboundTls(ProfileItem node, Outbound4Sbox outbound)
@@ -771,7 +771,7 @@ namespace ServiceLib.Services.CoreConfig
{
Logging.SaveLog(_tag, ex);
}
return 0;
return await Task.FromResult(0);
}
private async Task<int> GenOutboundTransport(ProfileItem node, Outbound4Sbox outbound)
@@ -848,7 +848,7 @@ namespace ServiceLib.Services.CoreConfig
{
Logging.SaveLog(_tag, ex);
}
return 0;
return await Task.FromResult(0);
}
private async Task<int> GenMoreOutbounds(ProfileItem node, SingboxConfig singboxConfig)
@@ -1088,7 +1088,7 @@ namespace ServiceLib.Services.CoreConfig
{
Logging.SaveLog(_tag, ex);
}
return 0;
return await Task.FromResult(0);
}
private bool ParseV2Domain(string domain, Rule4Sbox rule)
@@ -1240,7 +1240,7 @@ namespace ServiceLib.Services.CoreConfig
}
singboxConfig.dns = dns4Sbox;
return 0;
return await Task.FromResult(0);
}
private async Task<int> GenExperimental(SingboxConfig singboxConfig)
@@ -1259,11 +1259,12 @@ namespace ServiceLib.Services.CoreConfig
singboxConfig.experimental ??= new Experimental4Sbox();
singboxConfig.experimental.cache_file = new CacheFile4Sbox()
{
enabled = true
enabled = true,
path = Utils.GetConfigPath("cache.db")
};
}
return 0;
return await Task.FromResult(0);
}
private async Task<int> ConvertGeo2Ruleset(SingboxConfig singboxConfig)

View File

@@ -154,7 +154,7 @@ namespace ServiceLib.Services.CoreConfig
var outbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
await GenOutbound(item, outbound);
outbound.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}";
v2rayConfig.outbounds.Add(outbound);
v2rayConfig.outbounds.Insert(0, outbound);
tagProxy.Add(outbound.tag);
}
if (tagProxy.Count <= 0)
@@ -182,15 +182,12 @@ namespace ServiceLib.Services.CoreConfig
rule.balancerTag = balancer.tag;
}
}
else
v2rayConfig.routing.rules.Add(new()
{
v2rayConfig.routing.rules.Add(new()
{
network = "tcp,udp",
balancerTag = balancer.tag,
type = "field"
});
}
network = "tcp,udp",
balancerTag = balancer.tag,
type = "field"
});
ret.Success = true;
ret.Data = JsonUtils.Serialize(v2rayConfig);
@@ -382,7 +379,7 @@ namespace ServiceLib.Services.CoreConfig
{
Logging.SaveLog(_tag, ex);
}
return 0;
return await Task.FromResult(0);
}
private async Task<int> GenInbounds(V2rayConfig v2rayConfig)
@@ -426,7 +423,7 @@ namespace ServiceLib.Services.CoreConfig
{
Logging.SaveLog(_tag, ex);
}
return 0;
return await Task.FromResult(0);
}
private Inbounds4Ray GetInbound(InItem inItem, EInboundProtocol protocol, bool bSocks)
@@ -563,13 +560,14 @@ namespace ServiceLib.Services.CoreConfig
{
Logging.SaveLog(_tag, ex);
}
return 0;
return await Task.FromResult(0);
}
private async Task<int> GenOutbound(ProfileItem node, Outbounds4Ray outbound)
{
try
{
var muxEnabled = _config.CoreBasicItem.MuxEnabled;
switch (node.ConfigType)
{
case EConfigType.VMess:
@@ -610,7 +608,7 @@ namespace ServiceLib.Services.CoreConfig
usersItem.security = Global.DefaultSecurity;
}
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
await GenOutboundMux(node, outbound, muxEnabled, muxEnabled);
outbound.settings.servers = null;
break;
@@ -635,7 +633,7 @@ namespace ServiceLib.Services.CoreConfig
serversItem.ota = false;
serversItem.level = 1;
await GenOutboundMux(node, outbound, false);
await GenOutboundMux(node, outbound);
outbound.settings.vnext = null;
break;
@@ -671,7 +669,7 @@ namespace ServiceLib.Services.CoreConfig
serversItem.users = new List<SocksUsersItem4Ray>() { socksUsersItem };
}
await GenOutboundMux(node, outbound, false);
await GenOutboundMux(node, outbound);
outbound.settings.vnext = null;
break;
@@ -705,22 +703,15 @@ namespace ServiceLib.Services.CoreConfig
usersItem.email = Global.UserEMail;
usersItem.encryption = node.Security;
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
if (node.StreamSecurity == Global.StreamSecurityReality || node.StreamSecurity == Global.StreamSecurity)
if (node.Flow.IsNullOrEmpty())
{
if (Utils.IsNotEmpty(node.Flow))
{
usersItem.flow = node.Flow;
await GenOutboundMux(node, outbound, false);
}
await GenOutboundMux(node, outbound, muxEnabled, muxEnabled);
}
if (node.StreamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.Flow))
else
{
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
usersItem.flow = node.Flow;
await GenOutboundMux(node, outbound, false, muxEnabled);
}
outbound.settings.servers = null;
break;
}
@@ -743,7 +734,7 @@ namespace ServiceLib.Services.CoreConfig
serversItem.ota = false;
serversItem.level = 1;
await GenOutboundMux(node, outbound, false);
await GenOutboundMux(node, outbound);
outbound.settings.vnext = null;
break;
@@ -760,28 +751,30 @@ namespace ServiceLib.Services.CoreConfig
return 0;
}
private async Task<int> GenOutboundMux(ProfileItem node, Outbounds4Ray outbound, bool enabled)
private async Task<int> GenOutboundMux(ProfileItem node, Outbounds4Ray outbound, bool enabledTCP = false, bool enabledUDP = false)
{
try
{
if (enabled)
outbound.mux.enabled = false;
outbound.mux.concurrency = -1;
if (enabledTCP)
{
outbound.mux.enabled = true;
outbound.mux.concurrency = _config.Mux4RayItem.Concurrency;
}
else if (enabledUDP)
{
outbound.mux.enabled = true;
outbound.mux.xudpConcurrency = _config.Mux4RayItem.XudpConcurrency;
outbound.mux.xudpProxyUDP443 = _config.Mux4RayItem.XudpProxyUDP443;
}
else
{
outbound.mux.enabled = false;
outbound.mux.concurrency = -1;
}
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return 0;
return await Task.FromResult(0);
}
private async Task<int> GenBoundStreamSettings(ProfileItem node, Outbounds4Ray outbound)
@@ -931,7 +924,7 @@ namespace ServiceLib.Services.CoreConfig
}
streamSettings.xhttpSettings = xhttpSettings;
await GenOutboundMux(node, outbound, false);
await GenOutboundMux(node, outbound);
break;
//h2
@@ -1041,9 +1034,13 @@ namespace ServiceLib.Services.CoreConfig
//Outbound Freedom domainStrategy
if (Utils.IsNotEmpty(domainStrategy4Freedom))
{
var outbound = v2rayConfig.outbounds[1];
outbound.settings.domainStrategy = domainStrategy4Freedom;
outbound.settings.userLevel = 0;
var outbound = v2rayConfig.outbounds.FirstOrDefault(t => t is { protocol: "freedom", tag: Global.DirectTag });
if (outbound != null)
{
outbound.settings = new();
outbound.settings.domainStrategy = domainStrategy4Freedom;
outbound.settings.userLevel = 0;
}
}
var obj = JsonUtils.ParseJson(normalDNS);
@@ -1106,12 +1103,12 @@ namespace ServiceLib.Services.CoreConfig
servers.AsArray().Add(JsonUtils.SerializeToNode(dnsServer));
}
}
return 0;
return await Task.FromResult(0);
}
private async Task<int> GenStatistic(V2rayConfig v2rayConfig)
{
if (_config.GuiItem.EnableStatistics)
if (_config.GuiItem.EnableStatistics || _config.GuiItem.DisplayRealTimeSpeed)
{
string tag = EInboundProtocol.api.ToString();
Metrics4Ray apiObj = new();
@@ -1153,7 +1150,7 @@ namespace ServiceLib.Services.CoreConfig
v2rayConfig.routing.rules.Add(apiRoutingRule);
}
}
return 0;
return await Task.FromResult(0);
}
private async Task<int> GenMoreOutbounds(ProfileItem node, V2rayConfig v2rayConfig)
@@ -1170,9 +1167,9 @@ namespace ServiceLib.Services.CoreConfig
{
fragment = new()
{
packets = "tlshello",
length = "100-200",
interval = "10-20"
packets = _config.Fragment4RayItem?.Packets,
length = _config.Fragment4RayItem?.Length,
interval = _config.Fragment4RayItem?.Interval
}
}
};

View File

@@ -13,6 +13,7 @@ namespace ServiceLib.Services
public event EventHandler<RetResult>? UpdateCompleted;
public event ErrorEventHandler? Error;
private static readonly string _tag = "DownloadService";
public async Task<int> DownloadDataAsync(string url, WebProxy webProxy, int downloadTimeout, Action<bool, string> updateFunc)

View File

@@ -25,6 +25,7 @@ namespace ServiceLib.ViewModels
BrowseServerCmd = ReactiveCommand.CreateFromTask(async () =>
{
_updateView?.Invoke(EViewAction.BrowseServer, null);
await Task.CompletedTask;
});
EditServerCmd = ReactiveCommand.CreateFromTask(async () =>
{
@@ -109,6 +110,7 @@ namespace ServiceLib.ViewModels
{
NoticeHandler.Instance.Enqueue(ResUI.FailedReadConfiguration);
}
await Task.CompletedTask;
}
}
}

View File

@@ -154,7 +154,7 @@ namespace ServiceLib.ViewModels
ProcUtils.ProcessStart(upgradeFileName, Global.RebootAs, Utils.StartupPath());
}
}
service?.Shutdown();
service?.Shutdown(true);
}
else
{
@@ -176,7 +176,7 @@ namespace ServiceLib.ViewModels
FileManager.CopyDirectory(configDir, configDirTemp, false, "cache.db");
var ret = FileManager.CreateFromDirectory(configDirZipTemp, fileName);
Directory.Delete(configDirZipTemp, true);
return ret;
return await Task.FromResult(ret);
}
}
}

View File

@@ -259,7 +259,7 @@ namespace ServiceLib.ViewModels
}
else
{
FileManager.ZipExtractToFile(fileName, toPath, _config.GuiItem.IgnoreGeoUpdateCore ? "geo" : "");
FileManager.ZipExtractToFile(fileName, toPath, "geo");
}
if (Utils.IsNonWindows())

View File

@@ -48,7 +48,7 @@ namespace ServiceLib.ViewModels
await ClashConnectionClose(true);
});
Init();
_ = Init();
}
private async Task Init()
@@ -73,6 +73,7 @@ namespace ServiceLib.ViewModels
Task.Delay(1000).Wait();
}
});
await Task.CompletedTask;
}
private async Task GetClashConnections()

View File

@@ -90,13 +90,13 @@ namespace ServiceLib.ViewModels
y => y == true)
.Subscribe(c => { _config.ClashUIItem.ProxiesAutoRefresh = AutoRefresh; });
Init();
_ = Init();
}
private async Task Init()
{
await ProxiesReload();
DelayTestTask();
_ = DelayTestTask();
}
private async Task DoRulemodeSelected(bool c)
@@ -265,7 +265,7 @@ namespace ServiceLib.ViewModels
return;
}
_proxies.TryGetValue(name, out ProxiesItem proxy);
_proxies.TryGetValue(name, out var proxy);
if (proxy == null || proxy.all == null)
{
return;
@@ -316,7 +316,7 @@ namespace ServiceLib.ViewModels
{
if (_proxies is null)
return null;
_proxies.TryGetValue(name, out ProxiesItem proxy2);
_proxies.TryGetValue(name, out var proxy2);
if (proxy2 != null)
{
return proxy2;
@@ -399,6 +399,7 @@ namespace ServiceLib.ViewModels
_updateView?.Invoke(EViewAction.DispatcherProxiesDelayTest, new SpeedTestResult() { IndexId = item.Name, Delay = result });
});
await Task.CompletedTask;
}
public void ProxiesDelayTestResult(SpeedTestResult result)
@@ -434,7 +435,7 @@ namespace ServiceLib.ViewModels
public async Task DelayTestTask()
{
var lastTime = DateTime.Now;
Task.Run(async () =>
_ = Task.Run(async () =>
{
while (true)
{
@@ -457,6 +458,7 @@ namespace ServiceLib.ViewModels
lastTime = dtNow;
}
});
await Task.CompletedTask;
}
#endregion task

View File

@@ -32,15 +32,17 @@ namespace ServiceLib.ViewModels
ImportDefConfig4V2rayCmd = ReactiveCommand.CreateFromTask(async () =>
{
normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName);
await Task.CompletedTask;
});
ImportDefConfig4SingboxCmd = ReactiveCommand.CreateFromTask(async () =>
{
normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName);
tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
await Task.CompletedTask;
});
Init();
_ = Init();
}
private async Task Init()

View File

@@ -63,6 +63,8 @@ namespace ServiceLib.ViewModels
#endregion Menu
private bool _hasNextReloadJob = false;
#region Init
public MainWindowViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
@@ -204,7 +206,7 @@ namespace ServiceLib.ViewModels
#endregion WhenAnyValue && ReactiveCommand
Init();
_ = Init();
}
private async Task Init()
@@ -217,11 +219,12 @@ namespace ServiceLib.ViewModels
await CoreHandler.Instance.Init(_config, UpdateHandler);
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
if (_config.GuiItem.EnableStatistics)
if (_config.GuiItem.EnableStatistics || _config.GuiItem.DisplayRealTimeSpeed)
{
await StatisticsHandler.Instance.Init(_config, UpdateStatisticsHandler);
}
BlReloadEnabled = true;
await Reload();
await AutoHideStartup();
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
@@ -249,7 +252,7 @@ namespace ServiceLib.ViewModels
RefreshServers();
if (indexIdOld != _config.IndexId)
{
Reload();
_ = Reload();
}
if (_config.UiItem.EnableAutoAdjustMainLvColWidth)
{
@@ -269,16 +272,13 @@ namespace ServiceLib.ViewModels
public void SetStatisticsResult(ServerSpeedItem update)
{
try
if (_config.GuiItem.DisplayRealTimeSpeed)
{
Locator.Current.GetService<StatusBarViewModel>()?.UpdateStatistics(update);
if ((update.ProxyUp + update.ProxyDown) > 0 && DateTime.Now.Second % 9 == 0)
{
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
}
}
catch
if (_config.GuiItem.EnableStatistics && (update.ProxyUp + update.ProxyDown) > 0 && DateTime.Now.Second % 9 == 0)
{
Locator.Current.GetService<ProfilesViewModel>()?.UpdateStatistics(update);
}
}
@@ -303,7 +303,7 @@ namespace ServiceLib.ViewModels
{
if (!blWindowsShutDown)
{
_updateView?.Invoke(EViewAction.Shutdown, null);
_updateView?.Invoke(EViewAction.Shutdown, false);
}
}
}
@@ -329,9 +329,9 @@ namespace ServiceLib.ViewModels
_updateView?.Invoke(EViewAction.ShowHideWindow, blShow);
}
public void Shutdown()
public void Shutdown(bool byUser)
{
_updateView?.Invoke(EViewAction.Shutdown, null);
_updateView?.Invoke(EViewAction.Shutdown, byUser);
}
#endregion Actions
@@ -403,6 +403,7 @@ namespace ServiceLib.ViewModels
public async Task AddServerViaScanAsync()
{
_updateView?.Invoke(EViewAction.ScanScreenTask, null);
await Task.CompletedTask;
}
public async Task ScanScreenResult(byte[]? bytes)
@@ -414,6 +415,7 @@ namespace ServiceLib.ViewModels
public async Task AddServerViaImageAsync()
{
_updateView?.Invoke(EViewAction.ScanImageTask, null);
await Task.CompletedTask;
}
public async Task ScanImageResult(string fileName)
@@ -527,6 +529,7 @@ namespace ServiceLib.ViewModels
{
ProcUtils.ProcessStart("open", path);
}
await Task.CompletedTask;
}
#endregion Setting
@@ -535,19 +538,33 @@ namespace ServiceLib.ViewModels
public async Task Reload()
{
//If there are unfinished reload job, marked with next job.
if (!BlReloadEnabled)
{
_hasNextReloadJob = true;
return;
}
BlReloadEnabled = false;
await LoadCore();
Locator.Current.GetService<StatusBarViewModel>()?.TestServerAvailability();
await SysProxyHandler.UpdateSysProxy(_config, false);
Locator.Current.GetService<StatusBarViewModel>()?.TestServerAvailability();
_updateView?.Invoke(EViewAction.DispatcherReload, null);
BlReloadEnabled = true;
if (_hasNextReloadJob)
{
_hasNextReloadJob = false;
await Reload();
}
}
public void ReloadResult()
{
// BlReloadEnabled = true;
//Locator.Current.GetService<StatusBarViewModel>()?.ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, false);
BlReloadEnabled = true;
ShowClashUI = _config.IsRunningCore(ECoreType.sing_box);
if (ShowClashUI)
{
@@ -558,16 +575,8 @@ namespace ServiceLib.ViewModels
private async Task LoadCore()
{
//if (_config.tunModeItem.enableTun)
//{
// Task.Delay(1000).Wait();
// WindowsUtils.RemoveTunDevice();
//}
await Task.Run(async () =>
{
var node = await ConfigHandler.GetDefaultServer(_config);
await CoreHandler.Instance.LoadCore(node);
});
var node = await ConfigHandler.GetDefaultServer(_config);
await CoreHandler.Instance.LoadCore(node);
}
public async Task CloseCore()
@@ -582,6 +591,7 @@ namespace ServiceLib.ViewModels
{
ShowHideWindow(false);
}
await Task.CompletedTask;
}
#endregion core job

View File

@@ -59,14 +59,14 @@ namespace ServiceLib.ViewModels
{
return;
}
_blLockShow = true;
if (!_config.UiItem.ShowInTaskbar)
{
await Task.Delay(1000);
return;
}
await Task.Delay(100);
_blLockShow = true;
await Task.Delay(500);
var txt = string.Join("", _queueMsg.ToArray());
await _updateView?.Invoke(EViewAction.DispatcherShowMsg, txt);
@@ -105,6 +105,7 @@ namespace ServiceLib.ViewModels
{
_queueMsg.Enqueue(Environment.NewLine);
}
await Task.CompletedTask;
}
public void ClearMsg()

View File

@@ -49,7 +49,7 @@ namespace ServiceLib.ViewModels
[Reactive] public bool AutoRun { get; set; }
[Reactive] public bool EnableStatistics { get; set; }
[Reactive] public bool KeepOlderDedupl { get; set; }
[Reactive] public bool IgnoreGeoUpdateCore { get; set; }
[Reactive] public bool DisplayRealTimeSpeed { get; set; }
[Reactive] public bool EnableAutoAdjustMainLvColWidth { get; set; }
[Reactive] public bool EnableUpdateSubOnlyRemarksExist { get; set; }
[Reactive] public bool EnableSecurityProtocolTls13 { get; set; }
@@ -115,7 +115,7 @@ namespace ServiceLib.ViewModels
await SaveSettingAsync();
});
Init();
_ = Init();
}
private async Task Init()
@@ -164,8 +164,8 @@ namespace ServiceLib.ViewModels
AutoRun = _config.GuiItem.AutoRun;
EnableStatistics = _config.GuiItem.EnableStatistics;
DisplayRealTimeSpeed = _config.GuiItem.DisplayRealTimeSpeed;
KeepOlderDedupl = _config.GuiItem.KeepOlderDedupl;
IgnoreGeoUpdateCore = _config.GuiItem.IgnoreGeoUpdateCore;
EnableAutoAdjustMainLvColWidth = _config.UiItem.EnableAutoAdjustMainLvColWidth;
EnableUpdateSubOnlyRemarksExist = _config.UiItem.EnableUpdateSubOnlyRemarksExist;
EnableSecurityProtocolTls13 = _config.GuiItem.EnableSecurityProtocolTls13;
@@ -261,6 +261,7 @@ namespace ServiceLib.ViewModels
break;
}
});
await Task.CompletedTask;
}
private async Task SaveSettingAsync()
@@ -272,6 +273,7 @@ namespace ServiceLib.ViewModels
return;
}
var needReboot = (EnableStatistics != _config.GuiItem.EnableStatistics
|| DisplayRealTimeSpeed != _config.GuiItem.DisplayRealTimeSpeed
|| EnableDragDropSort != _config.UiItem.EnableDragDropSort
|| EnableHWA != _config.GuiItem.EnableHWA
|| CurrentFontFamily != _config.UiItem.CurrentFontFamily
@@ -317,8 +319,8 @@ namespace ServiceLib.ViewModels
_config.GuiItem.AutoRun = AutoRun;
_config.GuiItem.EnableStatistics = EnableStatistics;
_config.GuiItem.DisplayRealTimeSpeed = DisplayRealTimeSpeed;
_config.GuiItem.KeepOlderDedupl = KeepOlderDedupl;
_config.GuiItem.IgnoreGeoUpdateCore = IgnoreGeoUpdateCore;
_config.UiItem.EnableAutoAdjustMainLvColWidth = EnableAutoAdjustMainLvColWidth;
_config.UiItem.EnableUpdateSubOnlyRemarksExist = EnableUpdateSubOnlyRemarksExist;
_config.GuiItem.EnableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
@@ -410,6 +412,7 @@ namespace ServiceLib.ViewModels
}
item.CoreType = (ECoreType)Enum.Parse(typeof(ECoreType), type);
}
await Task.CompletedTask;
}
}
}

View File

@@ -231,7 +231,7 @@ namespace ServiceLib.ViewModels
MessageBus.Current.Listen<string>(EMsgCommand.RefreshProfiles.ToString()).Subscribe(OnNext);
}
Init();
_ = Init();
}
private async Task Init()
@@ -360,7 +360,7 @@ namespace ServiceLib.ViewModels
public async Task RefreshServersBiz()
{
var lstModel = await AppHandler.Instance.ProfileItemsEx(_config.SubIndexId, _serverFilter);
var lstModel = await GetProfileItemsEx(_config.SubIndexId, _serverFilter);
_lstProfile = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(lstModel)) ?? [];
_profileItems.Clear();
@@ -399,6 +399,45 @@ namespace ServiceLib.ViewModels
}
}
private async Task<List<ProfileItemModel>?> GetProfileItemsEx(string subid, string filter)
{
var lstModel = await AppHandler.Instance.ProfileItems(_config.SubIndexId, filter);
await ConfigHandler.SetDefaultServer(_config, lstModel);
var lstServerStat = (_config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
var lstProfileExs = await ProfileExHandler.Instance.GetProfileExs();
lstModel = (from t in lstModel
join t2 in lstServerStat on t.IndexId equals t2.IndexId into t2b
from t22 in t2b.DefaultIfEmpty()
join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b
from t33 in t3b.DefaultIfEmpty()
select new ProfileItemModel
{
IndexId = t.IndexId,
ConfigType = t.ConfigType,
Remarks = t.Remarks,
Address = t.Address,
Port = t.Port,
Security = t.Security,
Network = t.Network,
StreamSecurity = t.StreamSecurity,
Subid = t.Subid,
SubRemarks = t.SubRemarks,
IsActive = t.IndexId == _config.IndexId,
Sort = t33 == null ? 0 : t33.Sort,
Delay = t33 == null ? 0 : t33.Delay,
DelayVal = t33?.Delay != 0 ? $"{t33?.Delay} {Global.DelayUnit}" : string.Empty,
SpeedVal = t33?.Speed != 0 ? $"{t33?.Speed} {Global.SpeedUnit}" : string.Empty,
TodayDown = t22 == null ? "" : Utils.HumanFy(t22.TodayDown),
TodayUp = t22 == null ? "" : Utils.HumanFy(t22.TodayUp),
TotalDown = t22 == null ? "" : Utils.HumanFy(t22.TotalDown),
TotalUp = t22 == null ? "" : Utils.HumanFy(t22.TotalUp)
}).OrderBy(t => t.Sort).ToList();
return lstModel;
}
#endregion Servers && Groups
#region Add Servers

View File

@@ -2,6 +2,8 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace ServiceLib.ViewModels
{
@@ -189,7 +191,13 @@ namespace ServiceLib.ViewModels
}
if (lst.Count > 0)
{
await _updateView?.Invoke(EViewAction.SetClipboardData, JsonUtils.Serialize(lst));
var options = new JsonSerializerOptions
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
await _updateView?.Invoke(EViewAction.SetClipboardData, JsonUtils.Serialize(lst, options));
}
}
@@ -249,7 +257,7 @@ namespace ServiceLib.ViewModels
return;
}
string result = Utils.LoadResource(fileName);
var result = Utils.LoadResource(fileName);
if (Utils.IsNullOrEmpty(result))
{
return;

View File

@@ -67,7 +67,7 @@ namespace ServiceLib.ViewModels
await SaveRoutingAsync();
});
Init();
_ = Init();
}
private async Task Init()

View File

@@ -32,6 +32,7 @@ namespace ServiceLib.ViewModels
public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }
public ReactiveCommand<Unit, Unit> SubUpdateCmd { get; }
public ReactiveCommand<Unit, Unit> SubUpdateViaProxyCmd { get; }
public ReactiveCommand<Unit, Unit> CopyProxyCmdToClipboardCmd { get; }
public ReactiveCommand<Unit, Unit> NotifyLeftClickCmd { get; }
#region System Proxy
@@ -48,18 +49,6 @@ namespace ServiceLib.ViewModels
[Reactive]
public bool BlSystemProxyPac { get; set; }
[Reactive]
public bool BlNotSystemProxyClear { get; set; }
[Reactive]
public bool BlNotSystemProxySet { get; set; }
[Reactive]
public bool BlNotSystemProxyNothing { get; set; }
[Reactive]
public bool BlNotSystemProxyPac { get; set; }
public ReactiveCommand<Unit, Unit> SystemProxyClearCmd { get; }
public ReactiveCommand<Unit, Unit> SystemProxySetCmd { get; }
public ReactiveCommand<Unit, Unit> SystemProxyNothingCmd { get; }
@@ -140,9 +129,15 @@ namespace ServiceLib.ViewModels
y => y == true)
.Subscribe(async c => await DoEnableTun(c));
CopyProxyCmdToClipboardCmd = ReactiveCommand.CreateFromTask(async () =>
{
await CopyProxyCmdToClipboard();
});
NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () =>
{
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(null);
await Task.CompletedTask;
});
AddServerViaClipboardCmd = ReactiveCommand.CreateFromTask(async () =>
@@ -186,7 +181,7 @@ namespace ServiceLib.ViewModels
{
InitUpdateView(updateView);
}
Init();
_ = Init();
}
private async Task Init()
@@ -210,6 +205,23 @@ namespace ServiceLib.ViewModels
await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null);
}
private async Task CopyProxyCmdToClipboard()
{
var cmd = Utils.IsWindows() ? "set" : "export";
var address = $"{Global.Loopback}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)}";
var sb = new StringBuilder();
sb.AppendLine($"{cmd} http_proxy={Global.HttpProtocol}{address}");
sb.AppendLine($"{cmd} https_proxy={Global.HttpProtocol}{address}");
sb.AppendLine($"{cmd} all_proxy={Global.Socks5Protocol}{address}");
sb.AppendLine("");
sb.AppendLine($"{cmd} HTTP_PROXY={Global.HttpProtocol}{address}");
sb.AppendLine($"{cmd} HTTPS_PROXY={Global.HttpProtocol}{address}");
sb.AppendLine($"{cmd} ALL_PROXY={Global.Socks5Protocol}{address}");
await _updateView?.Invoke(EViewAction.SetClipboardData, sb.ToString());
}
private async Task AddServerViaClipboard()
{
var service = Locator.Current.GetService<MainWindowViewModel>();
@@ -333,11 +345,6 @@ namespace ServiceLib.ViewModels
BlSystemProxyNothing = (type == ESysProxyType.Unchanged);
BlSystemProxyPac = (type == ESysProxyType.Pac);
BlNotSystemProxyClear = !BlSystemProxyClear;
BlNotSystemProxySet = !BlSystemProxySet;
BlNotSystemProxyNothing = !BlSystemProxyNothing;
BlNotSystemProxyPac = !BlSystemProxyPac;
if (blChange)
{
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
@@ -417,10 +424,12 @@ namespace ServiceLib.ViewModels
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
return;
}
//else if (Utils.IsLinux())
//{
// NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordIsEmpty);
//}
else if (Utils.IsOSX())
{
_config.TunModeItem.EnableTun = false;
NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordIsEmpty);
return;
}
}
await ConfigHandler.SaveConfig(_config);
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
@@ -470,12 +479,19 @@ namespace ServiceLib.ViewModels
{
InboundLanDisplay = $"{ResUI.LabLAN}:{Global.None}";
}
await Task.CompletedTask;
}
public void UpdateStatistics(ServerSpeedItem update)
{
SpeedProxyDisplay = string.Format(ResUI.SpeedDisplayText, Global.ProxyTag, Utils.HumanFy(update.ProxyUp), Utils.HumanFy(update.ProxyDown));
SpeedDirectDisplay = string.Format(ResUI.SpeedDisplayText, Global.DirectTag, Utils.HumanFy(update.DirectUp), Utils.HumanFy(update.DirectDown));
try
{
SpeedProxyDisplay = string.Format(ResUI.SpeedDisplayText, Global.ProxyTag, Utils.HumanFy(update.ProxyUp), Utils.HumanFy(update.ProxyDown));
SpeedDirectDisplay = string.Format(ResUI.SpeedDisplayText, Global.DirectTag, Utils.HumanFy(update.DirectUp), Utils.HumanFy(update.DirectDown));
}
catch
{
}
}
#endregion UI

View File

@@ -48,7 +48,7 @@ namespace ServiceLib.ViewModels
await _updateView?.Invoke(EViewAction.ShareSub, SelectedSource?.Url);
}, canEditRemove);
Init();
_ = Init();
}
private async Task Init()

View File

@@ -3,12 +3,13 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:semi="https://irihi.tech/semi"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
x:DataType="vms:StatusBarViewModel"
RequestedThemeVariant="Default">
<Application.Styles>
<semi:SemiTheme />
<StyleInclude Source="Assets/GlobalStyles.axaml" />
<StyleInclude Source="avares://Semi.Avalonia/Themes/Index.axaml" />
<StyleInclude Source="avares://Semi.Avalonia.DataGrid/Index.axaml" />
<StyleInclude Source="avares://DialogHost.Avalonia/Styles.xaml" />
</Application.Styles>
@@ -31,38 +32,26 @@
<NativeMenuItem
Command="{Binding SystemProxyClearCmd}"
Header="{x:Static resx:ResUI.menuSystemProxyClear}"
IsVisible="{Binding BlNotSystemProxyClear}" />
<NativeMenuItem
Command="{Binding SystemProxyClearCmd}"
Header="{x:Static resx:ResUI.menuSystemProxyClear}"
Icon="/Assets/NotifyIcon1.ico"
IsVisible="{Binding BlSystemProxyClear}" />
IsChecked="{Binding BlSystemProxyClear}"
ToggleType="Radio" />
<NativeMenuItem
Command="{Binding SystemProxySetCmd}"
Header="{x:Static resx:ResUI.menuSystemProxySet}"
IsVisible="{Binding BlNotSystemProxySet}" />
<NativeMenuItem
Command="{Binding SystemProxySetCmd}"
Header="{x:Static resx:ResUI.menuSystemProxySet}"
Icon="/Assets/NotifyIcon2.ico"
IsVisible="{Binding BlSystemProxySet}" />
IsChecked="{Binding BlSystemProxySet}"
ToggleType="Radio" />
<NativeMenuItem
Command="{Binding SystemProxyNothingCmd}"
Header="{x:Static resx:ResUI.menuSystemProxyNothing}"
IsVisible="{Binding BlNotSystemProxyNothing}" />
<NativeMenuItem
Command="{Binding SystemProxyNothingCmd}"
Header="{x:Static resx:ResUI.menuSystemProxyNothing}"
Icon="/Assets/NotifyIcon3.ico"
IsVisible="{Binding BlSystemProxyNothing}" />
IsChecked="{Binding BlSystemProxyNothing}"
ToggleType="Radio" />
<NativeMenuItemSeparator />
<NativeMenuItem Click="MenuAddServerViaClipboardClick" Header="{x:Static resx:ResUI.menuAddServerViaClipboard}" />
<NativeMenuItem Header="{x:Static resx:ResUI.menuAddServerViaScan}" IsVisible="False" />
<NativeMenuItem Command="{Binding SubUpdateCmd}" Header="{x:Static resx:ResUI.menuSubUpdate}" />
<NativeMenuItem Command="{Binding SubUpdateViaProxyCmd}" Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" />
<NativeMenuItemSeparator />
<NativeMenuItem Command="{Binding CopyProxyCmdToClipboardCmd}" Header="{x:Static resx:ResUI.menuCopyProxyCmdToClipboard}" />
<NativeMenuItemSeparator />
<NativeMenuItem Command="{Binding NotifyLeftClickCmd}" Header="{x:Static resx:ResUI.menuShowOrHideMainWindow}" />
<NativeMenuItem Click="MenuExit_Click" Header="{x:Static resx:ResUI.menuExit}" />
</NativeMenu>

View File

@@ -71,12 +71,8 @@ public partial class App : Application
private async void MenuExit_Click(object? sender, EventArgs e)
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) await service.MyAppExitAsync(false);
desktop.Shutdown();
}
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) await service.MyAppExitAsync(true);
service?.Shutdown(true);
}
}

View File

@@ -40,6 +40,12 @@ namespace v2rayN.Desktop.Common
public static WindowIcon GetAppIcon(ESysProxyType sysProxyType)
{
var index = (int)sysProxyType + 1;
var fileName = Utils.GetPath($"NotifyIcon{index}.ico");
if (File.Exists(fileName))
{
return new(fileName);
}
var uri = new Uri(Path.Combine(Global.AvaAssets, $"NotifyIcon{index}.ico"));
using var bitmap = new Bitmap(AssetLoader.Open(uri));
return new(bitmap);

View File

@@ -17,13 +17,11 @@ namespace v2rayN.Desktop.Common
public static async Task<string?> OpenFileDialog(Window owner, FilePickerFileType? filter)
{
var topLevel = TopLevel.GetTopLevel(owner);
if (topLevel == null)
{
return null;
}
var sp = GetStorageProvider(owner);
if (sp is null) return null;
// Start async operation to open the dialog.
var files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
var files = await sp.OpenFilePickerAsync(new FilePickerOpenOptions
{
AllowMultiple = false,
FileTypeFilter = filter is null ? [FilePickerFileTypes.All, FilePickerFileTypes.ImagePng] : [filter]
@@ -34,17 +32,21 @@ namespace v2rayN.Desktop.Common
public static async Task<string?> SaveFileDialog(Window owner, string filter)
{
var topLevel = TopLevel.GetTopLevel(owner);
if (topLevel == null)
{
return null;
}
var sp = GetStorageProvider(owner);
if (sp is null) return null;
// Start async operation to open the dialog.
var files = await topLevel.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
var files = await sp.SaveFilePickerAsync(new FilePickerSaveOptions
{
});
return files?.TryGetLocalPath();
}
private static IStorageProvider? GetStorageProvider(Window owner)
{
var topLevel = TopLevel.GetTopLevel(owner);
return topLevel?.StorageProvider;
}
}
}

View File

@@ -6,14 +6,14 @@ using Avalonia.Media;
using Avalonia.Styling;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Semi.Avalonia;
using System.Reactive.Linq;
namespace v2rayN.Desktop.ViewModels
{
public class ThemeSettingViewModel : MyReactiveObject
{
[Reactive] public bool ColorModeDark { get; set; }
[Reactive] public bool FollowSystemTheme { get; set; }
[Reactive] public string CurrentTheme { get; set; }
[Reactive] public int CurrentFontSize { get; set; }
@@ -31,32 +31,21 @@ namespace v2rayN.Desktop.ViewModels
{
ModifyTheme();
ModifyFontFamily();
ModifyFontSize();
}
private void BindingUI()
{
ColorModeDark = _config.UiItem.ColorModeDark;
FollowSystemTheme = _config.UiItem.FollowSystemTheme;
CurrentTheme = _config.UiItem.CurrentTheme;
CurrentFontSize = _config.UiItem.CurrentFontSize;
CurrentLanguage = _config.UiItem.CurrentLanguage;
this.WhenAnyValue(x => x.ColorModeDark)
this.WhenAnyValue(x => x.CurrentTheme)
.Subscribe(c =>
{
if (_config.UiItem.ColorModeDark != ColorModeDark)
if (_config.UiItem.CurrentTheme != CurrentTheme)
{
_config.UiItem.ColorModeDark = ColorModeDark;
ModifyTheme();
ConfigHandler.SaveConfig(_config);
}
});
this.WhenAnyValue(x => x.FollowSystemTheme,
y => y == true)
.Subscribe(c =>
{
if (_config.UiItem.FollowSystemTheme != FollowSystemTheme)
{
_config.UiItem.FollowSystemTheme = FollowSystemTheme;
_config.UiItem.CurrentTheme = CurrentTheme;
ModifyTheme();
ConfigHandler.SaveConfig(_config);
}
@@ -67,11 +56,10 @@ namespace v2rayN.Desktop.ViewModels
y => y > 0)
.Subscribe(c =>
{
if (CurrentFontSize >= Global.MinFontSize)
if (_config.UiItem.CurrentFontSize != CurrentFontSize && CurrentFontSize >= Global.MinFontSize)
{
_config.UiItem.CurrentFontSize = CurrentFontSize;
double size = CurrentFontSize;
ModifyFontSize(size);
ModifyFontSize();
ConfigHandler.SaveConfig(_config);
}
});
@@ -96,12 +84,24 @@ namespace v2rayN.Desktop.ViewModels
var app = Application.Current;
if (app is not null)
{
app.RequestedThemeVariant = FollowSystemTheme ? ThemeVariant.Default : (ColorModeDark ? ThemeVariant.Dark : ThemeVariant.Light);
app.RequestedThemeVariant = CurrentTheme switch
{
nameof(ETheme.Dark) => ThemeVariant.Dark,
nameof(ETheme.Light) => ThemeVariant.Light,
nameof(ETheme.Aquatic) => SemiTheme.Aquatic,
nameof(ETheme.Desert) => SemiTheme.Desert,
nameof(ETheme.Dusk) => SemiTheme.Dusk,
nameof(ETheme.NightSky) => SemiTheme.NightSky,
_ => ThemeVariant.Default,
};
}
}
private void ModifyFontSize(double size)
private void ModifyFontSize()
{
double size = CurrentFontSize;
if (size < Global.MinFontSize) return;
Style style = new(x => Selectors.Or(
x.OfType<Button>(),
x.OfType<TextBox>(),

View File

@@ -5,25 +5,28 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
d:DesignHeight="450"
d:DesignWidth="800"
x:DataType="vms:BackupAndRestoreViewModel"
mc:Ignorable="d">
<UserControl.Styles>
<Style Selector="Button">
<Setter Property="MinWidth" Value="180" />
</Style>
</UserControl.Styles>
<DockPanel Classes="Margin8">
<DockPanel Classes="Margin8" DockPanel.Dock="Bottom">
<StackPanel Classes="Margin8" DockPanel.Dock="Bottom">
<TextBlock
Name="txtMsg"
HorizontalAlignment="Left"
Classes="Margin8" />
</DockPanel>
</StackPanel>
<StackPanel>
<Border
Margin="4"
VerticalAlignment="Center"
Theme="{StaticResource CardBorder}">
Theme="{DynamicResource CardBorder}">
<Grid
Classes="Margin8"
@@ -49,7 +52,10 @@
Classes="Margin8"
Content="{x:Static resx:ResUI.menuLocalBackup}" />
<Separator Grid.Row="2" Grid.ColumnSpan="2" />
<Separator
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2" />
<TextBlock
Grid.Row="3"
@@ -69,21 +75,21 @@
<Border
Margin="4"
VerticalAlignment="Center"
Theme="{StaticResource CardBorder}">
Theme="{DynamicResource CardBorder}">
<Grid
Classes="Margin8"
ColumnDefinitions="300,200"
RowDefinitions="Auto,Auto,Auto,Auto,Auto">
<StackPanel Orientation="Horizontal">
<TextBlock
Grid.Row="0"
Grid.Column="0"
Classes="Margin8"
Text="{x:Static resx:ResUI.menuRemoteBackupAndRestore}" />
<StackPanel
Grid.Row="0"
Grid.Column="0"
Orientation="Horizontal">
<TextBlock Classes="Margin8" Text="{x:Static resx:ResUI.menuRemoteBackupAndRestore}" />
<Button
Width="30"
Height="30"
MinWidth="30"
Margin="10,0"
Theme="{DynamicResource BorderlessButton}">
<Button.Content>
@@ -184,7 +190,10 @@
Classes="Margin8"
Content="{x:Static resx:ResUI.menuRemoteBackup}" />
<Separator Grid.Row="2" Grid.ColumnSpan="3" />
<Separator
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2" />
<TextBlock
Grid.Row="3"
Grid.Column="0"

View File

@@ -9,7 +9,12 @@ namespace v2rayN.Desktop.Views
{
public partial class BackupAndRestoreView : ReactiveUserControl<BackupAndRestoreViewModel>
{
private Window _window;
private Window? _window;
public BackupAndRestoreView()
{
InitializeComponent();
}
public BackupAndRestoreView(Window window)
{

View File

@@ -35,11 +35,16 @@
Content="{x:Static resx:ResUI.menuCheckUpdate}" />
</StackPanel>
<StackPanel>
<Border
Margin="4"
VerticalAlignment="Center"
Theme="{DynamicResource CardBorder}">
<ListBox
x:Name="lstCheckUpdates"
BorderThickness="1"
ItemsSource="{Binding CheckUpdateModels}">
ItemsSource="{Binding CheckUpdateModels}"
Theme="{StaticResource ButtonRadioGroupListBox}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
@@ -47,12 +52,7 @@
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border
Width="500"
Height="80"
Margin="-8"
VerticalAlignment="Center"
Theme="{StaticResource CardBorder}">
<Panel Width="500" VerticalAlignment="Center">
<Grid ColumnDefinitions="1*,1*,3*" RowDefinitions="Auto">
<ToggleSwitch
x:Name="togAutoRefresh"
@@ -73,11 +73,10 @@
Text="{Binding Remarks}"
TextWrapping="WrapWithOverflow" />
</Grid>
</Border>
</Panel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
</StackPanel>
</Border>
</DockPanel>
</UserControl>

View File

@@ -28,7 +28,7 @@
Text="{x:Static resx:ResUI.menuRulemode}" />
<ComboBox
x:Name="cmbRulemode"
Width="80"
Width="100"
Margin="8,0">
<ComboBoxItem Content="{x:Static resx:ResUI.menuModeRule}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuModeGlobal}" />
@@ -41,7 +41,7 @@
Text="{x:Static resx:ResUI.TbSorting}" />
<ComboBox
x:Name="cmbSorting"
Width="60"
Width="100"
Margin="8,0">
<ComboBoxItem Content="{x:Static resx:ResUI.TbSortingDelay}" />
<ComboBoxItem Content="{x:Static resx:ResUI.TbSortingName}" />
@@ -95,7 +95,8 @@
<ListBox
x:Name="lstProxyGroups"
DockPanel.Dock="Left"
ItemsSource="{Binding ProxyGroups}">
ItemsSource="{Binding ProxyGroups}"
Theme="{StaticResource ButtonRadioGroupListBox}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
@@ -105,24 +106,25 @@
<DataTemplate>
<Border
Width="160"
Margin="-6"
Margin="-8,-4"
Padding="0"
Theme="{StaticResource CardBorder}">
<DockPanel>
<Grid Classes="Margin8" RowDefinitions="1*,8,1*">
<DockPanel Grid.Row="0">
<TextBlock DockPanel.Dock="Right" Text="{Binding Type}" />
<TextBlock Text="{Binding Name}" />
</DockPanel>
<TextBlock Grid.Row="2" Text="{Binding Now}" />
</Grid>
</DockPanel>
<Grid Classes="Margin8" RowDefinitions="1*,8,1*">
<DockPanel Grid.Row="0">
<TextBlock DockPanel.Dock="Right" Text="{Binding Type}" />
<TextBlock Text="{Binding Name}" />
</DockPanel>
<TextBlock Grid.Row="2" Text="{Binding Now}" />
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
<ListBox x:Name="lstProxyDetails" ItemsSource="{Binding ProxyDetails}">
<ListBox
x:Name="lstProxyDetails"
ItemsSource="{Binding ProxyDetails}"
Theme="{StaticResource ButtonRadioGroupListBox}">
<ItemsControl.ContextMenu>
<ContextMenu>
<MenuItem x:Name="menuProxiesDelaytestPart" Header="{x:Static resx:ResUI.menuProxiesDelaytestPart}" />
@@ -138,7 +140,7 @@
<DataTemplate>
<Border
Width="160"
Margin="-6"
Margin="-12,-4"
Padding="0"
Theme="{StaticResource CardBorder}">
<DockPanel>

View File

@@ -150,71 +150,20 @@
x:Name="tabMain1"
Grid.Row="2"
TabStripPlacement="Left">
<TabItem x:Name="tabMsgView1">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.MsgInformationTitle}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabClashProxies1">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.TbProxies}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabClashConnections1">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.TbConnections}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabMsgView1" Header="{x:Static resx:ResUI.MsgInformationTitle}" />
<TabItem x:Name="tabClashProxies1" Header="{x:Static resx:ResUI.TbProxies}" />
<TabItem x:Name="tabClashConnections1" Header="{x:Static resx:ResUI.TbConnections}" />
</TabControl>
</Grid>
<Grid x:Name="gridMain2" IsVisible="False">
<TabControl x:Name="tabMain2" TabStripPlacement="Left">
<TabItem x:Name="tabProfiles2">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.menuServers}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabMsgView2">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.MsgInformationTitle}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabClashProxies2">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.TbProxies}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabClashConnections2">
<TabItem.Header>
<StackPanel>
<TextBlock HorizontalAlignment="Center" Text="{x:Static resx:ResUI.TbConnections}" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem x:Name="tabProfiles2" Header="{x:Static resx:ResUI.menuServers}" />
<TabItem x:Name="tabMsgView2" Header="{x:Static resx:ResUI.MsgInformationTitle}" />
<TabItem x:Name="tabClashProxies2" Header="{x:Static resx:ResUI.TbProxies}" />
<TabItem x:Name="tabClashConnections2" Header="{x:Static resx:ResUI.TbConnections}" />
</TabControl>
</Grid>
</Grid>
</DockPanel>
</dialogHost:DialogHost>
</Window>

View File

@@ -223,6 +223,10 @@ namespace v2rayN.Desktop.Views
break;
case EViewAction.Shutdown:
if (obj != null && _blCloseByUser == false)
{
_blCloseByUser = (bool)obj;
}
StorageUI();
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{

View File

@@ -65,7 +65,7 @@
Margin="8,0"
HorizontalAlignment="Left"
IsChecked="True"
Theme="{StaticResource SimpleToggleSwitch}" />
Theme="{DynamicResource SimpleToggleSwitch}" />
<TextBlock
Margin="8,0"
VerticalAlignment="Center"
@@ -75,7 +75,7 @@
Margin="8,0"
HorizontalAlignment="Left"
IsChecked="True"
Theme="{StaticResource SimpleToggleSwitch}" />
Theme="{DynamicResource SimpleToggleSwitch}" />
</WrapPanel>
<TextBox
Name="txtMsg"

View File

@@ -114,8 +114,8 @@
Grid.ColumnSpan="2"
HorizontalAlignment="Left"
Classes="Margin8"
SelectionMode="Multiple"
Theme="{DynamicResource PureCardRadioGroupListBox}" />
SelectionMode="Multiple,Toggle"
Theme="{DynamicResource CardCheckGroupListBox}" />
<TextBlock
Grid.Row="6"
@@ -385,9 +385,9 @@
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsKeepOlderDedupl}" />
Text="{x:Static resx:ResUI.TbSettingsDisplayRealTimeSpeed}" />
<ToggleSwitch
x:Name="togKeepOlderDedupl"
x:Name="togDisplayRealTimeSpeed"
Grid.Row="3"
Grid.Column="1"
HorizontalAlignment="Left"
@@ -398,9 +398,9 @@
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsIgnoreGeoUpdateCore}" />
Text="{x:Static resx:ResUI.TbSettingsKeepOlderDedupl}" />
<ToggleSwitch
x:Name="togIgnoreGeoUpdateCore"
x:Name="togKeepOlderDedupl"
Grid.Row="4"
Grid.Column="1"
HorizontalAlignment="Left"
@@ -714,102 +714,100 @@
</TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsTunMode}">
<DockPanel Classes="Margin8">
<Grid
<Grid
Classes="Margin8"
ColumnDefinitions="Auto,Auto,Auto"
DockPanel.Dock="Top"
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
<TextBlock
Grid.Row="2"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
ColumnDefinitions="Auto,Auto,Auto"
DockPanel.Dock="Top"
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
Text="Strict Route" />
<ToggleSwitch
x:Name="togStrictRoute"
Grid.Row="2"
Grid.Column="1"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="Strict Route" />
<ToggleSwitch
x:Name="togStrictRoute"
Grid.Row="2"
Grid.Column="1"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="Stack" />
<ComboBox
x:Name="cmbStack"
Grid.Row="3"
Grid.Column="1"
Width="200"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="Stack" />
<ComboBox
x:Name="cmbStack"
Grid.Row="3"
Grid.Column="1"
Width="200"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="4"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="Mtu" />
<ComboBox
x:Name="cmbMtu"
Grid.Row="4"
Grid.Column="1"
Width="200"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="4"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="Mtu" />
<ComboBox
x:Name="cmbMtu"
Grid.Row="4"
Grid.Column="1"
Width="200"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsEnableExInbound}" />
<ToggleSwitch
x:Name="togEnableExInbound"
Grid.Row="5"
Grid.Column="1"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsEnableExInbound}" />
<ToggleSwitch
x:Name="togEnableExInbound"
Grid.Row="5"
Grid.Column="1"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="6"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsEnableIPv6Address}" />
<ToggleSwitch
x:Name="togEnableIPv6Address"
Grid.Row="6"
Grid.Column="1"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="6"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsEnableIPv6Address}" />
<ToggleSwitch
x:Name="togEnableIPv6Address"
Grid.Row="6"
Grid.Column="1"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="7"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsLinuxSudoPassword}" />
<TextBox
x:Name="txtLinuxSudoPassword"
Grid.Row="7"
Grid.Column="1"
Width="200"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="7"
Grid.Column="2"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsLinuxSudoPasswordTip}"
TextWrapping="Wrap" />
</Grid>
</DockPanel>
<TextBlock
Grid.Row="7"
Grid.Column="0"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsLinuxSudoPassword}" />
<TextBox
x:Name="txtLinuxSudoPassword"
Grid.Row="7"
Grid.Column="1"
Width="200"
HorizontalAlignment="Left"
Classes="Margin8" />
<TextBlock
Grid.Row="7"
Grid.Column="2"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsLinuxSudoPasswordTip}"
TextWrapping="Wrap" />
</Grid>
</TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreType}">

View File

@@ -126,8 +126,8 @@ namespace v2rayN.Desktop.Views
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.DisplayRealTimeSpeed, v => v.togDisplayRealTimeSpeed.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.EnableAutoAdjustMainLvColWidth, v => v.togEnableAutoAdjustMainLvColWidth.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);

View File

@@ -165,7 +165,7 @@
Classes="Solid Red"
Content="{x:Static resx:ResUI.TipActiveServer}"
IsVisible="{Binding IsActive}"
Theme="{StaticResource TagLabel}" />
Theme="{DynamicResource TagLabel}" />
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"

View File

@@ -15,7 +15,12 @@ namespace v2rayN.Desktop.Views
public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
{
private static Config _config;
private Window _window;
private Window? _window;
public ProfilesView()
{
InitializeComponent();
}
public ProfilesView(Window window)
{

View File

@@ -4,12 +4,10 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
d:DesignHeight="480"
d:DesignWidth="400"
mc:Ignorable="d">
<Grid Margin="30" RowDefinitions="Auto,Auto">
<Image
Name="imgQrcode"
Width="300"
@@ -24,6 +22,5 @@
IsReadOnly="True"
MaxLines="1" />
</Grid>
</UserControl>

View File

@@ -5,6 +5,11 @@ namespace v2rayN.Desktop.Views
{
public partial class QrcodeView : UserControl
{
public QrcodeView()
{
InitializeComponent();
}
public QrcodeView(string? url)
{
InitializeComponent();

View File

@@ -94,8 +94,8 @@
Grid.Column="1"
HorizontalAlignment="Left"
Classes="Margin8"
SelectionMode="Multiple"
Theme="{DynamicResource PureCardRadioGroupListBox}" />
SelectionMode="Multiple,Toggle"
Theme="{DynamicResource CardCheckGroupListBox}" />
<TextBlock
Grid.Row="4"
@@ -108,8 +108,8 @@
Grid.Row="4"
Grid.Column="1"
Classes="Margin8"
SelectionMode="Multiple"
Theme="{DynamicResource PureCardRadioGroupListBox}" />
SelectionMode="Multiple,Toggle"
Theme="{DynamicResource CardCheckGroupListBox}" />
<TextBlock
Grid.Row="4"
Grid.Column="2"

View File

@@ -123,6 +123,7 @@
Classes="Margin8"
TextWrapping="Wrap" />
<!--
<TextBlock
Grid.Row="3"
Grid.Column="0"
@@ -144,6 +145,7 @@
Grid.Column="2"
Classes="Margin8"
Content="{x:Static resx:ResUI.TbBrowse}" />
-->
<TextBlock
Grid.Row="4"

View File

@@ -27,7 +27,7 @@ namespace v2rayN.Desktop.Views
lstRules.SelectionChanged += lstRules_SelectionChanged;
lstRules.DoubleTapped += LstRules_DoubleTapped;
menuRuleSelectAll.Click += menuRuleSelectAll_Click;
btnBrowseCustomIcon.Click += btnBrowseCustomIcon_Click;
//btnBrowseCustomIcon.Click += btnBrowseCustomIcon_Click;
btnBrowseCustomRulesetPath4Singbox.Click += btnBrowseCustomRulesetPath4Singbox_ClickAsync;
ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler);
@@ -51,7 +51,7 @@ namespace v2rayN.Desktop.Views
this.Bind(ViewModel, vm => vm.SelectedRouting.DomainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.Url, v => v.txtUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.CustomIcon, v => v.txtCustomIcon.Text).DisposeWith(disposables);
//this.Bind(ViewModel, vm => vm.SelectedRouting.CustomIcon, v => v.txtCustomIcon.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.CustomRulesetPath4Singbox, v => v.txtCustomRulesetPath4Singbox.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.Sort, v => v.txtSort.Text).DisposeWith(disposables);
@@ -179,16 +179,16 @@ namespace v2rayN.Desktop.Views
lstRules.SelectAll();
}
private async void btnBrowseCustomIcon_Click(object? sender, RoutedEventArgs e)
{
var fileName = await UI.OpenFileDialog(this, FilePickerFileTypes.ImagePng);
if (fileName.IsNullOrEmpty())
{
return;
}
//private async void btnBrowseCustomIcon_Click(object? sender, RoutedEventArgs e)
//{
// var fileName = await UI.OpenFileDialog(this, FilePickerFileTypes.ImagePng);
// if (fileName.IsNullOrEmpty())
// {
// return;
// }
txtCustomIcon.Text = fileName;
}
// txtCustomIcon.Text = fileName;
//}
private async void btnBrowseCustomRulesetPath4Singbox_ClickAsync(object? sender, RoutedEventArgs e)
{

View File

@@ -18,40 +18,29 @@
<StackPanel
Classes="Margin8"
DockPanel.Dock="Top"
Orientation="Horizontal">
Orientation="Horizontal"
Spacing="4">
<Menu>
<MenuItem x:Name="menuRoutingAdvancedAdd2" Header="{x:Static resx:ResUI.menuRoutingAdvancedAdd}" />
<MenuItem x:Name="menuRoutingAdvancedImportRules2" Header="{x:Static resx:ResUI.menuRoutingAdvancedImportRules}" />
</Menu>
<TextBlock Margin="8,0,0,0" VerticalAlignment="Center">
<TextBlock VerticalAlignment="Center">
<HyperlinkButton Classes="WithIcon" Click="linkdomainStrategy_Click">
<TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy}" />
</HyperlinkButton>
</TextBlock>
<ComboBox
x:Name="cmbdomainStrategy"
Width="110"
Margin="8,0,0,0" />
<ComboBox x:Name="cmbdomainStrategy" Width="110" />
<Separator />
<TextBlock
Margin="8,0,0,0"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbdomainMatcher}" />
<ComboBox
x:Name="cmbdomainMatcher"
Width="60"
Margin="8,0,0,0" />
<TextBlock VerticalAlignment="Center" Text="{x:Static resx:ResUI.TbdomainMatcher}" />
<ComboBox x:Name="cmbdomainMatcher" Width="60" />
<Separator />
<TextBlock Margin="8,0,0,0" VerticalAlignment="Center">
<TextBlock VerticalAlignment="Center">
<HyperlinkButton Classes="WithIcon" Click="linkdomainStrategy4Singbox_Click">
<TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy4Singbox}" />
</HyperlinkButton>
</TextBlock>
<ComboBox
x:Name="cmbdomainStrategy4Singbox"
Width="100"
Margin="8,0,0,0" />
<ComboBox x:Name="cmbdomainStrategy4Singbox" Width="100" />
</StackPanel>
<StackPanel

View File

@@ -11,73 +11,71 @@
x:DataType="vms:StatusBarViewModel"
mc:Ignorable="d">
<Grid>
<StackPanel Height="50">
<DockPanel>
<StackPanel
<DockPanel Margin="4">
<StackPanel
Margin="8,0"
VerticalAlignment="Center"
DockPanel.Dock="Right">
<TextBlock x:Name="txtSpeedProxyDisplay" HorizontalAlignment="Right" />
<Border Margin="1" />
<TextBlock x:Name="txtSpeedDirectDisplay" HorizontalAlignment="Right" />
</StackPanel>
<StackPanel
Margin="8,0"
VerticalAlignment="Center"
DockPanel.Dock="Left">
<TextBlock x:Name="txtInboundDisplay" />
<Border Margin="1" />
<TextBlock x:Name="txtInboundLanDisplay" />
</StackPanel>
<StackPanel
x:Name="spEnableTun"
Margin="8,0"
VerticalAlignment="Center"
DockPanel.Dock="Left"
Orientation="Horizontal">
<TextBlock
Margin="8,0"
VerticalAlignment="Center"
DockPanel.Dock="Right">
<TextBlock x:Name="txtSpeedProxyDisplay" />
<Border Margin="2" />
<TextBlock x:Name="txtSpeedDirectDisplay" />
</StackPanel>
Text="{x:Static resx:ResUI.TbEnableTunAs}" />
<ToggleSwitch
x:Name="togEnableTun"
HorizontalAlignment="Center"
Classes="Margin8"
Theme="{DynamicResource SimpleToggleSwitch}" />
</StackPanel>
<StackPanel
<StackPanel
Margin="8,0"
VerticalAlignment="Center"
DockPanel.Dock="Left"
Orientation="Horizontal">
<ComboBox
x:Name="cmbSystemProxy"
Width="160"
Margin="8,0"
VerticalAlignment="Center"
DockPanel.Dock="Left">
<TextBlock x:Name="txtInboundDisplay" />
<Border Margin="2" />
<TextBlock x:Name="txtInboundLanDisplay" />
</StackPanel>
ToolTip.Tip="{x:Static resx:ResUI.menuSystemproxy}">
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyNothing}" />
</ComboBox>
<StackPanel
x:Name="spEnableTun"
<ComboBox
x:Name="cmbRoutings2"
Width="160"
Margin="8,0"
VerticalAlignment="Center"
DockPanel.Dock="Left"
Orientation="Horizontal">
<TextBlock
Margin="8,0"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbEnableTunAs}" />
<ToggleSwitch
x:Name="togEnableTun"
HorizontalAlignment="Center"
Classes="Margin8"
Theme="{StaticResource SimpleToggleSwitch}" />
</StackPanel>
DisplayMemberBinding="{Binding Remarks}"
ItemsSource="{Binding RoutingItems}"
ToolTip.Tip="{x:Static resx:ResUI.menuRouting}" />
</StackPanel>
<StackPanel
Margin="8,0"
VerticalAlignment="Center"
DockPanel.Dock="Left"
Orientation="Horizontal">
<ComboBox
x:Name="cmbSystemProxy"
Width="160"
Margin="8,0"
ToolTip.Tip="{x:Static resx:ResUI.menuSystemproxy}">
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyNothing}" />
</ComboBox>
<ComboBox
x:Name="cmbRoutings2"
Width="160"
Margin="8,0"
DisplayMemberBinding="{Binding Remarks}"
ItemsSource="{Binding RoutingItems}"
ToolTip.Tip="{x:Static resx:ResUI.menuRouting}" />
</StackPanel>
<StackPanel Margin="8,0" VerticalAlignment="Center">
<TextBlock x:Name="txtRunningServerDisplay" />
<Border Margin="2" />
<TextBlock x:Name="txtRunningInfoDisplay" />
</StackPanel>
</DockPanel>
</StackPanel>
<StackPanel Margin="8,0" VerticalAlignment="Center">
<TextBlock x:Name="txtRunningServerDisplay" />
<Border Margin="1" />
<TextBlock x:Name="txtRunningInfoDisplay" />
</StackPanel>
</DockPanel>
</Grid>
</UserControl>

View File

@@ -69,6 +69,11 @@ namespace v2rayN.Desktop.Views
},
DispatcherPriority.Default);
break;
case EViewAction.SetClipboardData:
if (obj is null) return false;
await AvaUtils.SetClipboardData(this, (string)obj);
break;
}
return await Task.FromResult(true);
}

View File

@@ -10,6 +10,15 @@
d:DesignWidth="800"
x:DataType="vms:ThemeSettingViewModel"
mc:Ignorable="d">
<UserControl.Styles>
<Style Selector="TextBlock">
<Setter Property="Width" Value="100" />
</Style>
<Style Selector="ComboBox">
<Setter Property="Width" Value="130" />
</Style>
</UserControl.Styles>
<Button
Width="30"
Height="30"
@@ -24,43 +33,35 @@
</Button.Content>
<Button.Flyout>
<Flyout>
<StackPanel>
<StackPanel Margin="0,12">
<StackPanel Orientation="Horizontal">
<TextBlock
Width="100"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsColorMode}" />
<ToggleSwitch x:Name="togDarkMode" Classes="Margin8" />
Text="{x:Static resx:ResUI.TbSettingsTheme}" />
<ComboBox
x:Name="cmbCurrentTheme"
HorizontalAlignment="Center"
Classes="Margin8" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock
Width="100"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsFollowSystemTheme}" />
<ToggleSwitch x:Name="togFollowSystemTheme" Classes="Margin8" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock
Width="100"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsFontSize}" />
<ComboBox
x:Name="cmbCurrentFontSize"
Width="100"
HorizontalAlignment="Center"
Classes="Margin8" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock
Width="100"
VerticalAlignment="Center"
Classes="Margin8"
Text="{x:Static resx:ResUI.TbSettingsLanguage}" />
<ComboBox
x:Name="cmbCurrentLanguage"
Width="100"
HorizontalAlignment="Center"
Classes="Margin8" />
</StackPanel>
</StackPanel>

View File

@@ -16,6 +16,11 @@ namespace v2rayN.Desktop.Views
InitializeComponent();
ViewModel = new ThemeSettingViewModel();
foreach (ETheme it in Enum.GetValues(typeof(ETheme)))
{
cmbCurrentTheme.Items.Add(it.ToString());
}
for (int i = Global.MinFontSize; i <= Global.MinFontSize + 10; i++)
{
cmbCurrentFontSize.Items.Add(i);
@@ -28,8 +33,7 @@ namespace v2rayN.Desktop.Views
this.WhenActivated(disposables =>
{
this.Bind(ViewModel, vm => vm.ColorModeDark, v => v.togDarkMode.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.FollowSystemTheme, v => v.togFollowSystemTheme.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CurrentTheme, v => v.cmbCurrentTheme.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CurrentFontSize, v => v.cmbCurrentFontSize.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CurrentLanguage, v => v.cmbCurrentLanguage.SelectedValue).DisposeWith(disposables);
});

View File

@@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>Assets\v2rayN.ico</ApplicationIcon>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<Copyright>Copyright © 2017-2024 (GPLv3)</Copyright>
<Copyright>Copyright © 2017-2025 (GPLv3)</Copyright>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<AssemblyName>v2rayN</AssemblyName>
</PropertyGroup>
@@ -28,8 +28,8 @@
<PackageReference Include="Avalonia.ReactiveUI" Version="11.2.3" />
<PackageReference Include="DialogHost.Avalonia" Version="0.8.1" />
<PackageReference Include="MessageBox.Avalonia" Version="3.2.0" />
<PackageReference Include="Semi.Avalonia" Version="11.2.1.2" />
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.2.1.2" />
<PackageReference Include="Semi.Avalonia" Version="11.2.1.3" />
<PackageReference Include="Semi.Avalonia.DataGrid" Version="11.2.1.3" />
<PackageReference Include="ReactiveUI" Version="20.1.63" />
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
</ItemGroup>
@@ -48,7 +48,7 @@
<None Update="v2rayN.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="v2rayN2.png">
<None Update="v2rayN.icns">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -14,6 +14,7 @@ namespace v2rayN
internal static class WindowsUtils
{
private static readonly string _tag = "WindowsUtils";
/// <summary>
/// 获取剪贴板数
/// </summary>
@@ -63,14 +64,6 @@ namespace v2rayN
BitmapSizeOptions.FromEmptyOptions());
}
public static bool IsDarkTheme()
{
using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
var obj = key?.GetValue("AppsUseLightTheme");
int.TryParse(obj?.ToString(), out var value);
return value == 0;
}
public static void RemoveTunDevice()
{
try
@@ -102,7 +95,19 @@ namespace v2rayN
}
}
public static void SetDarkBorder(Window window, bool dark)
public static void SetDarkBorder(Window window, string? theme)
{
var isDark = theme switch
{
nameof(ETheme.Dark) => true,
nameof(ETheme.Light) => false,
_ => IsDarkTheme(),
};
SetDarkBorder(window, isDark);
}
private static void SetDarkBorder(Window window, bool dark)
{
// Make sure the handle is created before the window is shown
IntPtr hWnd = new WindowInteropHelper(window).EnsureHandle();
@@ -112,6 +117,14 @@ namespace v2rayN
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref attribute, attributeSize);
}
private static bool IsDarkTheme()
{
using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
var obj = key?.GetValue("AppsUseLightTheme");
int.TryParse(obj?.ToString(), out var value);
return value == 0;
}
#region Windows API
[Flags]

View File

@@ -16,23 +16,17 @@ namespace v2rayN.ViewModels
{
private readonly PaletteHelper _paletteHelper = new();
[Reactive]
public bool ColorModeDark { get; set; }
private IObservableCollection<Swatch> _swatches = new ObservableCollectionExtended<Swatch>();
public IObservableCollection<Swatch> Swatches => _swatches;
[Reactive]
public Swatch SelectedSwatch { get; set; }
[Reactive]
public int CurrentFontSize { get; set; }
[Reactive] public string CurrentTheme { get; set; }
[Reactive]
public bool FollowSystemTheme { get; set; }
[Reactive] public int CurrentFontSize { get; set; }
[Reactive]
public string CurrentLanguage { get; set; }
[Reactive] public string CurrentLanguage { get; set; }
public ThemeSettingViewModel()
{
@@ -47,6 +41,7 @@ namespace v2rayN.ViewModels
private void RestoreUI()
{
ModifyTheme();
ModifyFontSize();
if (!_config.UiItem.ColorPrimaryName.IsNullOrEmpty())
{
var swatch = new SwatchesProvider().Swatches.FirstOrDefault(t => t.Name == _config.UiItem.ColorPrimaryName);
@@ -61,40 +56,27 @@ namespace v2rayN.ViewModels
private void BindingUI()
{
ColorModeDark = _config.UiItem.ColorModeDark;
FollowSystemTheme = _config.UiItem.FollowSystemTheme;
_swatches.AddRange(new SwatchesProvider().Swatches);
if (!_config.UiItem.ColorPrimaryName.IsNullOrEmpty())
{
SelectedSwatch = _swatches.FirstOrDefault(t => t.Name == _config.UiItem.ColorPrimaryName);
}
CurrentTheme = _config.UiItem.CurrentTheme;
CurrentFontSize = _config.UiItem.CurrentFontSize;
CurrentLanguage = _config.UiItem.CurrentLanguage;
this.WhenAnyValue(
x => x.ColorModeDark,
y => y == true)
.Subscribe(c =>
{
if (_config.UiItem.ColorModeDark != ColorModeDark)
{
_config.UiItem.ColorModeDark = ColorModeDark;
ModifyTheme();
ConfigHandler.SaveConfig(_config);
}
});
this.WhenAnyValue(x => x.FollowSystemTheme,
y => y == true)
.Subscribe(c =>
{
if (_config.UiItem.FollowSystemTheme != FollowSystemTheme)
{
_config.UiItem.FollowSystemTheme = FollowSystemTheme;
ModifyTheme();
ConfigHandler.SaveConfig(_config);
}
});
x => x.CurrentTheme,
y => y != null && !y.IsNullOrEmpty())
.Subscribe(c =>
{
if (_config.UiItem.CurrentTheme != CurrentTheme)
{
_config.UiItem.CurrentTheme = CurrentTheme;
ModifyTheme();
ConfigHandler.SaveConfig(_config);
}
});
this.WhenAnyValue(
x => x.SelectedSwatch,
@@ -121,14 +103,10 @@ namespace v2rayN.ViewModels
y => y > 0)
.Subscribe(c =>
{
if (CurrentFontSize >= Global.MinFontSize)
if (_config.UiItem.CurrentFontSize != CurrentFontSize)
{
_config.UiItem.CurrentFontSize = CurrentFontSize;
double size = (long)CurrentFontSize;
Application.Current.Resources["StdFontSize"] = size;
Application.Current.Resources["StdFontSize1"] = size + 1;
Application.Current.Resources["StdFontSize-1"] = size - 1;
ModifyFontSize();
ConfigHandler.SaveConfig(_config);
}
});
@@ -150,12 +128,28 @@ namespace v2rayN.ViewModels
public void ModifyTheme()
{
var theme = _paletteHelper.GetTheme();
var baseTheme = CurrentTheme switch
{
nameof(ETheme.Dark) => BaseTheme.Dark,
nameof(ETheme.Light) => BaseTheme.Light,
_ => BaseTheme.Inherit,
};
var isDarkTheme = FollowSystemTheme ? WindowsUtils.IsDarkTheme() : ColorModeDark;
theme.SetBaseTheme(isDarkTheme ? BaseTheme.Dark : BaseTheme.Light);
var theme = _paletteHelper.GetTheme();
theme.SetBaseTheme(baseTheme);
_paletteHelper.SetTheme(theme);
WindowsUtils.SetDarkBorder(Application.Current.MainWindow, isDarkTheme);
WindowsUtils.SetDarkBorder(Application.Current.MainWindow, CurrentTheme);
}
private void ModifyFontSize()
{
double size = (long)CurrentFontSize;
if (size < Global.MinFontSize) return;
Application.Current.Resources["StdFontSize"] = size;
Application.Current.Resources["StdFontSize1"] = size + 1;
Application.Current.Resources["StdFontSize-1"] = size - 1;
}
public void ChangePrimaryColor(System.Windows.Media.Color color)
@@ -175,7 +169,7 @@ namespace v2rayN.ViewModels
var hwndSource = HwndSource.FromHwnd(helper.EnsureHandle());
hwndSource.AddHook((IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) =>
{
if (config.UiItem.FollowSystemTheme)
if (config.UiItem.CurrentTheme == nameof(ETheme.FollowSystem))
{
const int WM_SETTINGCHANGE = 0x001A;
if (msg == WM_SETTINGCHANGE)

View File

@@ -34,7 +34,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SaveServerCmd, v => v.btnSave).DisposeWith(disposables);
});
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark);
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
}
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -210,7 +210,7 @@ namespace v2rayN.Views
});
this.Title = $"{profileItem.ConfigType}";
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark);
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
}
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -64,7 +64,6 @@
<DataTemplate>
<Border
Width="500"
Height="50"
Margin="{StaticResource Margin8}"
Padding="0"
VerticalAlignment="Center">

View File

@@ -1,14 +1,14 @@
<reactiveui:ReactiveUserControl
x:Class="v2rayN.Views.ClashProxiesView"
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: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:reactiveui="http://reactiveui.net"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
xmlns:converters="clr-namespace:v2rayN.Converters"
d:DesignHeight="450"
d:DesignWidth="800"
x:TypeArguments="vms:ClashProxiesViewModel"
@@ -34,7 +34,7 @@
Text="{x:Static resx:ResUI.menuRulemode}" />
<ComboBox
x:Name="cmbRulemode"
Width="80"
Width="100"
Margin="{StaticResource MarginLeftRight8}"
Style="{StaticResource DefComboBox}">
<ComboBoxItem Content="{x:Static resx:ResUI.menuModeRule}" />
@@ -49,7 +49,7 @@
Text="{x:Static resx:ResUI.TbSorting}" />
<ComboBox
x:Name="cmbSorting"
Width="60"
Width="100"
Margin="{StaticResource MarginLeftRight8}"
Style="{StaticResource DefComboBox}">
<ComboBoxItem Content="{x:Static resx:ResUI.TbSortingDelay}" />

View File

@@ -50,7 +50,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCmd, v => v.btnImportDefConfig4Singbox).DisposeWith(disposables);
});
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark);
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
}
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -30,7 +30,7 @@ namespace v2rayN.Views
HotkeyHandler.Instance.IsPause = true;
this.Closing += (s, e) => HotkeyHandler.Instance.IsPause = false;
WindowsUtils.SetDarkBorder(this, _config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : _config.UiItem.ColorModeDark);
WindowsUtils.SetDarkBorder(this, _config.UiItem.CurrentTheme);
InitData();
}

View File

@@ -601,9 +601,9 @@
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsKeepOlderDedupl}" />
Text="{x:Static resx:ResUI.TbSettingsDisplayRealTimeSpeed}" />
<ToggleButton
x:Name="togKeepOlderDedupl"
x:Name="togDisplayRealTimeSpeed"
Grid.Row="3"
Grid.Column="1"
Margin="{StaticResource Margin8}"
@@ -615,9 +615,9 @@
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsIgnoreGeoUpdateCore}" />
Text="{x:Static resx:ResUI.TbSettingsKeepOlderDedupl}" />
<ToggleButton
x:Name="togIgnoreGeoUpdateCore"
x:Name="togKeepOlderDedupl"
Grid.Row="4"
Grid.Column="1"
Margin="{StaticResource Margin8}"
@@ -997,98 +997,96 @@
</TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsTunMode}">
<DockPanel Margin="{StaticResource Margin8}">
<Grid Margin="{StaticResource Margin8}" DockPanel.Dock="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Margin="{StaticResource Margin8}" DockPanel.Dock="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="Strict Route" />
<ToggleButton
x:Name="togStrictRoute"
Grid.Row="2"
Grid.Column="1"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="Strict Route" />
<ToggleButton
x:Name="togStrictRoute"
Grid.Row="2"
Grid.Column="1"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="Stack" />
<ComboBox
x:Name="cmbStack"
Grid.Row="3"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="Stack" />
<ComboBox
x:Name="cmbStack"
Grid.Row="3"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="4"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="Mtu" />
<ComboBox
x:Name="cmbMtu"
Grid.Row="4"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="4"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="Mtu" />
<ComboBox
x:Name="cmbMtu"
Grid.Row="4"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsEnableExInbound}" />
<ToggleButton
x:Name="togEnableExInbound"
Grid.Row="5"
Grid.Column="1"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="5"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsEnableExInbound}" />
<ToggleButton
x:Name="togEnableExInbound"
Grid.Row="5"
Grid.Column="1"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="6"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsEnableIPv6Address}" />
<ToggleButton
x:Name="togEnableIPv6Address"
Grid.Row="6"
Grid.Column="1"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
</Grid>
</DockPanel>
<TextBlock
Grid.Row="6"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsEnableIPv6Address}" />
<ToggleButton
x:Name="togEnableIPv6Address"
Grid.Row="6"
Grid.Column="1"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
</Grid>
</TabItem>
<TabItem Header="{x:Static resx:ResUI.TbSettingsCoreType}">

View File

@@ -136,8 +136,8 @@ namespace v2rayN.Views
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.DisplayRealTimeSpeed, v => v.togDisplayRealTimeSpeed.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.EnableAutoAdjustMainLvColWidth, v => v.togEnableAutoAdjustMainLvColWidth.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);
@@ -177,7 +177,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
});
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark);
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
}
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
@@ -248,7 +248,9 @@ namespace v2rayN.Views
{
Logging.SaveLog("GetFonts", ex);
}
return lstFonts.OrderBy(t => t).ToList();
var lst = lstFonts.OrderBy(t => t).ToList();
return await Task.FromResult(lst);
}
private void ClbdestOverride_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)

View File

@@ -58,7 +58,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
});
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark);
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
}
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -60,7 +60,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
});
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark);
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
}
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -52,7 +52,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
});
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark);
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
}
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -15,15 +15,24 @@
Style="{StaticResource ViewGlobal}"
mc:Ignorable="d">
<Grid>
<materialDesign:ColorZone Height="50" Mode="Standard">
<materialDesign:ColorZone
Height="auto"
Margin="{StaticResource Margin4}"
Mode="Standard">
<DockPanel>
<StackPanel
Margin="{StaticResource MarginLeftRight8}"
VerticalAlignment="Center"
DockPanel.Dock="Right">
<TextBlock x:Name="txtSpeedProxyDisplay" Style="{StaticResource StatusbarItem}" />
<Border Margin="{StaticResource Margin4}" />
<TextBlock x:Name="txtSpeedDirectDisplay" Style="{StaticResource StatusbarItem}" />
<TextBlock
x:Name="txtSpeedProxyDisplay"
HorizontalAlignment="Right"
Style="{StaticResource StatusbarItem}" />
<Border Margin="1" />
<TextBlock
x:Name="txtSpeedDirectDisplay"
HorizontalAlignment="Right"
Style="{StaticResource StatusbarItem}" />
</StackPanel>
<StackPanel
@@ -32,7 +41,7 @@
VerticalAlignment="Center"
DockPanel.Dock="Left">
<TextBlock x:Name="txtInboundDisplay" Style="{StaticResource StatusbarItem}" />
<Border Margin="{StaticResource Margin4}" />
<Border Margin="1" />
<TextBlock x:Name="txtInboundLanDisplay" Style="{StaticResource StatusbarItem}" />
</StackPanel>
@@ -85,7 +94,7 @@
<StackPanel Margin="{StaticResource MarginLeftRight8}" VerticalAlignment="Center">
<TextBlock x:Name="txtRunningServerDisplay" Style="{StaticResource StatusbarItem}" />
<Border Margin="{StaticResource Margin4}" />
<Border Margin="1" />
<TextBlock x:Name="txtRunningInfoDisplay" Style="{StaticResource StatusbarItem}" />
</StackPanel>
</DockPanel>
@@ -193,6 +202,11 @@
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuSubUpdateViaProxy}" />
<Separator />
<MenuItem
x:Name="menuCopyProxyCmdToClipboard"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuCopyProxyCmdToClipboard}" />
<Separator />
<MenuItem
x:Name="menuExit"
Height="{StaticResource MenuItemHeight}"

View File

@@ -51,6 +51,8 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SubUpdateCmd, v => v.menuSubUpdate2).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SubUpdateViaProxyCmd, v => v.menuSubUpdateViaProxy2).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.CopyProxyCmdToClipboardCmd, v => v.menuCopyProxyCmdToClipboard).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.RunningServerToolTipText, v => v.tbNotify.ToolTipText).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.NotifyLeftClickCmd, v => v.tbNotify.LeftClickCommand).DisposeWith(disposables);
@@ -96,6 +98,10 @@ namespace v2rayN.Views
Application.Current.MainWindow.Icon = WindowsHandler.Instance.GetAppIcon(_config);
}), DispatcherPriority.Normal);
break;
case EViewAction.SetClipboardData:
if (obj is null) return false;
WindowsUtils.SetClipboardData((string)obj);
break;
}
return await Task.FromResult(true);
}

View File

@@ -38,7 +38,7 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
});
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? WindowsUtils.IsDarkTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark);
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme);
}
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

Some files were not shown because too many files have changed in this diff Show More