mirror of
https://github.com/2dust/v2rayN.git
synced 2026-04-16 04:25:45 +00:00
Compare commits
8 commits
ab9603dac8
...
7febc85e1d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7febc85e1d | ||
|
|
0021c8aab1 | ||
|
|
723c78df33 | ||
|
|
a224d1def8 | ||
|
|
5fbcc46013 | ||
|
|
90f7b8b751 | ||
|
|
dd94199bbb | ||
|
|
0cec5986cd |
38 changed files with 942 additions and 167 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
<Project>
|
<Project>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>7.19.4</Version>
|
<Version>7.19.5</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
<PackageVersion Include="CliWrap" Version="3.10.0" />
|
<PackageVersion Include="CliWrap" Version="3.10.0" />
|
||||||
<PackageVersion Include="Downloader" Version="5.1.0" />
|
<PackageVersion Include="Downloader" Version="5.1.0" />
|
||||||
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.4.1" />
|
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.4.1" />
|
||||||
<PackageVersion Include="MaterialDesignThemes" Version="5.3.0" />
|
<PackageVersion Include="MaterialDesignThemes" Version="5.3.1" />
|
||||||
<PackageVersion Include="MessageBox.Avalonia" Version="3.3.1.1" />
|
<PackageVersion Include="MessageBox.Avalonia" Version="3.3.1.1" />
|
||||||
<PackageVersion Include="QRCoder" Version="1.7.0" />
|
<PackageVersion Include="QRCoder" Version="1.7.0" />
|
||||||
<PackageVersion Include="ReactiveUI" Version="23.1.8" />
|
<PackageVersion Include="ReactiveUI" Version="23.1.8" />
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ public enum EConfigType
|
||||||
WireGuard = 9,
|
WireGuard = 9,
|
||||||
HTTP = 10,
|
HTTP = 10,
|
||||||
Anytls = 11,
|
Anytls = 11,
|
||||||
|
Naive = 12,
|
||||||
PolicyGroup = 101,
|
PolicyGroup = 101,
|
||||||
ProxyChain = 102,
|
ProxyChain = 102,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,10 @@ public class Global
|
||||||
|
|
||||||
public const string Hysteria2ProtocolShare = "hy2://";
|
public const string Hysteria2ProtocolShare = "hy2://";
|
||||||
|
|
||||||
|
public const string NaiveHttpsProtocolShare = "naive+https://";
|
||||||
|
|
||||||
|
public const string NaiveQuicProtocolShare = "naive+quic://";
|
||||||
|
|
||||||
public static readonly Dictionary<EConfigType, string> ProtocolShares = new()
|
public static readonly Dictionary<EConfigType, string> ProtocolShares = new()
|
||||||
{
|
{
|
||||||
{ EConfigType.VMess, "vmess://" },
|
{ EConfigType.VMess, "vmess://" },
|
||||||
|
|
@ -203,7 +207,8 @@ public class Global
|
||||||
{ EConfigType.Hysteria2, "hysteria2://" },
|
{ EConfigType.Hysteria2, "hysteria2://" },
|
||||||
{ EConfigType.TUIC, "tuic://" },
|
{ EConfigType.TUIC, "tuic://" },
|
||||||
{ EConfigType.WireGuard, "wireguard://" },
|
{ EConfigType.WireGuard, "wireguard://" },
|
||||||
{ EConfigType.Anytls, "anytls://" }
|
{ EConfigType.Anytls, "anytls://" },
|
||||||
|
{ EConfigType.Naive, "naive://" }
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly Dictionary<EConfigType, string> ProtocolTypes = new()
|
public static readonly Dictionary<EConfigType, string> ProtocolTypes = new()
|
||||||
|
|
@ -217,7 +222,8 @@ public class Global
|
||||||
{ EConfigType.Hysteria2, "hysteria2" },
|
{ EConfigType.Hysteria2, "hysteria2" },
|
||||||
{ EConfigType.TUIC, "tuic" },
|
{ EConfigType.TUIC, "tuic" },
|
||||||
{ EConfigType.WireGuard, "wireguard" },
|
{ EConfigType.WireGuard, "wireguard" },
|
||||||
{ EConfigType.Anytls, "anytls" }
|
{ EConfigType.Anytls, "anytls" },
|
||||||
|
{ EConfigType.Naive, "naive" }
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly List<string> VmessSecurities =
|
public static readonly List<string> VmessSecurities =
|
||||||
|
|
@ -342,6 +348,7 @@ public class Global
|
||||||
EConfigType.Hysteria2,
|
EConfigType.Hysteria2,
|
||||||
EConfigType.TUIC,
|
EConfigType.TUIC,
|
||||||
EConfigType.Anytls,
|
EConfigType.Anytls,
|
||||||
|
EConfigType.Naive,
|
||||||
EConfigType.WireGuard,
|
EConfigType.WireGuard,
|
||||||
EConfigType.SOCKS,
|
EConfigType.SOCKS,
|
||||||
EConfigType.HTTP,
|
EConfigType.HTTP,
|
||||||
|
|
@ -558,6 +565,14 @@ public class Global
|
||||||
"bbr"
|
"bbr"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public static readonly List<string> NaiveCongestionControls =
|
||||||
|
[
|
||||||
|
"bbr",
|
||||||
|
"bbr2",
|
||||||
|
"cubic",
|
||||||
|
"reno"
|
||||||
|
];
|
||||||
|
|
||||||
public static readonly List<string> allowSelectType =
|
public static readonly List<string> allowSelectType =
|
||||||
[
|
[
|
||||||
"selector",
|
"selector",
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,12 @@ public class NodeValidator
|
||||||
|
|
||||||
private static string? ValidateSingboxTransport(EConfigType configType, string net)
|
private static string? ValidateSingboxTransport(EConfigType configType, string net)
|
||||||
{
|
{
|
||||||
|
// Naive support tcp and quic transports
|
||||||
|
if (configType == EConfigType.Naive && net == "quic")
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// sing-box does not support xhttp / kcp transports
|
// sing-box does not support xhttp / kcp transports
|
||||||
if (SingboxUnsupportedTransports.Contains(net))
|
if (SingboxUnsupportedTransports.Contains(net))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,7 @@ public static class ConfigHandler
|
||||||
EConfigType.TUIC => await AddTuicServer(config, item),
|
EConfigType.TUIC => await AddTuicServer(config, item),
|
||||||
EConfigType.WireGuard => await AddWireguardServer(config, item),
|
EConfigType.WireGuard => await AddWireguardServer(config, item),
|
||||||
EConfigType.Anytls => await AddAnytlsServer(config, item),
|
EConfigType.Anytls => await AddAnytlsServer(config, item),
|
||||||
|
EConfigType.Naive => await AddNaiveServer(config, item),
|
||||||
_ => -1,
|
_ => -1,
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -804,7 +805,7 @@ public static class ConfigHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add or edit a Anytls server
|
/// Add or edit an Anytls server
|
||||||
/// Validates and processes Anytls-specific settings
|
/// Validates and processes Anytls-specific settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="config">Current configuration</param>
|
/// <param name="config">Current configuration</param>
|
||||||
|
|
@ -831,6 +832,35 @@ public static class ConfigHandler
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add or edit a Naive server
|
||||||
|
/// Validates and processes Naive-specific settings
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config">Current configuration</param>
|
||||||
|
/// <param name="profileItem">Naive profile to add</param>
|
||||||
|
/// <param name="toFile">Whether to save to file</param>
|
||||||
|
/// <returns>0 if successful, -1 if failed</returns>
|
||||||
|
public static async Task<int> AddNaiveServer(Config config, ProfileItem profileItem, bool toFile = true)
|
||||||
|
{
|
||||||
|
profileItem.ConfigType = EConfigType.Naive;
|
||||||
|
profileItem.CoreType = ECoreType.sing_box;
|
||||||
|
|
||||||
|
profileItem.Address = profileItem.Address.TrimEx();
|
||||||
|
profileItem.Username = profileItem.Username.TrimEx();
|
||||||
|
profileItem.Password = profileItem.Password.TrimEx();
|
||||||
|
profileItem.Network = profileItem.Network == "quic" ? "quic" : string.Empty;
|
||||||
|
if (profileItem.StreamSecurity.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
profileItem.StreamSecurity = Global.StreamSecurity;
|
||||||
|
}
|
||||||
|
if (profileItem.Password.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
await AddServerCommon(config, profileItem, toFile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sort the server list by the specified column
|
/// Sort the server list by the specified column
|
||||||
/// Updates the sort order in the profile extension data
|
/// Updates the sort order in the profile extension data
|
||||||
|
|
@ -1077,7 +1107,8 @@ public static class ConfigHandler
|
||||||
|
|
||||||
if (toFile)
|
if (toFile)
|
||||||
{
|
{
|
||||||
profileItem.SetProtocolExtra();
|
//profileItem.SetProtocolExtra();
|
||||||
|
profileItem.SetProtocolExtra(profileItem.GetProtocolExtra());
|
||||||
await SQLiteHelper.Instance.ReplaceAsync(profileItem);
|
await SQLiteHelper.Instance.ReplaceAsync(profileItem);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1105,6 +1136,7 @@ public static class ConfigHandler
|
||||||
&& AreEqual(o.Address, n.Address)
|
&& AreEqual(o.Address, n.Address)
|
||||||
&& o.Port == n.Port
|
&& o.Port == n.Port
|
||||||
&& AreEqual(o.Password, n.Password)
|
&& AreEqual(o.Password, n.Password)
|
||||||
|
&& AreEqual(o.Username, n.Username)
|
||||||
&& AreEqual(oProtocolExtra.VlessEncryption, nProtocolExtra.VlessEncryption)
|
&& AreEqual(oProtocolExtra.VlessEncryption, nProtocolExtra.VlessEncryption)
|
||||||
&& AreEqual(oProtocolExtra.SsMethod, nProtocolExtra.SsMethod)
|
&& AreEqual(oProtocolExtra.SsMethod, nProtocolExtra.SsMethod)
|
||||||
&& AreEqual(oProtocolExtra.VmessSecurity, nProtocolExtra.VmessSecurity)
|
&& AreEqual(oProtocolExtra.VmessSecurity, nProtocolExtra.VmessSecurity)
|
||||||
|
|
@ -1496,6 +1528,7 @@ public static class ConfigHandler
|
||||||
EConfigType.TUIC => await AddTuicServer(config, profileItem, false),
|
EConfigType.TUIC => await AddTuicServer(config, profileItem, false),
|
||||||
EConfigType.WireGuard => await AddWireguardServer(config, profileItem, false),
|
EConfigType.WireGuard => await AddWireguardServer(config, profileItem, false),
|
||||||
EConfigType.Anytls => await AddAnytlsServer(config, profileItem, false),
|
EConfigType.Anytls => await AddAnytlsServer(config, profileItem, false),
|
||||||
|
EConfigType.Naive => await AddNaiveServer(config, profileItem, false),
|
||||||
_ => -1,
|
_ => -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ public class FmtHandler
|
||||||
EConfigType.TUIC => TuicFmt.ToUri(item),
|
EConfigType.TUIC => TuicFmt.ToUri(item),
|
||||||
EConfigType.WireGuard => WireguardFmt.ToUri(item),
|
EConfigType.WireGuard => WireguardFmt.ToUri(item),
|
||||||
EConfigType.Anytls => AnytlsFmt.ToUri(item),
|
EConfigType.Anytls => AnytlsFmt.ToUri(item),
|
||||||
|
EConfigType.Naive => NaiveFmt.ToUri(item),
|
||||||
_ => null,
|
_ => null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -80,6 +81,12 @@ public class FmtHandler
|
||||||
{
|
{
|
||||||
return AnytlsFmt.Resolve(str, out msg);
|
return AnytlsFmt.Resolve(str, out msg);
|
||||||
}
|
}
|
||||||
|
else if (str.StartsWith(Global.ProtocolShares[EConfigType.Naive])
|
||||||
|
|| str.StartsWith(Global.NaiveHttpsProtocolShare)
|
||||||
|
|| str.StartsWith(Global.NaiveQuicProtocolShare))
|
||||||
|
{
|
||||||
|
return NaiveFmt.Resolve(str, out msg);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msg = ResUI.NonvmessOrssProtocol;
|
msg = ResUI.NonvmessOrssProtocol;
|
||||||
|
|
|
||||||
85
v2rayN/ServiceLib/Handler/Fmt/NaiveFmt.cs
Normal file
85
v2rayN/ServiceLib/Handler/Fmt/NaiveFmt.cs
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
namespace ServiceLib.Handler.Fmt;
|
||||||
|
|
||||||
|
public class NaiveFmt : BaseFmt
|
||||||
|
{
|
||||||
|
public static ProfileItem? Resolve(string str, out string msg)
|
||||||
|
{
|
||||||
|
msg = ResUI.ConfigurationFormatIncorrect;
|
||||||
|
|
||||||
|
var parsedUrl = Utils.TryUri(str);
|
||||||
|
if (parsedUrl == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileItem item = new()
|
||||||
|
{
|
||||||
|
ConfigType = EConfigType.Naive,
|
||||||
|
Remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped),
|
||||||
|
Address = parsedUrl.IdnHost,
|
||||||
|
Port = parsedUrl.Port,
|
||||||
|
};
|
||||||
|
if (parsedUrl.Scheme.Contains("quic"))
|
||||||
|
{
|
||||||
|
item.Network = "quic";
|
||||||
|
}
|
||||||
|
var rawUserInfo = Utils.UrlDecode(parsedUrl.UserInfo);
|
||||||
|
if (rawUserInfo.Contains(':'))
|
||||||
|
{
|
||||||
|
var split = rawUserInfo.Split(':', 2);
|
||||||
|
item.Username = split[0];
|
||||||
|
item.Password = split[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.Password = rawUserInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
var query = Utils.ParseQueryString(parsedUrl.Query);
|
||||||
|
ResolveUriQuery(query, ref item);
|
||||||
|
var insecureConcurrency = int.TryParse(GetQueryValue(query, "insecure-concurrency"), out var ic) ? ic : 0;
|
||||||
|
if (insecureConcurrency > 0)
|
||||||
|
{
|
||||||
|
item.SetProtocolExtra(item.GetProtocolExtra() with
|
||||||
|
{
|
||||||
|
InsecureConcurrency = insecureConcurrency,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string? ToUri(ProfileItem? item)
|
||||||
|
{
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var remark = string.Empty;
|
||||||
|
if (item.Remarks.IsNotEmpty())
|
||||||
|
{
|
||||||
|
remark = "#" + Utils.UrlEncode(item.Remarks);
|
||||||
|
}
|
||||||
|
var userInfo = item.Username.IsNotEmpty() ? $"{Utils.UrlEncode(item.Username)}:{Utils.UrlEncode(item.Password)}" : Utils.UrlEncode(item.Password);
|
||||||
|
var dicQuery = new Dictionary<string, string>();
|
||||||
|
ToUriQuery(item, Global.None, ref dicQuery);
|
||||||
|
if (item.GetProtocolExtra().InsecureConcurrency > 0)
|
||||||
|
{
|
||||||
|
dicQuery.Add("insecure-concurrency", item.GetProtocolExtra()?.InsecureConcurrency.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
var query = dicQuery.Count > 0
|
||||||
|
? ("?" + string.Join("&", dicQuery.Select(x => x.Key + "=" + x.Value).ToArray()))
|
||||||
|
: string.Empty;
|
||||||
|
var url = $"{userInfo}@{GetIpv6(item.Address)}:{item.Port}";
|
||||||
|
|
||||||
|
if (item.Network == "quic")
|
||||||
|
{
|
||||||
|
return $"{Global.NaiveQuicProtocolShare}{url}{query}{remark}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $"{Global.NaiveHttpsProtocolShare}{url}{query}{remark}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -30,7 +30,10 @@ public class TuicFmt : BaseFmt
|
||||||
|
|
||||||
var query = Utils.ParseQueryString(url.Query);
|
var query = Utils.ParseQueryString(url.Query);
|
||||||
ResolveUriQuery(query, ref item);
|
ResolveUriQuery(query, ref item);
|
||||||
item.HeaderType = GetQueryValue(query, "congestion_control");
|
item.SetProtocolExtra(item.GetProtocolExtra() with
|
||||||
|
{
|
||||||
|
CongestionControl = GetQueryValue(query, "congestion_control")
|
||||||
|
});
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +54,10 @@ public class TuicFmt : BaseFmt
|
||||||
var dicQuery = new Dictionary<string, string>();
|
var dicQuery = new Dictionary<string, string>();
|
||||||
ToUriQueryLite(item, ref dicQuery);
|
ToUriQueryLite(item, ref dicQuery);
|
||||||
|
|
||||||
dicQuery.Add("congestion_control", item.HeaderType);
|
if (!item.GetProtocolExtra().CongestionControl.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
dicQuery.Add("congestion_control", item.GetProtocolExtra().CongestionControl);
|
||||||
|
}
|
||||||
|
|
||||||
return ToUri(EConfigType.TUIC, item.Address, item.Port, $"{item.Username ?? ""}:{item.Password}", dicQuery, remark);
|
return ToUri(EConfigType.TUIC, item.Address, item.Port, $"{item.Username ?? ""}:{item.Password}", dicQuery, remark);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -305,12 +305,11 @@ public sealed class AppManager
|
||||||
return await SQLiteHelper.Instance.TableAsync<FullConfigTemplateItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
|
return await SQLiteHelper.Instance.TableAsync<FullConfigTemplateItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CS0618
|
||||||
public async Task MigrateProfileExtra()
|
public async Task MigrateProfileExtra()
|
||||||
{
|
{
|
||||||
await MigrateProfileExtraGroup();
|
await MigrateProfileExtraGroup();
|
||||||
|
|
||||||
#pragma warning disable CS0618
|
|
||||||
|
|
||||||
const int pageSize = 100;
|
const int pageSize = 100;
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
|
|
||||||
|
|
@ -334,7 +333,6 @@ public sealed class AppManager
|
||||||
}
|
}
|
||||||
|
|
||||||
//await ProfileGroupItemManager.Instance.ClearAll();
|
//await ProfileGroupItemManager.Instance.ClearAll();
|
||||||
#pragma warning restore CS0618
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> MigrateProfileExtraSub(List<ProfileItem> batch)
|
private async Task<int> MigrateProfileExtraSub(List<ProfileItem> batch)
|
||||||
|
|
@ -380,6 +378,7 @@ public sealed class AppManager
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.TUIC:
|
case EConfigType.TUIC:
|
||||||
|
extra = extra with { CongestionControl = item.HeaderType.NullIfEmpty(), };
|
||||||
item.Username = item.Id;
|
item.Username = item.Id;
|
||||||
item.Id = item.Security;
|
item.Id = item.Security;
|
||||||
item.Password = item.Security;
|
item.Password = item.Security;
|
||||||
|
|
@ -436,7 +435,6 @@ public sealed class AppManager
|
||||||
|
|
||||||
private async Task<bool> MigrateProfileExtraGroup()
|
private async Task<bool> MigrateProfileExtraGroup()
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0618
|
|
||||||
var list = await SQLiteHelper.Instance.TableAsync<ProfileGroupItem>().ToListAsync();
|
var list = await SQLiteHelper.Instance.TableAsync<ProfileGroupItem>().ToListAsync();
|
||||||
var groupItems = new ConcurrentDictionary<string, ProfileGroupItem>(list.Where(t => !string.IsNullOrEmpty(t.IndexId)).ToDictionary(t => t.IndexId!));
|
var groupItems = new ConcurrentDictionary<string, ProfileGroupItem>(list.Where(t => !string.IsNullOrEmpty(t.IndexId)).ToDictionary(t => t.IndexId!));
|
||||||
|
|
||||||
|
|
@ -501,8 +499,8 @@ public sealed class AppManager
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
//await ProfileGroupItemManager.Instance.ClearAll();
|
//await ProfileGroupItemManager.Instance.ClearAll();
|
||||||
#pragma warning restore CS0618
|
|
||||||
}
|
}
|
||||||
|
#pragma warning restore CS0618
|
||||||
|
|
||||||
#endregion SqliteHelper
|
#endregion SqliteHelper
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ namespace ServiceLib.Models;
|
||||||
|
|
||||||
public record ProtocolExtraItem
|
public record ProtocolExtraItem
|
||||||
{
|
{
|
||||||
|
public bool? Uot { get; init; }
|
||||||
|
public string? CongestionControl { get; init; }
|
||||||
|
|
||||||
// vmess
|
// vmess
|
||||||
public string? AlterId { get; init; }
|
public string? AlterId { get; init; }
|
||||||
public string? VmessSecurity { get; init; }
|
public string? VmessSecurity { get; init; }
|
||||||
|
|
@ -29,6 +32,9 @@ public record ProtocolExtraItem
|
||||||
public string? Ports { get; init; }
|
public string? Ports { get; init; }
|
||||||
public string? HopInterval { get; init; }
|
public string? HopInterval { get; init; }
|
||||||
|
|
||||||
|
// naiveproxy
|
||||||
|
public int? InsecureConcurrency { get; init; }
|
||||||
|
|
||||||
// group profile
|
// group profile
|
||||||
public string? GroupType { get; init; }
|
public string? GroupType { get; init; }
|
||||||
public string? ChildItems { get; init; }
|
public string? ChildItems { get; init; }
|
||||||
|
|
|
||||||
|
|
@ -134,10 +134,14 @@ public class Outbound4Sbox : BaseServer4Sbox
|
||||||
public int? recv_window_conn { get; set; }
|
public int? recv_window_conn { get; set; }
|
||||||
public int? recv_window { get; set; }
|
public int? recv_window { get; set; }
|
||||||
public bool? disable_mtu_discovery { get; set; }
|
public bool? disable_mtu_discovery { get; set; }
|
||||||
|
public int? insecure_concurrency { get; set; }
|
||||||
|
public bool? udp_over_tcp { get; set; }
|
||||||
public string? method { get; set; }
|
public string? method { get; set; }
|
||||||
public string? username { get; set; }
|
public string? username { get; set; }
|
||||||
public string? password { get; set; }
|
public string? password { get; set; }
|
||||||
public string? congestion_control { get; set; }
|
public string? congestion_control { get; set; }
|
||||||
|
public bool? quic { get; set; }
|
||||||
|
public string? quic_congestion_control { get; set; }
|
||||||
public string? version { get; set; }
|
public string? version { get; set; }
|
||||||
public string? network { get; set; }
|
public string? network { get; set; }
|
||||||
public string? packet_encoding { get; set; }
|
public string? packet_encoding { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,8 @@ public class ServersItem4Ray
|
||||||
|
|
||||||
public string flow { get; set; }
|
public string flow { get; set; }
|
||||||
|
|
||||||
|
public bool? uot { get; set; }
|
||||||
|
|
||||||
public List<SocksUsersItem4Ray> users { get; set; }
|
public List<SocksUsersItem4Ray> users { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
72
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
72
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
|
|
@ -726,6 +726,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Add [NaïveProxy] 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuAddNaiveServer {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuAddNaiveServer", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Add Policy Group 的本地化字符串。
|
/// 查找类似 Add Policy Group 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -924,6 +933,42 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Copy 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuEditCopy {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuEditCopy", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Format 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuEditFormat {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuEditFormat", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Paste 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuEditPaste {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuEditPaste", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Select all 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string menuEditSelectAll {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("menuEditSelectAll", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Edit 的本地化字符串。
|
/// 查找类似 Edit 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -3069,6 +3114,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Insecure Concurrency 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbInsecureConcurrency {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbInsecureConcurrency", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Most Stable 的本地化字符串。
|
/// 查找类似 Most Stable 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -4455,6 +4509,24 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 UDP over TCP 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbUot {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbUot", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Username 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbUsername {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbUsername", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Validate Regional Domain IPs 的本地化字符串。
|
/// 查找类似 Validate Regional Domain IPs 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1668,4 +1668,28 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||||
<data name="menuGenRegionGroup" xml:space="preserve">
|
<data name="menuGenRegionGroup" xml:space="preserve">
|
||||||
<value>Group by Region</value>
|
<value>Group by Region</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuEditCopy" xml:space="preserve">
|
||||||
|
<value>کپی</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditSelectAll" xml:space="preserve">
|
||||||
|
<value>انتخاب همه</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditPaste" xml:space="preserve">
|
||||||
|
<value>Paste</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditFormat" xml:space="preserve">
|
||||||
|
<value>Format</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUot" xml:space="preserve">
|
||||||
|
<value>UDP over TCP</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||||
|
<value>Add NaïveProxy</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||||
|
<value>Insecure Concurrency</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUsername" xml:space="preserve">
|
||||||
|
<value>Username</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1665,4 +1665,28 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||||
<data name="menuGenRegionGroup" xml:space="preserve">
|
<data name="menuGenRegionGroup" xml:space="preserve">
|
||||||
<value>Group by Region</value>
|
<value>Group by Region</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuEditCopy" xml:space="preserve">
|
||||||
|
<value>Copier</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditSelectAll" xml:space="preserve">
|
||||||
|
<value>Tout sélect</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditPaste" xml:space="preserve">
|
||||||
|
<value>Paste</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditFormat" xml:space="preserve">
|
||||||
|
<value>Format</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUot" xml:space="preserve">
|
||||||
|
<value>UDP over TCP</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||||
|
<value>Ajouter [NaïveProxy]</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||||
|
<value>Insecure Concurrency</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUsername" xml:space="preserve">
|
||||||
|
<value>Username</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1668,4 +1668,28 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||||
<data name="menuGenRegionGroup" xml:space="preserve">
|
<data name="menuGenRegionGroup" xml:space="preserve">
|
||||||
<value>Group by Region</value>
|
<value>Group by Region</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuEditCopy" xml:space="preserve">
|
||||||
|
<value>Másolás</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditSelectAll" xml:space="preserve">
|
||||||
|
<value>Összes kijelölése</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditPaste" xml:space="preserve">
|
||||||
|
<value>Paste</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditFormat" xml:space="preserve">
|
||||||
|
<value>Format</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUot" xml:space="preserve">
|
||||||
|
<value>UDP over TCP</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||||
|
<value>[NaïveProxy] konfiguráció hozzáadása</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||||
|
<value>Insecure Concurrency</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUsername" xml:space="preserve">
|
||||||
|
<value>Username</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -514,19 +514,19 @@
|
||||||
<value>Add a custom configuration</value>
|
<value>Add a custom configuration</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddShadowsocksServer" xml:space="preserve">
|
<data name="menuAddShadowsocksServer" xml:space="preserve">
|
||||||
<value>Add [Shadowsocks] </value>
|
<value>Add [Shadowsocks]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddSocksServer" xml:space="preserve">
|
<data name="menuAddSocksServer" xml:space="preserve">
|
||||||
<value>Add [SOCKS] </value>
|
<value>Add [SOCKS]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddTrojanServer" xml:space="preserve">
|
<data name="menuAddTrojanServer" xml:space="preserve">
|
||||||
<value>Add [Trojan] </value>
|
<value>Add [Trojan]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddVlessServer" xml:space="preserve">
|
<data name="menuAddVlessServer" xml:space="preserve">
|
||||||
<value>Add [VLESS] </value>
|
<value>Add [VLESS]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddVmessServer" xml:space="preserve">
|
<data name="menuAddVmessServer" xml:space="preserve">
|
||||||
<value>Add [VMess] </value>
|
<value>Add [VMess]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuSelectAll" xml:space="preserve">
|
<data name="menuSelectAll" xml:space="preserve">
|
||||||
<value>Select all</value>
|
<value>Select all</value>
|
||||||
|
|
@ -1036,7 +1036,7 @@
|
||||||
<value>Domain</value>
|
<value>Domain</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddHysteria2Server" xml:space="preserve">
|
<data name="menuAddHysteria2Server" xml:space="preserve">
|
||||||
<value>Add [Hysteria2] </value>
|
<value>Add [Hysteria2]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
|
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
|
||||||
<value>Hysteria Max bandwidth (Up/Down)</value>
|
<value>Hysteria Max bandwidth (Up/Down)</value>
|
||||||
|
|
@ -1045,7 +1045,7 @@
|
||||||
<value>Use System Hosts</value>
|
<value>Use System Hosts</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddTuicServer" xml:space="preserve">
|
<data name="menuAddTuicServer" xml:space="preserve">
|
||||||
<value>Add [TUIC] </value>
|
<value>Add [TUIC]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbHeaderType8" xml:space="preserve">
|
<data name="TbHeaderType8" xml:space="preserve">
|
||||||
<value>Congestion control</value>
|
<value>Congestion control</value>
|
||||||
|
|
@ -1075,7 +1075,7 @@
|
||||||
<value>Enable IPv6 Address</value>
|
<value>Enable IPv6 Address</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddWireguardServer" xml:space="preserve">
|
<data name="menuAddWireguardServer" xml:space="preserve">
|
||||||
<value>Add [WireGuard] </value>
|
<value>Add [WireGuard]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbPrivateKey" xml:space="preserve">
|
<data name="TbPrivateKey" xml:space="preserve">
|
||||||
<value>Private Key</value>
|
<value>Private Key</value>
|
||||||
|
|
@ -1495,13 +1495,13 @@
|
||||||
<value>Policy Group Type</value>
|
<value>Policy Group Type</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddPolicyGroupServer" xml:space="preserve">
|
<data name="menuAddPolicyGroupServer" xml:space="preserve">
|
||||||
<value>Add Policy Group </value>
|
<value>Add Policy Group</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddProxyChainServer" xml:space="preserve">
|
<data name="menuAddProxyChainServer" xml:space="preserve">
|
||||||
<value>Add Proxy Chain</value>
|
<value>Add Proxy Chain</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddChildServer" xml:space="preserve">
|
<data name="menuAddChildServer" xml:space="preserve">
|
||||||
<value>Add Child </value>
|
<value>Add Child</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuRemoveChildServer" xml:space="preserve">
|
<data name="menuRemoveChildServer" xml:space="preserve">
|
||||||
<value>Remove Child </value>
|
<value>Remove Child </value>
|
||||||
|
|
@ -1668,4 +1668,28 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||||
<data name="menuGenRegionGroup" xml:space="preserve">
|
<data name="menuGenRegionGroup" xml:space="preserve">
|
||||||
<value>Group by Region</value>
|
<value>Group by Region</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuEditCopy" xml:space="preserve">
|
||||||
|
<value>Copy</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditSelectAll" xml:space="preserve">
|
||||||
|
<value>Select all</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditPaste" xml:space="preserve">
|
||||||
|
<value>Paste</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditFormat" xml:space="preserve">
|
||||||
|
<value>Format</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUot" xml:space="preserve">
|
||||||
|
<value>UDP over TCP</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||||
|
<value>Add [NaïveProxy]</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||||
|
<value>Insecure Concurrency</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUsername" xml:space="preserve">
|
||||||
|
<value>Username</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1027,7 +1027,7 @@
|
||||||
<value>Протокол Mux для sing-box</value>
|
<value>Протокол Mux для sing-box</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRoutingRuleProcess" xml:space="preserve">
|
<data name="TbRoutingRuleProcess" xml:space="preserve">
|
||||||
<value>Process (Linux/Windows)</value>
|
<value>Процесс (Linux/Windows)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRoutingRuleIP" xml:space="preserve">
|
<data name="TbRoutingRuleIP" xml:space="preserve">
|
||||||
<value>IP-адрес или сеть CIDR</value>
|
<value>IP-адрес или сеть CIDR</value>
|
||||||
|
|
@ -1393,10 +1393,10 @@
|
||||||
<value>Внутренний DNS</value>
|
<value>Внутренний DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbDirectResolveStrategy" xml:space="preserve">
|
<data name="TbDirectResolveStrategy" xml:space="preserve">
|
||||||
<value>Direct Target Resolution Strategy</value>
|
<value>Стратегия разрешения прямых соединений</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRemoteResolveStrategy" xml:space="preserve">
|
<data name="TbRemoteResolveStrategy" xml:space="preserve">
|
||||||
<value>Proxy Target Resolution Strategy</value>
|
<value>Стратегия разрешения прокси-соединений</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbAddCommonDNSHosts" xml:space="preserve">
|
<data name="TbAddCommonDNSHosts" xml:space="preserve">
|
||||||
<value>Добавить стандартные записи hosts (DNS)</value>
|
<value>Добавить стандартные записи hosts (DNS)</value>
|
||||||
|
|
@ -1429,7 +1429,7 @@
|
||||||
<value>Включён пользовательский DNS — настройки на этой странице не применяются</value>
|
<value>Включён пользовательский DNS — настройки на этой странице не применяются</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve">
|
<data name="TbBlockSVCBHTTPSQueriesTips" xml:space="preserve">
|
||||||
<value>Block ECH and HTTP/3 availability checks when enabled</value>
|
<value>При включении блокирует проверки доступности ECH и HTTP/3</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FillCorrectConfigTemplateText" xml:space="preserve">
|
<data name="FillCorrectConfigTemplateText" xml:space="preserve">
|
||||||
<value>Пожалуйста, заполните корректный шаблон конфигурации</value>
|
<value>Пожалуйста, заполните корректный шаблон конфигурации</value>
|
||||||
|
|
@ -1462,127 +1462,127 @@
|
||||||
<value>Эта функция предназначена для продвинутых пользователей и особых случаев. После включения игнорируются базовые настройки ядра, DNS и маршрутизации. Вы должны самостоятельно корректно задать порт системного прокси, учёт трафика и другие связанные параметры — всё настраивается вручную.</value>
|
<value>Эта функция предназначена для продвинутых пользователей и особых случаев. После включения игнорируются базовые настройки ядра, DNS и маршрутизации. Вы должны самостоятельно корректно задать порт системного прокси, учёт трафика и другие связанные параметры — всё настраивается вручную.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgStartParsingSubscription" xml:space="preserve">
|
<data name="MsgStartParsingSubscription" xml:space="preserve">
|
||||||
<value>Start parsing and processing subscription content</value>
|
<value>Начинается разбор и обработка содержимого подписки</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSelectProfile" xml:space="preserve">
|
<data name="TbSelectProfile" xml:space="preserve">
|
||||||
<value>Select Profile</value>
|
<value>Выбрать профиль</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbFakeIPTips" xml:space="preserve">
|
<data name="TbFakeIPTips" xml:space="preserve">
|
||||||
<value>Applies globally by default, with built-in FakeIP filtering (sing-box only).</value>
|
<value>По умолчанию применяется глобально, со встроенной фильтрацией FakeIP (только sing-box).</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PleaseAddAtLeastOneServer" xml:space="preserve">
|
<data name="PleaseAddAtLeastOneServer" xml:space="preserve">
|
||||||
<value>Please Add At Least One Configuration</value>
|
<value>Добавьте хотя бы одну конфигурацию</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbConfigTypePolicyGroup" xml:space="preserve">
|
<data name="TbConfigTypePolicyGroup" xml:space="preserve">
|
||||||
<value>Policy Group</value>
|
<value>Группа политик</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbConfigTypeProxyChain" xml:space="preserve">
|
<data name="TbConfigTypeProxyChain" xml:space="preserve">
|
||||||
<value>Proxy Chain</value>
|
<value>Цепочка прокси</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbLeastPing" xml:space="preserve">
|
<data name="TbLeastPing" xml:space="preserve">
|
||||||
<value>Lowest Latency</value>
|
<value>Наименьшая задержка</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRandom" xml:space="preserve">
|
<data name="TbRandom" xml:space="preserve">
|
||||||
<value>Random</value>
|
<value>Случайный</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRoundRobin" xml:space="preserve">
|
<data name="TbRoundRobin" xml:space="preserve">
|
||||||
<value>Round Robin</value>
|
<value>Циклический (Round Robin)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbLeastLoad" xml:space="preserve">
|
<data name="TbLeastLoad" xml:space="preserve">
|
||||||
<value>Most Stable</value>
|
<value>Наиболее стабильный</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbPolicyGroupType" xml:space="preserve">
|
<data name="TbPolicyGroupType" xml:space="preserve">
|
||||||
<value>Policy Group Type</value>
|
<value>Тип группы политик</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddPolicyGroupServer" xml:space="preserve">
|
<data name="menuAddPolicyGroupServer" xml:space="preserve">
|
||||||
<value>Add Policy Group Configuration</value>
|
<value>Добавить группу политик </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddProxyChainServer" xml:space="preserve">
|
<data name="menuAddProxyChainServer" xml:space="preserve">
|
||||||
<value>Add Proxy Chain Configuration</value>
|
<value>Добавить цепочку прокси</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddChildServer" xml:space="preserve">
|
<data name="menuAddChildServer" xml:space="preserve">
|
||||||
<value>Add Child Configuration</value>
|
<value>Добавить дочернюю конфигурацию </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuRemoveChildServer" xml:space="preserve">
|
<data name="menuRemoveChildServer" xml:space="preserve">
|
||||||
<value>Remove Child Configuration</value>
|
<value>Удалить дочернюю конфигурацию </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuServerList" xml:space="preserve">
|
<data name="menuServerList" xml:space="preserve">
|
||||||
<value>Configuration item 1, Auto add from subscription group</value>
|
<value>Конфигурация 1: автодобавление из группы подписки</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbFallback" xml:space="preserve">
|
<data name="TbFallback" xml:space="preserve">
|
||||||
<value>Fallback</value>
|
<value>Резервный (Fallback)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgCoreNotSupportNetwork" xml:space="preserve">
|
<data name="MsgCoreNotSupportNetwork" xml:space="preserve">
|
||||||
<value>Core '{0}' does not support network type '{1}'</value>
|
<value>Ядро «{0}» не поддерживает тип сети «{1}»</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgCoreNotSupportProtocolTransport" xml:space="preserve">
|
<data name="MsgCoreNotSupportProtocolTransport" xml:space="preserve">
|
||||||
<value>Core '{0}' does not support protocol '{1}' when using transport '{2}'</value>
|
<value>Ядро «{0}» не поддерживает протокол «{1}» при транспорте «{2}»</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgCoreNotSupportProtocol" xml:space="preserve">
|
<data name="MsgCoreNotSupportProtocol" xml:space="preserve">
|
||||||
<value>Core '{0}' does not support protocol '{1}'</value>
|
<value>Ядро «{0}» не поддерживает протокол «{1}»</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgInvalidProperty" xml:space="preserve">
|
<data name="MsgInvalidProperty" xml:space="preserve">
|
||||||
<value>The {0} property is invalid, please check</value>
|
<value>Свойство {0} недопустимо, проверьте его</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgNotSupportProtocol" xml:space="preserve">
|
<data name="MsgNotSupportProtocol" xml:space="preserve">
|
||||||
<value>Not support protocol '{0}'</value>
|
<value>Протокол «{0}» не поддерживается</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsHide2TrayWhenCloseTip" xml:space="preserve">
|
<data name="TbSettingsHide2TrayWhenCloseTip" xml:space="preserve">
|
||||||
<value>If the system does not have a tray function, please do not enable it</value>
|
<value>Если в системе нет функции трея, не включайте эту опцию</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRuleTypeTips" xml:space="preserve">
|
<data name="TbRuleTypeTips" xml:space="preserve">
|
||||||
<value>You can set separate rules for Routing and DNS, or select "ALL" to apply to both</value>
|
<value>Можно задать отдельные правила для маршрутизации и DNS или выбрать «ALL» для применения к обоим</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRuleType" xml:space="preserve">
|
<data name="TbRuleType" xml:space="preserve">
|
||||||
<value>Rule Type</value>
|
<value>Тип правила</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbBootstrapDNS" xml:space="preserve">
|
<data name="TbBootstrapDNS" xml:space="preserve">
|
||||||
<value>Bootstrap DNS</value>
|
<value>Bootstrap DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbBootstrapDNSTips" xml:space="preserve">
|
<data name="TbBootstrapDNSTips" xml:space="preserve">
|
||||||
<value>Resolve DNS server domains, requires IP</value>
|
<value>Разрешает домены DNS-серверов, требуется IP-адрес</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuFastRealPing" xml:space="preserve">
|
<data name="menuFastRealPing" xml:space="preserve">
|
||||||
<value>Test real delay</value>
|
<value>Тест реальной задержки</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbPolicyGroupSubChildTip" xml:space="preserve">
|
<data name="TbPolicyGroupSubChildTip" xml:space="preserve">
|
||||||
<value>Auto add filtered configuration from subscription groups</value>
|
<value>Автодобавление отфильтрованных конфигураций из групп подписки</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCertPinning" xml:space="preserve">
|
<data name="TbCertPinning" xml:space="preserve">
|
||||||
<value>Certificate Pinning</value>
|
<value>Привязка сертификата</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCertPinningTips" xml:space="preserve">
|
<data name="TbCertPinningTips" xml:space="preserve">
|
||||||
<value>Pinned certificate (fill in either one)
|
<value>Привязанный сертификат (заполните любое из полей)
|
||||||
When specified, the certificate will be pinned, and "Allow Insecure" will be disabled.
|
При указании сертификат будет привязан, а «Разрешить небезопасные» отключится.
|
||||||
|
|
||||||
The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA.</value>
|
Получение сертификата может завершиться неудачей при использовании самоподписанного сертификата или при наличии ненадёжного / вредоносного ЦС в системе.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbFetchCert" xml:space="preserve">
|
<data name="TbFetchCert" xml:space="preserve">
|
||||||
<value>Fetch Certificate</value>
|
<value>Получить сертификат</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbFetchCertChain" xml:space="preserve">
|
<data name="TbFetchCertChain" xml:space="preserve">
|
||||||
<value>Fetch Certificate Chain</value>
|
<value>Получить цепочку сертификатов</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ServerNameMustBeValidDomain" xml:space="preserve">
|
<data name="ServerNameMustBeValidDomain" xml:space="preserve">
|
||||||
<value>Please set a valid domain</value>
|
<value>Укажите корректный домен</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="CertNotSet" xml:space="preserve">
|
<data name="CertNotSet" xml:space="preserve">
|
||||||
<value>Certificate not set</value>
|
<value>Сертификат не задан</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="CertSet" xml:space="preserve">
|
<data name="CertSet" xml:space="preserve">
|
||||||
<value>Certificate set</value>
|
<value>Сертификат задан</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsCustomSystemProxyPacPath" xml:space="preserve">
|
<data name="TbSettingsCustomSystemProxyPacPath" xml:space="preserve">
|
||||||
<value>Custom PAC file path</value>
|
<value>Путь к пользовательскому PAC-файлу</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsCustomSystemProxyScriptPath" xml:space="preserve">
|
<data name="TbSettingsCustomSystemProxyScriptPath" xml:space="preserve">
|
||||||
<value>Custom system proxy script file path</value>
|
<value>Путь к скрипту системного прокси</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsMacOSShowInDock" xml:space="preserve">
|
<data name="TbSettingsMacOSShowInDock" xml:space="preserve">
|
||||||
<value>macOS displays this in the Dock (requires restart)</value>
|
<value>Отображать в Dock на macOS (требуется перезапуск)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuServerList2" xml:space="preserve">
|
<data name="menuServerList2" xml:space="preserve">
|
||||||
<value>Configuration Item 2, Select and add from self-built</value>
|
<value>Конфигурация 2: выбор и добавление из собственных</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbEchConfigList" xml:space="preserve">
|
<data name="TbEchConfigList" xml:space="preserve">
|
||||||
<value>EchConfigList</value>
|
<value>EchConfigList</value>
|
||||||
|
|
@ -1591,81 +1591,105 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||||
<value>EchForceQuery</value>
|
<value>EchForceQuery</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbFullCertTips" xml:space="preserve">
|
<data name="TbFullCertTips" xml:space="preserve">
|
||||||
<value>Full certificate (chain), PEM format</value>
|
<value>Полный сертификат (цепочка) в формате PEM</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbCertSha256Tips" xml:space="preserve">
|
<data name="TbCertSha256Tips" xml:space="preserve">
|
||||||
<value>Certificate fingerprint (SHA-256)</value>
|
<value>Отпечаток сертификата (SHA-256)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbServeStale" xml:space="preserve">
|
<data name="TbServeStale" xml:space="preserve">
|
||||||
<value>Serve Stale</value>
|
<value>Отдавать устаревшие записи (Serve Stale)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbParallelQuery" xml:space="preserve">
|
<data name="TbParallelQuery" xml:space="preserve">
|
||||||
<value>Parallel Query</value>
|
<value>Параллельные запросы</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbDomesticDNSTips" xml:space="preserve">
|
<data name="TbDomesticDNSTips" xml:space="preserve">
|
||||||
<value>By default, invoked only during routing for resolution</value>
|
<value>По умолчанию используется только при разрешении имён в процессе маршрутизации</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRemoteDNSTips" xml:space="preserve">
|
<data name="TbRemoteDNSTips" xml:space="preserve">
|
||||||
<value>By default, invoked only during routing for resolution; ensure the remote server can reach this DNS</value>
|
<value>По умолчанию используется только при разрешении имён в процессе маршрутизации; убедитесь, что удалённый сервер может достичь этого DNS</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbDirectResolveStrategyTips" xml:space="preserve">
|
<data name="TbDirectResolveStrategyTips" xml:space="preserve">
|
||||||
<value>If unset or "AsIs", DNS resolution uses the system DNS; otherwise, the internal DNS module is used.</value>
|
<value>Если не задано или «AsIs», используется системный DNS; иначе — встроенный DNS-модуль.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRemoteResolveStrategyTips" xml:space="preserve">
|
<data name="TbRemoteResolveStrategyTips" xml:space="preserve">
|
||||||
<value>If unset or "AsIs", DNS resolution is performed by the remote server's DNS; otherwise, the internal DNS module is used.</value>
|
<value>Если не задано или «AsIs», разрешение DNS выполняется DNS удалённого сервера; иначе — встроенный DNS-модуль.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbHopInt7" xml:space="preserve">
|
<data name="TbHopInt7" xml:space="preserve">
|
||||||
<value>Port hopping interval</value>
|
<value>Интервал смены портов (Port Hopping)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuServerListPreview" xml:space="preserve">
|
<data name="menuServerListPreview" xml:space="preserve">
|
||||||
<value>Configuration item preview</value>
|
<value>Предпросмотр конфигурации</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbFinalmask" xml:space="preserve">
|
<data name="TbFinalmask" xml:space="preserve">
|
||||||
<value>Finalmask</value>
|
<value>Finalmask</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgRoutingRuleOutboundNodeWarning" xml:space="preserve">
|
<data name="MsgRoutingRuleOutboundNodeWarning" xml:space="preserve">
|
||||||
<value>Routing rule {0} outbound node {1} warning: {2}</value>
|
<value>Правило маршрутизации {0}, исходящий узел {1}, предупреждение: {2}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgRoutingRuleOutboundNodeError" xml:space="preserve">
|
<data name="MsgRoutingRuleOutboundNodeError" xml:space="preserve">
|
||||||
<value>Routing rule {0} outbound node {1} error: {2}. Fallback to proxy node only.</value>
|
<value>Правило маршрутизации {0}, исходящий узел {1}, ошибка: {2}. Используется только прокси-узел.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgGroupCycleDependency" xml:space="preserve">
|
<data name="MsgGroupCycleDependency" xml:space="preserve">
|
||||||
<value>Group {0} has a cycle dependency on child node {1}. Skipping this node.</value>
|
<value>Группа {0} имеет циклическую зависимость на дочерний узел {1}. Узел пропущен.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgGroupChildNodeWarning" xml:space="preserve">
|
<data name="MsgGroupChildNodeWarning" xml:space="preserve">
|
||||||
<value>Group {0} child node {1} warning: {2}</value>
|
<value>Группа {0}: предупреждение дочернего узла {1}: {2}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgGroupChildNodeError" xml:space="preserve">
|
<data name="MsgGroupChildNodeError" xml:space="preserve">
|
||||||
<value>Group {0} child node {1} error: {2}. Skipping this node.</value>
|
<value>Группа {0}: ошибка дочернего узла {1}: {2}. Узел пропущен.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgGroupChildGroupNodeWarning" xml:space="preserve">
|
<data name="MsgGroupChildGroupNodeWarning" xml:space="preserve">
|
||||||
<value>Group {0} child group node {1} warning: {2}</value>
|
<value>Группа {0}: предупреждение дочернего узла группы {1}: {2}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgGroupChildGroupNodeError" xml:space="preserve">
|
<data name="MsgGroupChildGroupNodeError" xml:space="preserve">
|
||||||
<value>Group {0} child group node {1} error: {2}. Skipping this node.</value>
|
<value>Группа {0}: ошибка дочернего узла группы {1}: {2}. Узел пропущен.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgGroupNoValidChildNode" xml:space="preserve">
|
<data name="MsgGroupNoValidChildNode" xml:space="preserve">
|
||||||
<value>Group {0} has no valid child node.</value>
|
<value>У группы {0} нет допустимых дочерних узлов.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgRoutingRuleEmptyOutboundTag" xml:space="preserve">
|
<data name="MsgRoutingRuleEmptyOutboundTag" xml:space="preserve">
|
||||||
<value>Routing rule {0} has an empty outbound tag. Fallback to proxy node only.</value>
|
<value>У правила маршрутизации {0} пустой исходящий тег. Используется только прокси-узел.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgRoutingRuleOutboundNodeNotFound" xml:space="preserve">
|
<data name="MsgRoutingRuleOutboundNodeNotFound" xml:space="preserve">
|
||||||
<value>Routing rule {0} outbound node {1} not found. Fallback to proxy node only.</value>
|
<value>Правило маршрутизации {0}, исходящий узел {1} не найден. Используется только прокси-узел.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgSubscriptionPrevProfileNotFound" xml:space="preserve">
|
<data name="MsgSubscriptionPrevProfileNotFound" xml:space="preserve">
|
||||||
<value>Subscription previous proxy {0} not found. Skipping.</value>
|
<value>Предыдущий прокси подписки {0} не найден. Пропущено.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgSubscriptionNextProfileNotFound" xml:space="preserve">
|
<data name="MsgSubscriptionNextProfileNotFound" xml:space="preserve">
|
||||||
<value>Subscription next proxy {0} not found. Skipping.</value>
|
<value>Следующий прокси подписки {0} не найден. Пропущено.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuGenGroupServer" xml:space="preserve">
|
<data name="menuGenGroupServer" xml:space="preserve">
|
||||||
<value>Generate Policy Group</value>
|
<value>Сгенерировать группу политик</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAllServers" xml:space="preserve">
|
<data name="menuAllServers" xml:space="preserve">
|
||||||
<value>All configurations</value>
|
<value>Все конфигурации</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuGenRegionGroup" xml:space="preserve">
|
<data name="menuGenRegionGroup" xml:space="preserve">
|
||||||
<value>Group by Region</value>
|
<value>Группировка по регионам</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditCopy" xml:space="preserve">
|
||||||
|
<value>Скопировать</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditSelectAll" xml:space="preserve">
|
||||||
|
<value>Выбрать все</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditPaste" xml:space="preserve">
|
||||||
|
<value>Paste</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditFormat" xml:space="preserve">
|
||||||
|
<value>Format</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUot" xml:space="preserve">
|
||||||
|
<value>UDP over TCP</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||||
|
<value>Добавить сервер [NaïveProxy]</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||||
|
<value>Insecure Concurrency</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUsername" xml:space="preserve">
|
||||||
|
<value>Username</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -517,16 +517,16 @@
|
||||||
<value>添加 [Shadowsocks]</value>
|
<value>添加 [Shadowsocks]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddSocksServer" xml:space="preserve">
|
<data name="menuAddSocksServer" xml:space="preserve">
|
||||||
<value>添加 [SOCKS] </value>
|
<value>添加 [SOCKS]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddTrojanServer" xml:space="preserve">
|
<data name="menuAddTrojanServer" xml:space="preserve">
|
||||||
<value>添加 [Trojan] </value>
|
<value>添加 [Trojan]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddVlessServer" xml:space="preserve">
|
<data name="menuAddVlessServer" xml:space="preserve">
|
||||||
<value>添加 [VLESS] </value>
|
<value>添加 [VLESS]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddVmessServer" xml:space="preserve">
|
<data name="menuAddVmessServer" xml:space="preserve">
|
||||||
<value>添加 [VMess] </value>
|
<value>添加 [VMess]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuSelectAll" xml:space="preserve">
|
<data name="menuSelectAll" xml:space="preserve">
|
||||||
<value>全选</value>
|
<value>全选</value>
|
||||||
|
|
@ -1033,7 +1033,7 @@
|
||||||
<value>Domain</value>
|
<value>Domain</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddHysteria2Server" xml:space="preserve">
|
<data name="menuAddHysteria2Server" xml:space="preserve">
|
||||||
<value>添加 [Hysteria2] </value>
|
<value>添加 [Hysteria2]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
|
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
|
||||||
<value>Hysteria 最大带宽 (Up/Dw)</value>
|
<value>Hysteria 最大带宽 (Up/Dw)</value>
|
||||||
|
|
@ -1042,7 +1042,7 @@
|
||||||
<value>使用系统 hosts</value>
|
<value>使用系统 hosts</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddTuicServer" xml:space="preserve">
|
<data name="menuAddTuicServer" xml:space="preserve">
|
||||||
<value>添加 [TUIC] </value>
|
<value>添加 [TUIC]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbHeaderType8" xml:space="preserve">
|
<data name="TbHeaderType8" xml:space="preserve">
|
||||||
<value>拥塞控制算法</value>
|
<value>拥塞控制算法</value>
|
||||||
|
|
@ -1072,7 +1072,7 @@
|
||||||
<value>启用 IPv6</value>
|
<value>启用 IPv6</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddWireguardServer" xml:space="preserve">
|
<data name="menuAddWireguardServer" xml:space="preserve">
|
||||||
<value>添加 [WireGuard] </value>
|
<value>添加 [WireGuard]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbPrivateKey" xml:space="preserve">
|
<data name="TbPrivateKey" xml:space="preserve">
|
||||||
<value>PrivateKey</value>
|
<value>PrivateKey</value>
|
||||||
|
|
@ -1102,7 +1102,7 @@
|
||||||
<value>*grpc Authority</value>
|
<value>*grpc Authority</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddHttpServer" xml:space="preserve">
|
<data name="menuAddHttpServer" xml:space="preserve">
|
||||||
<value>添加 [HTTP] </value>
|
<value>添加 [HTTP]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||||
<value>启用分片 (Fragment)</value>
|
<value>启用分片 (Fragment)</value>
|
||||||
|
|
@ -1381,7 +1381,7 @@
|
||||||
<value>Mldsa65Verify</value>
|
<value>Mldsa65Verify</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||||
<value>添加 [Anytls] </value>
|
<value>添加 [Anytls]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbRemoteDNS" xml:space="preserve">
|
<data name="TbRemoteDNS" xml:space="preserve">
|
||||||
<value>远程 DNS</value>
|
<value>远程 DNS</value>
|
||||||
|
|
@ -1665,4 +1665,28 @@
|
||||||
<data name="menuGenRegionGroup" xml:space="preserve">
|
<data name="menuGenRegionGroup" xml:space="preserve">
|
||||||
<value>按地区分组</value>
|
<value>按地区分组</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuEditCopy" xml:space="preserve">
|
||||||
|
<value>复制</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditSelectAll" xml:space="preserve">
|
||||||
|
<value>全选</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditPaste" xml:space="preserve">
|
||||||
|
<value>粘贴</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditFormat" xml:space="preserve">
|
||||||
|
<value>格式化</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUot" xml:space="preserve">
|
||||||
|
<value>UDP over TCP</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||||
|
<value>添加 [NaïveProxy]</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||||
|
<value>不安全并发</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUsername" xml:space="preserve">
|
||||||
|
<value>用户名</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1665,4 +1665,28 @@
|
||||||
<data name="menuGenRegionGroup" xml:space="preserve">
|
<data name="menuGenRegionGroup" xml:space="preserve">
|
||||||
<value>按區域分組</value>
|
<value>按區域分組</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuEditCopy" xml:space="preserve">
|
||||||
|
<value>複製</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditSelectAll" xml:space="preserve">
|
||||||
|
<value>全選</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditPaste" xml:space="preserve">
|
||||||
|
<value>Paste</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuEditFormat" xml:space="preserve">
|
||||||
|
<value>Format</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUot" xml:space="preserve">
|
||||||
|
<value>UDP over TCP</value>
|
||||||
|
</data>
|
||||||
|
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||||
|
<value>新增 [NaïveProxy] 節點</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||||
|
<value>Insecure Concurrency</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbUsername" xml:space="preserve">
|
||||||
|
<value>Username</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -112,6 +112,7 @@ public partial class CoreConfigSingboxService
|
||||||
outbound.method = AppManager.Instance.GetShadowsocksSecurities(_node).Contains(protocolExtra.SsMethod)
|
outbound.method = AppManager.Instance.GetShadowsocksSecurities(_node).Contains(protocolExtra.SsMethod)
|
||||||
? protocolExtra.SsMethod : Global.None;
|
? protocolExtra.SsMethod : Global.None;
|
||||||
outbound.password = _node.Password;
|
outbound.password = _node.Password;
|
||||||
|
outbound.udp_over_tcp = protocolExtra.Uot == true ? true : null;
|
||||||
|
|
||||||
if (_node.Network == nameof(ETransport.tcp) && _node.HeaderType == Global.TcpHeaderHttp)
|
if (_node.Network == nameof(ETransport.tcp) && _node.HeaderType == Global.TcpHeaderHttp)
|
||||||
{
|
{
|
||||||
|
|
@ -269,7 +270,7 @@ public partial class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
outbound.uuid = _node.Username;
|
outbound.uuid = _node.Username;
|
||||||
outbound.password = _node.Password;
|
outbound.password = _node.Password;
|
||||||
outbound.congestion_control = _node.HeaderType;
|
outbound.congestion_control = protocolExtra.CongestionControl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EConfigType.Anytls:
|
case EConfigType.Anytls:
|
||||||
|
|
@ -277,6 +278,22 @@ public partial class CoreConfigSingboxService
|
||||||
outbound.password = _node.Password;
|
outbound.password = _node.Password;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case EConfigType.Naive:
|
||||||
|
{
|
||||||
|
outbound.username = _node.Username;
|
||||||
|
outbound.password = _node.Password;
|
||||||
|
if (outbound.network == "quic")
|
||||||
|
{
|
||||||
|
outbound.quic = true;
|
||||||
|
outbound.quic_congestion_control = protocolExtra.CongestionControl.NullIfEmpty();
|
||||||
|
}
|
||||||
|
if (protocolExtra.InsecureConcurrency > 0)
|
||||||
|
{
|
||||||
|
outbound.insecure_concurrency = protocolExtra.InsecureConcurrency;
|
||||||
|
}
|
||||||
|
outbound.udp_over_tcp = protocolExtra.Uot == true ? true : null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FillOutboundTls(outbound);
|
FillOutboundTls(outbound);
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,7 @@ public partial class CoreConfigV2rayService
|
||||||
serversItem.password = _node.Password;
|
serversItem.password = _node.Password;
|
||||||
serversItem.method = AppManager.Instance.GetShadowsocksSecurities(_node).Contains(protocolExtra.SsMethod)
|
serversItem.method = AppManager.Instance.GetShadowsocksSecurities(_node).Contains(protocolExtra.SsMethod)
|
||||||
? protocolExtra.SsMethod : "none";
|
? protocolExtra.SsMethod : "none";
|
||||||
|
serversItem.uot = protocolExtra.Uot == true ? true : null;
|
||||||
|
|
||||||
serversItem.ota = false;
|
serversItem.ota = false;
|
||||||
serversItem.level = 1;
|
serversItem.level = 1;
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,15 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public int WgMtu { get; set; }
|
public int WgMtu { get; set; }
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public bool Uot { get; set; }
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public string CongestionControl { get; set; }
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public int InsecureConcurrency { get; set; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> FetchCertCmd { get; }
|
public ReactiveCommand<Unit, Unit> FetchCertCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> FetchCertChainCmd { get; }
|
public ReactiveCommand<Unit, Unit> FetchCertChainCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||||
|
|
@ -123,6 +132,9 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
WgInterfaceAddress = protocolExtra?.WgInterfaceAddress ?? string.Empty;
|
WgInterfaceAddress = protocolExtra?.WgInterfaceAddress ?? string.Empty;
|
||||||
WgReserved = protocolExtra?.WgReserved ?? string.Empty;
|
WgReserved = protocolExtra?.WgReserved ?? string.Empty;
|
||||||
WgMtu = protocolExtra?.WgMtu ?? 1280;
|
WgMtu = protocolExtra?.WgMtu ?? 1280;
|
||||||
|
Uot = protocolExtra?.Uot ?? false;
|
||||||
|
CongestionControl = protocolExtra?.CongestionControl ?? string.Empty;
|
||||||
|
InsecureConcurrency = protocolExtra?.InsecureConcurrency ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveServerAsync()
|
private async Task SaveServerAsync()
|
||||||
|
|
@ -185,6 +197,9 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
WgInterfaceAddress = WgInterfaceAddress.NullIfEmpty(),
|
WgInterfaceAddress = WgInterfaceAddress.NullIfEmpty(),
|
||||||
WgReserved = WgReserved.NullIfEmpty(),
|
WgReserved = WgReserved.NullIfEmpty(),
|
||||||
WgMtu = WgMtu >= 576 ? WgMtu : null,
|
WgMtu = WgMtu >= 576 ? WgMtu : null,
|
||||||
|
Uot = Uot ? true : null,
|
||||||
|
CongestionControl = CongestionControl.NullIfEmpty(),
|
||||||
|
InsecureConcurrency = InsecureConcurrency > 0 ? InsecureConcurrency : null
|
||||||
});
|
});
|
||||||
|
|
||||||
if (await ConfigHandler.AddServer(_config, SelectedSource) == 0)
|
if (await ConfigHandler.AddServer(_config, SelectedSource) == 0)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddWireguardServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddWireguardServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddAnytlsServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddAnytlsServerCmd { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> AddNaiveServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddCustomServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddCustomServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddPolicyGroupServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddPolicyGroupServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddProxyChainServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddProxyChainServerCmd { get; }
|
||||||
|
|
@ -117,6 +118,10 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
await AddServerAsync(EConfigType.Anytls);
|
await AddServerAsync(EConfigType.Anytls);
|
||||||
});
|
});
|
||||||
|
AddNaiveServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
|
{
|
||||||
|
await AddServerAsync(EConfigType.Naive);
|
||||||
|
});
|
||||||
AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
await AddServerAsync(EConfigType.Custom);
|
await AddServerAsync(EConfigType.Custom);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
|
xmlns:views="clr-namespace:v2rayN.Desktop.Views"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuServers}"
|
Title="{x:Static resx:ResUI.menuServers}"
|
||||||
Width="900"
|
Width="900"
|
||||||
|
|
@ -197,6 +198,19 @@
|
||||||
Width="300"
|
Width="300"
|
||||||
Margin="{StaticResource Margin4}" />
|
Margin="{StaticResource Margin4}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbUot}" />
|
||||||
|
<ToggleSwitch
|
||||||
|
x:Name="togUotEnabled3"
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="4"
|
Grid.Row="4"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
|
|
@ -580,12 +594,84 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{x:Static resx:ResUI.TbId3}" />
|
Text="{x:Static resx:ResUI.TbId3}" />
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txtId10"
|
x:Name="txtId11"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}" />
|
Margin="{StaticResource Margin4}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
x:Name="gridNaive"
|
||||||
|
Grid.Row="2"
|
||||||
|
ColumnDefinitions="300,Auto"
|
||||||
|
IsVisible="False"
|
||||||
|
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto">
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbUsername}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtId12"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbId3}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtSecurity12"
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbInsecureConcurrency}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtInsecureConcurrency12"
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="4"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbHeaderType8}" />
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbHeaderType12"
|
||||||
|
Grid.Row="4"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="5"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbUot}" />
|
||||||
|
<ToggleSwitch
|
||||||
|
x:Name="togUotEnabled12"
|
||||||
|
Grid.Row="5"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Separator
|
<Separator
|
||||||
x:Name="sepa2"
|
x:Name="sepa2"
|
||||||
|
|
@ -658,16 +744,13 @@
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{x:Static resx:ResUI.TransportExtraTip}" />
|
Text="{x:Static resx:ResUI.TransportExtraTip}" />
|
||||||
<TextBox
|
<views:JsonEditor
|
||||||
x:Name="txtExtra"
|
x:Name="txtExtra"
|
||||||
Width="400"
|
Width="400"
|
||||||
MinHeight="100"
|
MinHeight="100"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center" />
|
||||||
Classes="TextArea"
|
|
||||||
MinLines="6"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Flyout>
|
</Flyout>
|
||||||
</Button.Flyout>
|
</Button.Flyout>
|
||||||
|
|
@ -749,13 +832,13 @@
|
||||||
<Button.Flyout>
|
<Button.Flyout>
|
||||||
<Flyout>
|
<Flyout>
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<TextBox
|
<views:JsonEditor
|
||||||
x:Name="txtFinalmask"
|
x:Name="txtFinalmask"
|
||||||
Width="400"
|
Width="400"
|
||||||
|
MinHeight="100"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
AcceptsReturn="True"
|
HorizontalAlignment="Stretch"
|
||||||
Classes="TextArea"
|
VerticalAlignment="Center" />
|
||||||
TextWrapping="NoWrap" />
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Flyout>
|
</Flyout>
|
||||||
</Button.Flyout>
|
</Button.Flyout>
|
||||||
|
|
|
||||||
|
|
@ -94,10 +94,24 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||||
|
|
||||||
case EConfigType.Anytls:
|
case EConfigType.Anytls:
|
||||||
gridAnytls.IsVisible = true;
|
gridAnytls.IsVisible = true;
|
||||||
|
sepa2.IsVisible = false;
|
||||||
|
gridTransport.IsVisible = false;
|
||||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||||
cmbCoreType.IsEnabled = false;
|
cmbCoreType.IsEnabled = false;
|
||||||
gridFinalmask.IsVisible = false;
|
gridFinalmask.IsVisible = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EConfigType.Naive:
|
||||||
|
gridNaive.IsVisible = true;
|
||||||
|
cmbCoreType.IsEnabled = false;
|
||||||
|
gridFinalmask.IsVisible = false;
|
||||||
|
cmbFingerprint.IsEnabled = false;
|
||||||
|
cmbFingerprint.SelectedValue = string.Empty;
|
||||||
|
cmbAllowInsecure.IsEnabled = false;
|
||||||
|
cmbAllowInsecure.SelectedValue = string.Empty;
|
||||||
|
|
||||||
|
cmbHeaderType12.ItemsSource = Global.NaiveCongestionControls;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||||
|
|
||||||
|
|
@ -122,6 +136,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||||
case EConfigType.Shadowsocks:
|
case EConfigType.Shadowsocks:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId3.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId3.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SsMethod, v => v.cmbSecurity3.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SsMethod, v => v.cmbSecurity3.SelectedValue).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled3.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.MuxEnabled, v => v.togmuxEnabled3.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.MuxEnabled, v => v.togmuxEnabled3.IsChecked).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -156,7 +171,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||||
case EConfigType.TUIC:
|
case EConfigType.TUIC:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId8.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId8.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity8.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity8.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType8.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CongestionControl, v => v.cmbHeaderType8.SelectedValue).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.WireGuard:
|
case EConfigType.WireGuard:
|
||||||
|
|
@ -168,7 +183,15 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.Anytls:
|
case EConfigType.Anytls:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId10.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId11.Text).DisposeWith(disposables);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EConfigType.Naive:
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId12.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity12.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.InsecureConcurrency, v => v.txtInsecureConcurrency12.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.CongestionControl, v => v.cmbHeaderType12.SelectedValue).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled12.IsChecked).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="using:v2rayN.Desktop.Views"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
|
|
@ -399,12 +400,7 @@
|
||||||
BorderBrush="Gray"
|
BorderBrush="Gray"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="HTTP/SOCKS">
|
Header="HTTP/SOCKS">
|
||||||
<TextBox
|
<local:JsonEditor Name="txtnormalDNSCompatible" VerticalAlignment="Stretch" />
|
||||||
Name="txtnormalDNSCompatible"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Classes="TextArea"
|
|
||||||
MinLines="10"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</HeaderedContentControl>
|
</HeaderedContentControl>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
@ -473,12 +469,7 @@
|
||||||
BorderBrush="Gray"
|
BorderBrush="Gray"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="HTTP/SOCKS">
|
Header="HTTP/SOCKS">
|
||||||
<TextBox
|
<local:JsonEditor Name="txtnormalDNS2Compatible" VerticalAlignment="Stretch" />
|
||||||
Name="txtnormalDNS2Compatible"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Classes="TextArea"
|
|
||||||
MinLines="10"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</HeaderedContentControl>
|
</HeaderedContentControl>
|
||||||
|
|
||||||
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
||||||
|
|
@ -488,12 +479,7 @@
|
||||||
BorderBrush="Gray"
|
BorderBrush="Gray"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="{x:Static resx:ResUI.TbSettingsTunMode}">
|
Header="{x:Static resx:ResUI.TbSettingsTunMode}">
|
||||||
<TextBox
|
<local:JsonEditor Name="txttunDNS2Compatible" VerticalAlignment="Stretch" />
|
||||||
Name="txttunDNS2Compatible"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Classes="TextArea"
|
|
||||||
MinLines="10"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</HeaderedContentControl>
|
</HeaderedContentControl>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
|
xmlns:views="clr-namespace:v2rayN.Desktop.Views"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuFullConfigTemplate}"
|
Title="{x:Static resx:ResUI.menuFullConfigTemplate}"
|
||||||
Width="900"
|
Width="900"
|
||||||
|
|
@ -94,12 +95,7 @@
|
||||||
BorderBrush="Gray"
|
BorderBrush="Gray"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="xray config template json">
|
Header="xray config template json">
|
||||||
<TextBox
|
<views:JsonEditor x:Name="rayFullConfigTemplate" VerticalAlignment="Stretch" />
|
||||||
x:Name="rayFullConfigTemplate"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Classes="TextArea"
|
|
||||||
MinLines="10"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</HeaderedContentControl>
|
</HeaderedContentControl>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
@ -166,12 +162,7 @@
|
||||||
BorderBrush="Gray"
|
BorderBrush="Gray"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="sing-box config template json">
|
Header="sing-box config template json">
|
||||||
<TextBox
|
<views:JsonEditor x:Name="sbFullConfigTemplate" VerticalAlignment="Stretch" />
|
||||||
x:Name="sbFullConfigTemplate"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Classes="TextArea"
|
|
||||||
MinLines="10"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</HeaderedContentControl>
|
</HeaderedContentControl>
|
||||||
|
|
||||||
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
||||||
|
|
@ -181,12 +172,7 @@
|
||||||
BorderBrush="Gray"
|
BorderBrush="Gray"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Header="sing-box tun config template json">
|
Header="sing-box tun config template json">
|
||||||
<TextBox
|
<views:JsonEditor x:Name="sbFullTunConfigTemplate" VerticalAlignment="Stretch" />
|
||||||
x:Name="sbFullTunConfigTemplate"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Classes="TextArea"
|
|
||||||
MinLines="10"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</HeaderedContentControl>
|
</HeaderedContentControl>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
|
|
|
||||||
23
v2rayN/v2rayN.Desktop/Views/JsonEditor.axaml
Normal file
23
v2rayN/v2rayN.Desktop/Views/JsonEditor.axaml
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="v2rayN.Desktop.Views.JsonEditor"
|
||||||
|
xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:ae="clr-namespace:AvaloniaEdit;assembly=AvaloniaEdit"
|
||||||
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib">
|
||||||
|
|
||||||
|
<ae:TextEditor
|
||||||
|
Name="Editor"
|
||||||
|
FontFamily="Cascadia Code,Consolas,Monospace"
|
||||||
|
FontSize="14"
|
||||||
|
ShowLineNumbers="True">
|
||||||
|
<ae:TextEditor.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem Click="FormatJson_Click" Header="{x:Static resx:ResUI.menuEditFormat}" />
|
||||||
|
<Separator />
|
||||||
|
<MenuItem Click="Copy_Click" Header="{x:Static resx:ResUI.menuEditCopy}" />
|
||||||
|
<MenuItem Click="Paste_Click" Header="{x:Static resx:ResUI.menuEditPaste}" />
|
||||||
|
<MenuItem Click="SelectAll_Click" Header="{x:Static resx:ResUI.menuEditSelectAll}" />
|
||||||
|
</ContextMenu>
|
||||||
|
</ae:TextEditor.ContextMenu>
|
||||||
|
</ae:TextEditor>
|
||||||
|
</UserControl>
|
||||||
96
v2rayN/v2rayN.Desktop/Views/JsonEditor.axaml.cs
Normal file
96
v2rayN/v2rayN.Desktop/Views/JsonEditor.axaml.cs
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Xml;
|
||||||
|
using AvaloniaEdit.Highlighting;
|
||||||
|
using AvaloniaEdit.Highlighting.Xshd;
|
||||||
|
|
||||||
|
namespace v2rayN.Desktop.Views;
|
||||||
|
|
||||||
|
public partial class JsonEditor : UserControl
|
||||||
|
{
|
||||||
|
private static readonly JsonSerializerOptions SIndentedOptions = new() { WriteIndented = true };
|
||||||
|
|
||||||
|
private static readonly Lazy<IHighlightingDefinition> SHighlightingDark =
|
||||||
|
new(() => BuildHighlighting(dark: true), isThreadSafe: true);
|
||||||
|
|
||||||
|
private static readonly Lazy<IHighlightingDefinition> SHighlightingLight =
|
||||||
|
new(() => BuildHighlighting(dark: false), isThreadSafe: true);
|
||||||
|
|
||||||
|
public static readonly StyledProperty<string> TextProperty =
|
||||||
|
AvaloniaProperty.Register<JsonEditor, string>(nameof(Text), defaultValue: string.Empty);
|
||||||
|
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get => GetValue(TextProperty);
|
||||||
|
set => SetValue(TextProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonEditor()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
var isDark = Application.Current?.ActualThemeVariant != ThemeVariant.Light;
|
||||||
|
Editor.SyntaxHighlighting = isDark ? SHighlightingDark.Value : SHighlightingLight.Value;
|
||||||
|
Editor.TextArea.TextView.Options.EnableHyperlinks = false;
|
||||||
|
|
||||||
|
Editor.TextChanged += (_, _) =>
|
||||||
|
{
|
||||||
|
if (Text != Editor.Text)
|
||||||
|
{
|
||||||
|
SetCurrentValue(TextProperty, Editor.Text);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.GetObservable(TextProperty).Subscribe(text =>
|
||||||
|
{
|
||||||
|
if (Editor.Text != text)
|
||||||
|
{
|
||||||
|
Editor.Text = text ?? string.Empty;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IHighlightingDefinition BuildHighlighting(bool dark)
|
||||||
|
{
|
||||||
|
var keyColor = dark ? "#9CDCFE" : "#0451A5";
|
||||||
|
var strColor = dark ? "#CE9178" : "#A31515";
|
||||||
|
var numColor = dark ? "#B5CEA8" : "#098658";
|
||||||
|
var kwColor = dark ? "#569CD6" : "#0000FF";
|
||||||
|
var xshd = $"""
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<SyntaxDefinition name="JSON" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
|
||||||
|
<Color name="Key" foreground="{keyColor}" />
|
||||||
|
<Color name="String" foreground="{strColor}" />
|
||||||
|
<Color name="Number" foreground="{numColor}" />
|
||||||
|
<Color name="Keyword" foreground="{kwColor}" fontWeight="bold" />
|
||||||
|
<RuleSet>
|
||||||
|
<Rule color="Key">"([^"\\]|\\.)*"(?=\s*:)</Rule>
|
||||||
|
<Rule color="String">"([^"\\]|\\.)*"</Rule>
|
||||||
|
<Rule color="Number">-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?</Rule>
|
||||||
|
<Keywords color="Keyword">
|
||||||
|
<Word>true</Word>
|
||||||
|
<Word>false</Word>
|
||||||
|
<Word>null</Word>
|
||||||
|
</Keywords>
|
||||||
|
</RuleSet>
|
||||||
|
</SyntaxDefinition>
|
||||||
|
""";
|
||||||
|
using var reader = XmlReader.Create(new StringReader(xshd));
|
||||||
|
return HighlightingLoader.Load(reader, HighlightingManager.Instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FormatJson_Click(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var obj = JsonUtils.ParseJson(Editor.Text);
|
||||||
|
Editor.Text = JsonUtils.Serialize(obj, SIndentedOptions);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Copy_Click(object? sender, RoutedEventArgs e) => Editor.Copy();
|
||||||
|
private void Paste_Click(object? sender, RoutedEventArgs e) => Editor.Paste();
|
||||||
|
private void SelectAll_Click(object? sender, RoutedEventArgs e) => Editor.SelectAll();
|
||||||
|
}
|
||||||
|
|
@ -50,6 +50,7 @@
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem x:Name="menuAddTuicServer" Header="{x:Static resx:ResUI.menuAddTuicServer}" />
|
<MenuItem x:Name="menuAddTuicServer" Header="{x:Static resx:ResUI.menuAddTuicServer}" />
|
||||||
<MenuItem x:Name="menuAddAnytlsServer" Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
|
<MenuItem x:Name="menuAddAnytlsServer" Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
|
||||||
|
<MenuItem x:Name="menuAddNaiveServer" Header="{x:Static resx:ResUI.menuAddNaiveServer}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
<MenuItem Header="{x:Static resx:ResUI.menuSubscription}">
|
<MenuItem Header="{x:Static resx:ResUI.menuSubscription}">
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
||||||
|
this.BindCommand(ViewModel, vm => vm.AddNaiveServerCmd, v => v.menuAddNaiveServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddPolicyGroupServerCmd, v => v.menuAddPolicyGroupServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddPolicyGroupServerCmd, v => v.menuAddPolicyGroupServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddProxyChainServerCmd, v => v.menuAddProxyChainServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddProxyChainServerCmd, v => v.menuAddProxyChainServer).DisposeWith(disposables);
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,8 @@
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuMsgViewSelectAll"
|
x:Name="menuMsgViewSelectAll"
|
||||||
Click="menuMsgViewSelectAll_Click"
|
Click="menuMsgViewSelectAll_Click"
|
||||||
InputGesture="Ctrl+A"
|
Header="{x:Static resx:ResUI.menuMsgViewSelectAll}"
|
||||||
Header="{x:Static resx:ResUI.menuMsgViewSelectAll}" />
|
InputGesture="Ctrl+A" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuMsgViewCopy"
|
x:Name="menuMsgViewCopy"
|
||||||
Click="menuMsgViewCopy_Click"
|
Click="menuMsgViewCopy_Click"
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,20 @@
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Style="{StaticResource DefComboBox}" />
|
Style="{StaticResource DefComboBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbUot}" />
|
||||||
|
<ToggleButton
|
||||||
|
x:Name="togUotEnabled3"
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="4"
|
Grid.Row="4"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
|
|
@ -772,13 +786,106 @@
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
Text="{x:Static resx:ResUI.TbId3}" />
|
Text="{x:Static resx:ResUI.TbId3}" />
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="txtId10"
|
x:Name="txtId11"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
x:Name="gridNaive"
|
||||||
|
Grid.Row="2"
|
||||||
|
Visibility="Hidden">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="300" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbUsername}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtId12"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbId3}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtSecurity12"
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbInsecureConcurrency}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtInsecureConcurrency12"
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="4"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbHeaderType8}" />
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbHeaderType12"
|
||||||
|
Grid.Row="4"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="200"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
Style="{StaticResource DefComboBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="5"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbUot}" />
|
||||||
|
<ToggleButton
|
||||||
|
x:Name="togUotEnabled12"
|
||||||
|
Grid.Row="5"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Separator
|
<Separator
|
||||||
x:Name="sepa2"
|
x:Name="sepa2"
|
||||||
|
|
|
||||||
|
|
@ -89,10 +89,24 @@ public partial class AddServerWindow
|
||||||
|
|
||||||
case EConfigType.Anytls:
|
case EConfigType.Anytls:
|
||||||
gridAnytls.Visibility = Visibility.Visible;
|
gridAnytls.Visibility = Visibility.Visible;
|
||||||
|
sepa2.Visibility = Visibility.Collapsed;
|
||||||
|
gridTransport.Visibility = Visibility.Collapsed;
|
||||||
cmbCoreType.IsEnabled = false;
|
cmbCoreType.IsEnabled = false;
|
||||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||||
gridFinalmask.Visibility = Visibility.Collapsed;
|
gridFinalmask.Visibility = Visibility.Collapsed;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EConfigType.Naive:
|
||||||
|
gridNaive.Visibility = Visibility.Visible;
|
||||||
|
cmbCoreType.IsEnabled = false;
|
||||||
|
gridFinalmask.Visibility = Visibility.Collapsed;
|
||||||
|
cmbFingerprint.IsEnabled = false;
|
||||||
|
cmbFingerprint.Text = string.Empty;
|
||||||
|
cmbAllowInsecure.IsEnabled = false;
|
||||||
|
cmbAllowInsecure.Text = string.Empty;
|
||||||
|
|
||||||
|
cmbHeaderType12.ItemsSource = Global.NaiveCongestionControls;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||||
|
|
||||||
|
|
@ -117,6 +131,7 @@ public partial class AddServerWindow
|
||||||
case EConfigType.Shadowsocks:
|
case EConfigType.Shadowsocks:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId3.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId3.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SsMethod, v => v.cmbSecurity3.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SsMethod, v => v.cmbSecurity3.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled3.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.MuxEnabled, v => v.togmuxEnabled3.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.MuxEnabled, v => v.togmuxEnabled3.IsChecked).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -151,7 +166,7 @@ public partial class AddServerWindow
|
||||||
case EConfigType.TUIC:
|
case EConfigType.TUIC:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId8.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId8.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity8.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity8.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType8.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CongestionControl, v => v.cmbHeaderType8.Text).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.WireGuard:
|
case EConfigType.WireGuard:
|
||||||
|
|
@ -163,7 +178,15 @@ public partial class AddServerWindow
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.Anytls:
|
case EConfigType.Anytls:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId10.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId11.Text).DisposeWith(disposables);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EConfigType.Naive:
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId12.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity12.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.InsecureConcurrency, v => v.txtInsecureConcurrency12.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.CongestionControl, v => v.cmbHeaderType12.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled12.IsChecked).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.Text).DisposeWith(disposables);
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,10 @@
|
||||||
x:Name="menuAddAnytlsServer"
|
x:Name="menuAddAnytlsServer"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
|
Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
|
||||||
|
<MenuItem
|
||||||
|
x:Name="menuAddNaiveServer"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
Header="{x:Static resx:ResUI.menuAddNaiveServer}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ public partial class MainWindow
|
||||||
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
||||||
|
this.BindCommand(ViewModel, vm => vm.AddNaiveServerCmd, v => v.menuAddNaiveServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddPolicyGroupServerCmd, v => v.menuAddPolicyGroupServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddPolicyGroupServerCmd, v => v.menuAddPolicyGroupServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddProxyChainServerCmd, v => v.menuAddProxyChainServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddProxyChainServerCmd, v => v.menuAddProxyChainServer).DisposeWith(disposables);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue