mirror of https://github.com/2dust/v2rayN
Added Tuic v5 support (using sing-box)
parent
e2657e746d
commit
bd9a4ca094
|
@ -77,6 +77,8 @@
|
||||||
public const string hysteria2Protocol = "hysteria2://";
|
public const string hysteria2Protocol = "hysteria2://";
|
||||||
public const string hysteria2Protocol2 = "hy2://";
|
public const string hysteria2Protocol2 = "hy2://";
|
||||||
public const string hysteria2ProtocolLite = "hysteria2";
|
public const string hysteria2ProtocolLite = "hysteria2";
|
||||||
|
public const string tuicProtocol = "tuic://";
|
||||||
|
public const string tuicProtocolLite = "tuic";
|
||||||
|
|
||||||
public const string userEMail = "t@t.tt";
|
public const string userEMail = "t@t.tt";
|
||||||
public const string MyRegPath = "Software\\v2rayNGUI";
|
public const string MyRegPath = "Software\\v2rayNGUI";
|
||||||
|
@ -165,6 +167,7 @@
|
||||||
public static readonly List<string> TunStacks = new() { "gvisor", "system" };
|
public static readonly List<string> TunStacks = new() { "gvisor", "system" };
|
||||||
public static readonly List<string> PresetMsgFilters = new() { "proxy", "direct", "block", "" };
|
public static readonly List<string> PresetMsgFilters = new() { "proxy", "direct", "block", "" };
|
||||||
public static readonly List<string> SingboxMuxs = new() { "h2mux", "smux", "yamux", "" };
|
public static readonly List<string> SingboxMuxs = new() { "h2mux", "smux", "yamux", "" };
|
||||||
|
public static readonly List<string> TuicCongestionControl = new() { "cubic", "new_reno", "bbr" };
|
||||||
|
|
||||||
#endregion const
|
#endregion const
|
||||||
|
|
||||||
|
|
|
@ -729,6 +729,44 @@ namespace v2rayN.Handler
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add or edit server
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config"></param>
|
||||||
|
/// <param name="profileItem"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static int AddTuicServer(ref Config config, ProfileItem profileItem, bool toFile = true)
|
||||||
|
{
|
||||||
|
profileItem.configType = EConfigType.Tuic;
|
||||||
|
profileItem.coreType = ECoreType.sing_box;
|
||||||
|
|
||||||
|
profileItem.address = profileItem.address.TrimEx();
|
||||||
|
profileItem.id = profileItem.id.TrimEx();
|
||||||
|
profileItem.security = profileItem.security.TrimEx();
|
||||||
|
|
||||||
|
if (!Global.TuicCongestionControl.Contains(profileItem.headerType))
|
||||||
|
{
|
||||||
|
profileItem.headerType = Global.TuicCongestionControl.FirstOrDefault()!;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Utils.IsNullOrEmpty(profileItem.streamSecurity))
|
||||||
|
{
|
||||||
|
profileItem.streamSecurity = Global.StreamSecurity;
|
||||||
|
}
|
||||||
|
if (Utils.IsNullOrEmpty(profileItem.alpn))
|
||||||
|
{
|
||||||
|
profileItem.alpn = "h3";
|
||||||
|
}
|
||||||
|
if (profileItem.id.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddServerCommon(ref config, profileItem, toFile);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static int SortServers(ref Config config, string subId, string colName, bool asc)
|
public static int SortServers(ref Config config, string subId, string colName, bool asc)
|
||||||
{
|
{
|
||||||
var lstModel = LazyConfig.Instance.ProfileItems(subId, "");
|
var lstModel = LazyConfig.Instance.ProfileItems(subId, "");
|
||||||
|
@ -1082,6 +1120,10 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
addStatus = AddHysteria2Server(ref config, profileItem, false);
|
addStatus = AddHysteria2Server(ref config, profileItem, false);
|
||||||
}
|
}
|
||||||
|
else if (profileItem.configType == EConfigType.Tuic)
|
||||||
|
{
|
||||||
|
addStatus = AddTuicServer(ref config, profileItem, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (addStatus == 0)
|
if (addStatus == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -294,6 +294,16 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
outboundMux(node, outbound);
|
outboundMux(node, outbound);
|
||||||
}
|
}
|
||||||
|
else if (node.configType == EConfigType.Tuic)
|
||||||
|
{
|
||||||
|
outbound.type = Global.tuicProtocolLite;
|
||||||
|
|
||||||
|
outbound.uuid = node.id;
|
||||||
|
outbound.password = node.security;
|
||||||
|
outbound.congestion_control = node.headerType;
|
||||||
|
|
||||||
|
outboundMux(node, outbound);
|
||||||
|
}
|
||||||
|
|
||||||
outboundTls(node, outbound);
|
outboundTls(node, outbound);
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace v2rayN.Handler
|
||||||
EConfigType.Trojan => ShareTrojan(item),
|
EConfigType.Trojan => ShareTrojan(item),
|
||||||
EConfigType.VLESS => ShareVLESS(item),
|
EConfigType.VLESS => ShareVLESS(item),
|
||||||
EConfigType.Hysteria2 => ShareHysteria2(item),
|
EConfigType.Hysteria2 => ShareHysteria2(item),
|
||||||
|
EConfigType.Tuic => ShareTuic(item),
|
||||||
_ => null,
|
_ => null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -192,6 +193,35 @@ namespace v2rayN.Handler
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string ShareTuic(ProfileItem item)
|
||||||
|
{
|
||||||
|
string url = string.Empty;
|
||||||
|
string remark = string.Empty;
|
||||||
|
if (!Utils.IsNullOrEmpty(item.remarks))
|
||||||
|
{
|
||||||
|
remark = "#" + Utils.UrlEncode(item.remarks);
|
||||||
|
}
|
||||||
|
var dicQuery = new Dictionary<string, string>();
|
||||||
|
if (!Utils.IsNullOrEmpty(item.sni))
|
||||||
|
{
|
||||||
|
dicQuery.Add("sni", item.sni);
|
||||||
|
}
|
||||||
|
if (!Utils.IsNullOrEmpty(item.alpn))
|
||||||
|
{
|
||||||
|
dicQuery.Add("alpn", Utils.UrlEncode(item.alpn));
|
||||||
|
}
|
||||||
|
dicQuery.Add("congestion_control", item.headerType);
|
||||||
|
|
||||||
|
string query = "?" + string.Join("&", dicQuery.Select(x => x.Key + "=" + x.Value).ToArray());
|
||||||
|
|
||||||
|
url = string.Format("{0}@{1}:{2}",
|
||||||
|
$"{item.id}:{item.security}",
|
||||||
|
GetIpv6(item.address),
|
||||||
|
item.port);
|
||||||
|
url = $"{Global.tuicProtocol}{url}{query}{remark}";
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetIpv6(string address)
|
private static string GetIpv6(string address)
|
||||||
{
|
{
|
||||||
return Utils.IsIpv6(address) ? $"[{address}]" : address;
|
return Utils.IsIpv6(address) ? $"[{address}]" : address;
|
||||||
|
@ -389,6 +419,10 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
profileItem = ResolveHysteria2(result);
|
profileItem = ResolveHysteria2(result);
|
||||||
}
|
}
|
||||||
|
else if (result.StartsWith(Global.tuicProtocol))
|
||||||
|
{
|
||||||
|
profileItem = ResolveTuic(result);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msg = ResUI.NonvmessOrssProtocol;
|
msg = ResUI.NonvmessOrssProtocol;
|
||||||
|
@ -815,6 +849,32 @@ namespace v2rayN.Handler
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ProfileItem ResolveTuic(string result)
|
||||||
|
{
|
||||||
|
ProfileItem item = new()
|
||||||
|
{
|
||||||
|
configType = EConfigType.Tuic
|
||||||
|
};
|
||||||
|
|
||||||
|
Uri url = new(result);
|
||||||
|
|
||||||
|
item.address = url.IdnHost;
|
||||||
|
item.port = url.Port;
|
||||||
|
item.remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);
|
||||||
|
var userInfoParts = url.UserInfo.Split(new[] { ':' }, 2);
|
||||||
|
if (userInfoParts.Length == 2)
|
||||||
|
{
|
||||||
|
item.id = userInfoParts[0];
|
||||||
|
item.security = userInfoParts[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
var query = HttpUtility.ParseQueryString(url.Query);
|
||||||
|
ResolveStdTransport(query, ref item);
|
||||||
|
item.headerType = query["congestion_control"] ?? "";
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
private static int ResolveStdTransport(NameValueCollection query, ref ProfileItem item)
|
private static int ResolveStdTransport(NameValueCollection query, ref ProfileItem item)
|
||||||
{
|
{
|
||||||
item.flow = query["flow"] ?? "";
|
item.flow = query["flow"] ?? "";
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace v2rayN.Handler
|
||||||
_selecteds = new List<ServerTestItem>();
|
_selecteds = new List<ServerTestItem>();
|
||||||
foreach (var it in selecteds)
|
foreach (var it in selecteds)
|
||||||
{
|
{
|
||||||
if (it.configType == EConfigType.Custom || it.configType == EConfigType.Hysteria2)
|
if (it.configType == EConfigType.Custom || it.configType == EConfigType.Hysteria2 || it.configType == EConfigType.Tuic)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
Socks = 4,
|
Socks = 4,
|
||||||
VLESS = 5,
|
VLESS = 5,
|
||||||
Trojan = 6,
|
Trojan = 6,
|
||||||
Hysteria2 = 7
|
Hysteria2 = 7,
|
||||||
|
Tuic = 8
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -54,6 +54,7 @@ namespace v2rayN.Mode
|
||||||
case EConfigType.VLESS:
|
case EConfigType.VLESS:
|
||||||
case EConfigType.Trojan:
|
case EConfigType.Trojan:
|
||||||
case EConfigType.Hysteria2:
|
case EConfigType.Hysteria2:
|
||||||
|
case EConfigType.Tuic:
|
||||||
summary += string.Format("{0}({1}:{2})", remarks, addr, port);
|
summary += string.Format("{0}({1}:{2})", remarks, addr, port);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,7 @@
|
||||||
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? 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; }
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -148,7 +148,7 @@
|
||||||
<value>Failed to generate default configuration file</value>
|
<value>Failed to generate default configuration file</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FailedGetDefaultConfiguration" xml:space="preserve">
|
<data name="FailedGetDefaultConfiguration" xml:space="preserve">
|
||||||
<value> Failed to get the default configuration</value>
|
<value>Failed to get the default configuration</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FailedImportedCustomServer" xml:space="preserve">
|
<data name="FailedImportedCustomServer" xml:space="preserve">
|
||||||
<value>Failed to import custom configuration server</value>
|
<value>Failed to import custom configuration server</value>
|
||||||
|
@ -175,13 +175,13 @@
|
||||||
<value>Please fill in the user ID</value>
|
<value>Please fill in the user ID</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IncorrectClientConfiguration" xml:space="preserve">
|
<data name="IncorrectClientConfiguration" xml:space="preserve">
|
||||||
<value> is not the correct client configuration file, please check</value>
|
<value>Is not the correct client configuration file, please check</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Incorrectconfiguration" xml:space="preserve">
|
<data name="Incorrectconfiguration" xml:space="preserve">
|
||||||
<value> is not the correct configuration, please check</value>
|
<value>Is not the correct configuration, please check</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IncorrectServerConfiguration" xml:space="preserve">
|
<data name="IncorrectServerConfiguration" xml:space="preserve">
|
||||||
<value> is not the correct server configuration file, please check</value>
|
<value>Is not the correct server configuration file, please check</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="InitialConfiguration" xml:space="preserve">
|
<data name="InitialConfiguration" xml:space="preserve">
|
||||||
<value>Initial Configuration</value>
|
<value>Initial Configuration</value>
|
||||||
|
@ -250,7 +250,7 @@
|
||||||
<value>Invalid subscription content</value>
|
<value>Invalid subscription content</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgUnpacking" xml:space="preserve">
|
<data name="MsgUnpacking" xml:space="preserve">
|
||||||
<value>is unpacking...</value>
|
<value>Is unpacking......</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MsgUpdateSubscriptionEnd" xml:space="preserve">
|
<data name="MsgUpdateSubscriptionEnd" xml:space="preserve">
|
||||||
<value>Update subscription end</value>
|
<value>Update subscription end</value>
|
||||||
|
@ -268,7 +268,7 @@
|
||||||
<value>Non-VMess or ss protocol</value>
|
<value>Non-VMess or ss protocol</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="NonVmessService" xml:space="preserve">
|
<data name="NonVmessService" xml:space="preserve">
|
||||||
<value> non-standard service, this feature is invalid</value>
|
<value>Non-standard service, this feature is invalid</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="NotFoundCore" xml:space="preserve">
|
<data name="NotFoundCore" xml:space="preserve">
|
||||||
<value>The Core file (file name: {1}) was not found under the folder ({0}), please download and put it in the folder, download address: {2}</value>
|
<value>The Core file (file name: {1}) was not found under the folder ({0}), please download and put it in the folder, download address: {2}</value>
|
||||||
|
@ -277,7 +277,7 @@
|
||||||
<value>Scan completed, no valid QR code found</value>
|
<value>Scan completed, no valid QR code found</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="OperationFailed" xml:space="preserve">
|
<data name="OperationFailed" xml:space="preserve">
|
||||||
<value> operation failed, please check and retry</value>
|
<value>Operation failed, please check and retry</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PleaseFillRemarks" xml:space="preserve">
|
<data name="PleaseFillRemarks" xml:space="preserve">
|
||||||
<value>Please Fill Remarks</value>
|
<value>Please Fill Remarks</value>
|
||||||
|
@ -308,10 +308,10 @@
|
||||||
{0}</value>
|
{0}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SuccessfullyImportedCustomServer" xml:space="preserve">
|
<data name="SuccessfullyImportedCustomServer" xml:space="preserve">
|
||||||
<value>Custom configuration server imported successfully.</value>
|
<value>Custom configuration server imported successfully</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SuccessfullyImportedServerViaClipboard" xml:space="preserve">
|
<data name="SuccessfullyImportedServerViaClipboard" xml:space="preserve">
|
||||||
<value>{0} servers have been imported from clipboard.</value>
|
<value>{0} servers have been imported from clipboard</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
|
<data name="SuccessfullyImportedServerViaScan" xml:space="preserve">
|
||||||
<value>Scan import URL successfully</value>
|
<value>Scan import URL successfully</value>
|
||||||
|
@ -1082,7 +1082,7 @@
|
||||||
<value>Enable hardware acceleration(Require restart)</value>
|
<value>Enable hardware acceleration(Require restart)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SpeedtestingWait" xml:space="preserve">
|
<data name="SpeedtestingWait" xml:space="preserve">
|
||||||
<value>Waiting for testing</value>
|
<value>Waiting for testing......</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TipDisplayLog" xml:space="preserve">
|
<data name="TipDisplayLog" xml:space="preserve">
|
||||||
<value>Please turn off when there is an abnormal disconnection</value>
|
<value>Please turn off when there is an abnormal disconnection</value>
|
||||||
|
@ -1147,4 +1147,10 @@
|
||||||
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
|
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
|
||||||
<value>Use System Hosts</value>
|
<value>Use System Hosts</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuAddTuicServer" xml:space="preserve">
|
||||||
|
<value>Add [Tuic] server</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbHeaderType8" xml:space="preserve">
|
||||||
|
<value>Congestion control</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -1082,7 +1082,7 @@
|
||||||
<value>启用硬件加速(需重启)</value>
|
<value>启用硬件加速(需重启)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SpeedtestingWait" xml:space="preserve">
|
<data name="SpeedtestingWait" xml:space="preserve">
|
||||||
<value>等待测试中...</value>
|
<value>等待测试中......</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TipDisplayLog" xml:space="preserve">
|
<data name="TipDisplayLog" xml:space="preserve">
|
||||||
<value>当有异常断流时请关闭</value>
|
<value>当有异常断流时请关闭</value>
|
||||||
|
@ -1144,4 +1144,10 @@
|
||||||
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
|
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
|
||||||
<value>使用系统hosts</value>
|
<value>使用系统hosts</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="menuAddTuicServer" xml:space="preserve">
|
||||||
|
<value>添加[Tuic]服务器</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbHeaderType8" xml:space="preserve">
|
||||||
|
<value>拥塞控制算法</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -1082,7 +1082,7 @@
|
||||||
<value>啟用硬體加速(需重啟)</value>
|
<value>啟用硬體加速(需重啟)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SpeedtestingWait" xml:space="preserve">
|
<data name="SpeedtestingWait" xml:space="preserve">
|
||||||
<value>等待測試中...</value>
|
<value>等待測試中......</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TipDisplayLog" xml:space="preserve">
|
<data name="TipDisplayLog" xml:space="preserve">
|
||||||
<value>當有異常斷流時請關閉</value>
|
<value>當有異常斷流時請關閉</value>
|
||||||
|
@ -1135,4 +1135,7 @@
|
||||||
<data name="TbRoutingRuleIP" xml:space="preserve">
|
<data name="TbRoutingRuleIP" xml:space="preserve">
|
||||||
<value>IP 或 IP CIDR</value>
|
<value>IP 或 IP CIDR</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
<data name="menuAddTuicServer" xml:space="preserve">
|
||||||
|
<value>新增[Tuic]伺服器</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
|
@ -906,8 +906,8 @@ namespace v2rayN
|
||||||
public static T DeepCopy<T>(T obj)
|
public static T DeepCopy<T>(T obj)
|
||||||
{
|
{
|
||||||
object retval;
|
object retval;
|
||||||
MemoryStream ms = new MemoryStream();
|
MemoryStream ms = new();
|
||||||
BinaryFormatter bf = new BinaryFormatter();
|
BinaryFormatter bf = new();
|
||||||
//序列化成流
|
//序列化成流
|
||||||
bf.Serialize(ms, obj);
|
bf.Serialize(ms, obj);
|
||||||
ms.Seek(0, SeekOrigin.Begin);
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
|
@ -149,6 +149,10 @@ namespace v2rayN.ViewModels
|
||||||
case EConfigType.Hysteria2:
|
case EConfigType.Hysteria2:
|
||||||
ret = ConfigHandler.AddHysteria2Server(ref _config, item);
|
ret = ConfigHandler.AddHysteria2Server(ref _config, item);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EConfigType.Tuic:
|
||||||
|
ret = ConfigHandler.AddTuicServer(ref _config, item);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
|
|
|
@ -90,6 +90,7 @@ namespace v2rayN.ViewModels
|
||||||
public ReactiveCommand<Unit, Unit> AddSocksServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddSocksServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddTrojanServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddTrojanServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddCustomServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddCustomServerCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddServerViaClipboardCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddServerViaClipboardCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }
|
||||||
|
@ -345,6 +346,10 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
EditServer(true, EConfigType.Hysteria2);
|
EditServer(true, EConfigType.Hysteria2);
|
||||||
});
|
});
|
||||||
|
AddTuicServerCmd = ReactiveCommand.Create(() =>
|
||||||
|
{
|
||||||
|
EditServer(true, EConfigType.Tuic);
|
||||||
|
});
|
||||||
AddCustomServerCmd = ReactiveCommand.Create(() =>
|
AddCustomServerCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
EditServer(true, EConfigType.Custom);
|
EditServer(true, EConfigType.Custom);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.AddServerWindow"
|
x:Class="v2rayN.Views.AddServerWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||||
xmlns:resx="clr-namespace:v2rayN.Resx"
|
xmlns:resx="clr-namespace:v2rayN.Resx"
|
||||||
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
||||||
Title="{x:Static resx:ResUI.menuServers}"
|
Title="{x:Static resx:ResUI.menuServers}"
|
||||||
|
@ -450,6 +450,66 @@
|
||||||
Margin="{StaticResource ServerItemMargin}"
|
Margin="{StaticResource ServerItemMargin}"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
x:Name="gridTuic"
|
||||||
|
Grid.Row="2"
|
||||||
|
Visibility="Hidden">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="180" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource ServerItemMargin}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbId}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtId8"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource ServerItemMargin}"
|
||||||
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource ServerItemMargin}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbId3}" />
|
||||||
|
<TextBox
|
||||||
|
x:Name="txtSecurity8"
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource ServerItemMargin}"
|
||||||
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource ServerItemMargin}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbHeaderType8}" />
|
||||||
|
<ComboBox
|
||||||
|
x:Name="cmbHeaderType8"
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="100"
|
||||||
|
Margin="{StaticResource ServerItemMargin}"
|
||||||
|
Style="{StaticResource DefComboBox}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Separator
|
<Separator
|
||||||
x:Name="sepa2"
|
x:Name="sepa2"
|
||||||
|
@ -785,7 +845,6 @@
|
||||||
Grid.Row="8"
|
Grid.Row="8"
|
||||||
Margin="0,2"
|
Margin="0,2"
|
||||||
Style="{DynamicResource MaterialDesignSeparator}" />
|
Style="{DynamicResource MaterialDesignSeparator}" />
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
|
|
|
@ -126,6 +126,20 @@ namespace v2rayN.Views
|
||||||
cmbFingerprint.IsEnabled = false;
|
cmbFingerprint.IsEnabled = false;
|
||||||
cmbFingerprint.Text = string.Empty;
|
cmbFingerprint.Text = string.Empty;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EConfigType.Tuic:
|
||||||
|
gridTuic.Visibility = Visibility.Visible;
|
||||||
|
sepa2.Visibility = Visibility.Collapsed;
|
||||||
|
gridTransport.Visibility = Visibility.Collapsed;
|
||||||
|
cmbCoreType.IsEnabled = false;
|
||||||
|
cmbFingerprint.IsEnabled = false;
|
||||||
|
cmbFingerprint.Text = string.Empty;
|
||||||
|
|
||||||
|
Global.TuicCongestionControl.ForEach(it =>
|
||||||
|
{
|
||||||
|
cmbHeaderType8.Items.Add(it);
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gridTlsMore.Visibility = Visibility.Hidden;
|
gridTlsMore.Visibility = Visibility.Hidden;
|
||||||
|
@ -169,6 +183,12 @@ namespace v2rayN.Views
|
||||||
case EConfigType.Hysteria2:
|
case EConfigType.Hysteria2:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId7.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId7.Text).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EConfigType.Tuic:
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId8.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity8.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.SelectedSource.headerType, v => v.cmbHeaderType8.Text).DisposeWith(disposables);
|
||||||
|
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);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.headerType, v => v.cmbHeaderType.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.headerType, v => v.cmbHeaderType.Text).DisposeWith(disposables);
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace v2rayN.Views
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
this.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
this.Bind(ViewModel, vm=>vm.useSystemHosts, v=>v.togUseSystemHosts.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.useSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.normalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.normalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.normalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.normalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables);
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.MainWindow"
|
x:Class="v2rayN.Views.MainWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:tb="clr-namespace:H.NotifyIcon;assembly=H.NotifyIcon.Wpf"
|
||||||
xmlns:base="clr-namespace:v2rayN.Base"
|
xmlns:base="clr-namespace:v2rayN.Base"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:local="clr-namespace:v2rayN.Views"
|
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:resx="clr-namespace:v2rayN.Resx"
|
xmlns:resx="clr-namespace:v2rayN.Resx"
|
||||||
xmlns:tb="clr-namespace:H.NotifyIcon;assembly=H.NotifyIcon.Wpf"
|
|
||||||
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
||||||
|
xmlns:local="clr-namespace:v2rayN.Views"
|
||||||
Title="v2rayN"
|
Title="v2rayN"
|
||||||
Width="900"
|
Width="900"
|
||||||
Height="700"
|
Height="700"
|
||||||
|
@ -87,6 +87,10 @@
|
||||||
x:Name="menuAddHysteria2Server"
|
x:Name="menuAddHysteria2Server"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuAddHysteria2Server}" />
|
Header="{x:Static resx:ResUI.menuAddHysteria2Server}" />
|
||||||
|
<MenuItem
|
||||||
|
x:Name="menuAddTuicServer"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
Header="{x:Static resx:ResUI.menuAddTuicServer}" />
|
||||||
<Separator Margin="-40,5" />
|
<Separator Margin="-40,5" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuAddServerViaClipboard"
|
x:Name="menuAddServerViaClipboard"
|
||||||
|
|
|
@ -87,6 +87,7 @@ namespace v2rayN.Views
|
||||||
this.BindCommand(ViewModel, vm => vm.AddSocksServerCmd, v => v.menuAddSocksServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddSocksServerCmd, v => v.menuAddSocksServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddTrojanServerCmd, v => v.menuAddTrojanServer).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddTrojanServerCmd, v => v.menuAddTrojanServer).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddHysteria2ServerCmd, v => v.menuAddHysteria2Server).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddHysteria2ServerCmd, v => v.menuAddHysteria2Server).DisposeWith(disposables);
|
||||||
|
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).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.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan).DisposeWith(disposables);
|
||||||
|
|
Loading…
Reference in New Issue