mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-30 03:52:53 +00:00
Compare commits
No commits in common. "7995bdd4dfc5091a7b393c0d60f77c3735bf4556" and "c669e72189e22bb50822402a7096bc0a06ec3c54" have entirely different histories.
7995bdd4df
...
c669e72189
38 changed files with 167 additions and 788 deletions
|
|
@ -411,11 +411,11 @@ public class Utils
|
||||||
// Link-local address fe80::/10
|
// Link-local address fe80::/10
|
||||||
if (ipBytes[0] == 0xfe && (ipBytes[1] & 0xc0) == 0x80)
|
if (ipBytes[0] == 0xfe && (ipBytes[1] & 0xc0) == 0x80)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Unique local address fc00::/7 (typically fd00::/8)
|
// Unique local address fc00::/7 (typically fd00::/8)
|
||||||
if ((ipBytes[0] & 0xfe) == 0xfc)
|
if ((ipBytes[0] & 0xfe) == 0xfc)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Private portion in IPv4-mapped addresses ::ffff:0:0/96
|
// Private portion in IPv4-mapped addresses ::ffff:0:0/96
|
||||||
if (address.IsIPv4MappedToIPv6)
|
if (address.IsIPv4MappedToIPv6)
|
||||||
{
|
{
|
||||||
|
|
@ -466,11 +466,11 @@ public class Utils
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetFreePort(int defaultPort = 0)
|
public static int GetFreePort(int defaultPort = 9090)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!(defaultPort == 0 || Utils.PortInUse(defaultPort)))
|
if (!Utils.PortInUse(defaultPort))
|
||||||
{
|
{
|
||||||
return defaultPort;
|
return defaultPort;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,5 @@ public enum EConfigType
|
||||||
Hysteria2 = 7,
|
Hysteria2 = 7,
|
||||||
TUIC = 8,
|
TUIC = 8,
|
||||||
WireGuard = 9,
|
WireGuard = 9,
|
||||||
HTTP = 10,
|
HTTP = 10
|
||||||
Anytls = 11
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -169,8 +169,7 @@ public class Global
|
||||||
{ EConfigType.Trojan, "trojan://" },
|
{ EConfigType.Trojan, "trojan://" },
|
||||||
{ EConfigType.Hysteria2, "hysteria2://" },
|
{ EConfigType.Hysteria2, "hysteria2://" },
|
||||||
{ EConfigType.TUIC, "tuic://" },
|
{ EConfigType.TUIC, "tuic://" },
|
||||||
{ EConfigType.WireGuard, "wireguard://" },
|
{ EConfigType.WireGuard, "wireguard://" }
|
||||||
{ EConfigType.Anytls, "anytls://" }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly Dictionary<EConfigType, string> ProtocolTypes = new()
|
public static readonly Dictionary<EConfigType, string> ProtocolTypes = new()
|
||||||
|
|
@ -183,8 +182,7 @@ public class Global
|
||||||
{ EConfigType.Trojan, "trojan" },
|
{ EConfigType.Trojan, "trojan" },
|
||||||
{ EConfigType.Hysteria2, "hysteria2" },
|
{ EConfigType.Hysteria2, "hysteria2" },
|
||||||
{ EConfigType.TUIC, "tuic" },
|
{ EConfigType.TUIC, "tuic" },
|
||||||
{ EConfigType.WireGuard, "wireguard" },
|
{ EConfigType.WireGuard, "wireguard" }
|
||||||
{ EConfigType.Anytls, "anytls" }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly List<string> VmessSecurities =
|
public static readonly List<string> VmessSecurities =
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,6 @@ public class ConfigHandler
|
||||||
EConfigType.Hysteria2 => await AddHysteria2Server(config, item),
|
EConfigType.Hysteria2 => await AddHysteria2Server(config, item),
|
||||||
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),
|
|
||||||
_ => -1,
|
_ => -1,
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -787,35 +786,6 @@ public class ConfigHandler
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add or edit a Anytls server
|
|
||||||
/// Validates and processes Anytls-specific settings
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="config">Current configuration</param>
|
|
||||||
/// <param name="profileItem">Anytls 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> AddAnytlsServer(Config config, ProfileItem profileItem, bool toFile = true)
|
|
||||||
{
|
|
||||||
profileItem.ConfigType = EConfigType.Anytls;
|
|
||||||
profileItem.CoreType = ECoreType.sing_box;
|
|
||||||
|
|
||||||
profileItem.Address = profileItem.Address.TrimEx();
|
|
||||||
profileItem.Id = profileItem.Id.TrimEx();
|
|
||||||
profileItem.Security = profileItem.Security.TrimEx();
|
|
||||||
profileItem.Network = string.Empty;
|
|
||||||
if (profileItem.StreamSecurity.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
profileItem.StreamSecurity = Global.StreamSecurity;
|
|
||||||
}
|
|
||||||
if (profileItem.Id.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
|
||||||
|
|
@ -1325,7 +1295,6 @@ public class ConfigHandler
|
||||||
EConfigType.Hysteria2 => await AddHysteria2Server(config, profileItem, false),
|
EConfigType.Hysteria2 => await AddHysteria2Server(config, profileItem, false),
|
||||||
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),
|
|
||||||
_ => -1,
|
_ => -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2028,7 +1997,7 @@ public class ConfigHandler
|
||||||
|
|
||||||
if (!blImportAdvancedRules && items.Count > 0)
|
if (!blImportAdvancedRules && items.Count > 0)
|
||||||
{
|
{
|
||||||
//migrate
|
//migrate
|
||||||
//TODO Temporary code to be removed later
|
//TODO Temporary code to be removed later
|
||||||
if (config.RoutingBasicItem.RoutingIndexId.IsNotEmpty())
|
if (config.RoutingBasicItem.RoutingIndexId.IsNotEmpty())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ public class CoreHandler
|
||||||
Environment.SetEnvironmentVariable(Global.V2RayLocalAsset, Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
Environment.SetEnvironmentVariable(Global.V2RayLocalAsset, Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
||||||
Environment.SetEnvironmentVariable(Global.XrayLocalAsset, Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
Environment.SetEnvironmentVariable(Global.XrayLocalAsset, Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
||||||
Environment.SetEnvironmentVariable(Global.XrayLocalCert, Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
Environment.SetEnvironmentVariable(Global.XrayLocalCert, Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
|
||||||
|
// TODO Temporary addition to support proper use of sing-box v1.12
|
||||||
|
Environment.SetEnvironmentVariable("ENABLE_DEPRECATED_SPECIAL_OUTBOUNDS", "true", EnvironmentVariableTarget.Process);
|
||||||
|
|
||||||
//Copy the bin folder to the storage location (for init)
|
//Copy the bin folder to the storage location (for init)
|
||||||
if (Environment.GetEnvironmentVariable(Global.LocalAppData) == "1")
|
if (Environment.GetEnvironmentVariable(Global.LocalAppData) == "1")
|
||||||
|
|
@ -101,7 +103,7 @@ public class CoreHandler
|
||||||
|
|
||||||
public async Task<int> LoadCoreConfigSpeedtest(List<ServerTestItem> selecteds)
|
public async Task<int> LoadCoreConfigSpeedtest(List<ServerTestItem> selecteds)
|
||||||
{
|
{
|
||||||
var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls) ? ECoreType.sing_box : ECoreType.Xray;
|
var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC) ? ECoreType.sing_box : ECoreType.Xray;
|
||||||
var fileName = string.Format(Global.CoreSpeedtestConfigFileName, Utils.GetGuid(false));
|
var fileName = string.Format(Global.CoreSpeedtestConfigFileName, Utils.GetGuid(false));
|
||||||
var configPath = Utils.GetBinConfigPath(fileName);
|
var configPath = Utils.GetBinConfigPath(fileName);
|
||||||
var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType);
|
var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType);
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
using static QRCoder.PayloadGenerator;
|
|
||||||
|
|
||||||
namespace ServiceLib.Handler.Fmt;
|
|
||||||
public class AnytlsFmt : 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.Anytls,
|
|
||||||
Remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped),
|
|
||||||
Address = parsedUrl.IdnHost,
|
|
||||||
Port = parsedUrl.Port,
|
|
||||||
};
|
|
||||||
var rawUserInfo = Utils.UrlDecode(parsedUrl.UserInfo);
|
|
||||||
item.Id = rawUserInfo;
|
|
||||||
|
|
||||||
var query = Utils.ParseQueryString(parsedUrl.Query);
|
|
||||||
_ = ResolveStdTransport(query, ref item);
|
|
||||||
|
|
||||||
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 pw = item.Id;
|
|
||||||
var dicQuery = new Dictionary<string, string>();
|
|
||||||
_ = GetStdTransport(item, Global.None, ref dicQuery);
|
|
||||||
|
|
||||||
return ToUri(EConfigType.Anytls, item.Address, item.Port, pw, dicQuery, remark);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -62,7 +62,7 @@ public class BaseFmt
|
||||||
if (item.Mldsa65Verify.IsNotEmpty())
|
if (item.Mldsa65Verify.IsNotEmpty())
|
||||||
{
|
{
|
||||||
dicQuery.Add("pqv", Utils.UrlEncode(item.Mldsa65Verify));
|
dicQuery.Add("pqv", Utils.UrlEncode(item.Mldsa65Verify));
|
||||||
}
|
}
|
||||||
if (item.AllowInsecure.Equals("true"))
|
if (item.AllowInsecure.Equals("true"))
|
||||||
{
|
{
|
||||||
dicQuery.Add("allowInsecure", "1");
|
dicQuery.Add("allowInsecure", "1");
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ public class FmtHandler
|
||||||
EConfigType.Hysteria2 => Hysteria2Fmt.ToUri(item),
|
EConfigType.Hysteria2 => Hysteria2Fmt.ToUri(item),
|
||||||
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),
|
|
||||||
_ => null,
|
_ => null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -76,10 +75,6 @@ public class FmtHandler
|
||||||
{
|
{
|
||||||
return WireguardFmt.Resolve(str, out msg);
|
return WireguardFmt.Resolve(str, out msg);
|
||||||
}
|
}
|
||||||
else if (str.StartsWith(Global.ProtocolShares[EConfigType.Anytls]))
|
|
||||||
{
|
|
||||||
return AnytlsFmt.Resolve(str, out msg);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msg = ResUI.NonvmessOrssProtocol;
|
msg = ResUI.NonvmessOrssProtocol;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace ServiceLib.Models;
|
namespace ServiceLib.Models;
|
||||||
|
|
||||||
public class SingboxConfig
|
public class SingboxConfig
|
||||||
|
|
@ -8,7 +6,6 @@ public class SingboxConfig
|
||||||
public Dns4Sbox? dns { get; set; }
|
public Dns4Sbox? dns { get; set; }
|
||||||
public List<Inbound4Sbox> inbounds { get; set; }
|
public List<Inbound4Sbox> inbounds { get; set; }
|
||||||
public List<Outbound4Sbox> outbounds { get; set; }
|
public List<Outbound4Sbox> outbounds { get; set; }
|
||||||
public List<Endpoints4Sbox>? endpoints { get; set; }
|
|
||||||
public Route4Sbox route { get; set; }
|
public Route4Sbox route { get; set; }
|
||||||
public Experimental4Sbox? experimental { get; set; }
|
public Experimental4Sbox? experimental { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -32,6 +29,7 @@ public class Dns4Sbox
|
||||||
public bool? independent_cache { get; set; }
|
public bool? independent_cache { get; set; }
|
||||||
public bool? reverse_mapping { get; set; }
|
public bool? reverse_mapping { get; set; }
|
||||||
public string? client_subnet { get; set; }
|
public string? client_subnet { get; set; }
|
||||||
|
public Fakeip4Sbox? fakeip { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Route4Sbox
|
public class Route4Sbox
|
||||||
|
|
@ -39,7 +37,6 @@ public class Route4Sbox
|
||||||
public bool? auto_detect_interface { get; set; }
|
public bool? auto_detect_interface { get; set; }
|
||||||
public List<Rule4Sbox> rules { get; set; }
|
public List<Rule4Sbox> rules { get; set; }
|
||||||
public List<Ruleset4Sbox>? rule_set { get; set; }
|
public List<Ruleset4Sbox>? rule_set { get; set; }
|
||||||
public string? final { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
|
@ -52,7 +49,6 @@ public class Rule4Sbox
|
||||||
public string? mode { get; set; }
|
public string? mode { get; set; }
|
||||||
public bool? ip_is_private { get; set; }
|
public bool? ip_is_private { get; set; }
|
||||||
public string? client_subnet { get; set; }
|
public string? client_subnet { get; set; }
|
||||||
public int? rewrite_ttl { get; set; }
|
|
||||||
public bool? invert { get; set; }
|
public bool? invert { get; set; }
|
||||||
public string? clash_mode { get; set; }
|
public string? clash_mode { get; set; }
|
||||||
public List<string>? inbound { get; set; }
|
public List<string>? inbound { get; set; }
|
||||||
|
|
@ -71,27 +67,6 @@ public class Rule4Sbox
|
||||||
public List<string>? process_name { get; set; }
|
public List<string>? process_name { get; set; }
|
||||||
public List<string>? rule_set { get; set; }
|
public List<string>? rule_set { get; set; }
|
||||||
public List<Rule4Sbox>? rules { get; set; }
|
public List<Rule4Sbox>? rules { get; set; }
|
||||||
public string? action { get; set; }
|
|
||||||
public string? strategy { get; set; }
|
|
||||||
public List<string>? sniffer { get; set; }
|
|
||||||
public string? rcode { get; set; }
|
|
||||||
public List<object>? query_type { get; set; }
|
|
||||||
public List<string>? answer { get; set; }
|
|
||||||
public List<string>? ns { get; set; }
|
|
||||||
public List<string>? extra { get; set; }
|
|
||||||
public string? method { get; set; }
|
|
||||||
public bool? no_drop { get; set; }
|
|
||||||
public bool? source_ip_is_private { get; set; }
|
|
||||||
public bool? ip_accept_any { get; set; }
|
|
||||||
public int? source_port { get; set; }
|
|
||||||
public List<string>? source_port_range { get; set; }
|
|
||||||
public List<string>? network_type { get; set; }
|
|
||||||
public bool? network_is_expensive { get; set; }
|
|
||||||
public bool? network_is_constrained { get; set; }
|
|
||||||
public List<string>? wifi_ssid { get; set; }
|
|
||||||
public List<string>? wifi_bssid { get; set; }
|
|
||||||
public bool? rule_set_ip_cidr_match_source { get; set; }
|
|
||||||
public bool? rule_set_ip_cidr_accept_empty { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
|
@ -101,6 +76,7 @@ public class Inbound4Sbox
|
||||||
public string tag { get; set; }
|
public string tag { get; set; }
|
||||||
public string listen { get; set; }
|
public string listen { get; set; }
|
||||||
public int? listen_port { get; set; }
|
public int? listen_port { get; set; }
|
||||||
|
public string? domain_strategy { get; set; }
|
||||||
public string interface_name { get; set; }
|
public string interface_name { get; set; }
|
||||||
public List<string>? address { get; set; }
|
public List<string>? address { get; set; }
|
||||||
public int? mtu { get; set; }
|
public int? mtu { get; set; }
|
||||||
|
|
@ -108,6 +84,8 @@ public class Inbound4Sbox
|
||||||
public bool? strict_route { get; set; }
|
public bool? strict_route { get; set; }
|
||||||
public bool? endpoint_independent_nat { get; set; }
|
public bool? endpoint_independent_nat { get; set; }
|
||||||
public string? stack { get; set; }
|
public string? stack { get; set; }
|
||||||
|
public bool? sniff { get; set; }
|
||||||
|
public bool? sniff_override_destination { get; set; }
|
||||||
public List<User4Sbox> users { get; set; }
|
public List<User4Sbox> users { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,8 +95,10 @@ public class User4Sbox
|
||||||
public string password { get; set; }
|
public string password { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Outbound4Sbox : BaseServer4Sbox
|
public class Outbound4Sbox
|
||||||
{
|
{
|
||||||
|
public string type { get; set; }
|
||||||
|
public string tag { get; set; }
|
||||||
public string? server { get; set; }
|
public string? server { get; set; }
|
||||||
public int? server_port { get; set; }
|
public int? server_port { get; set; }
|
||||||
public List<string>? server_ports { get; set; }
|
public List<string>? server_ports { get; set; }
|
||||||
|
|
@ -133,6 +113,7 @@ 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 string? detour { 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; }
|
||||||
|
|
@ -140,36 +121,21 @@ public class Outbound4Sbox : BaseServer4Sbox
|
||||||
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; }
|
||||||
|
public List<string>? local_address { get; set; }
|
||||||
|
public string? private_key { get; set; }
|
||||||
|
public string? peer_public_key { get; set; }
|
||||||
|
public List<int>? reserved { get; set; }
|
||||||
|
public int? mtu { get; set; }
|
||||||
public string? plugin { get; set; }
|
public string? plugin { get; set; }
|
||||||
public string? plugin_opts { get; set; }
|
public string? plugin_opts { get; set; }
|
||||||
|
public Tls4Sbox? tls { get; set; }
|
||||||
|
public Multiplex4Sbox? multiplex { get; set; }
|
||||||
|
public Transport4Sbox? transport { get; set; }
|
||||||
|
public HyObfs4Sbox? obfs { get; set; }
|
||||||
public List<string>? outbounds { get; set; }
|
public List<string>? outbounds { get; set; }
|
||||||
public bool? interrupt_exist_connections { get; set; }
|
public bool? interrupt_exist_connections { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Endpoints4Sbox : BaseServer4Sbox
|
|
||||||
{
|
|
||||||
public bool? system { get; set; }
|
|
||||||
public string? name { get; set; }
|
|
||||||
public int? mtu { get; set; }
|
|
||||||
public List<string> address { get; set; }
|
|
||||||
public string private_key { get; set; }
|
|
||||||
public int? listen_port { get; set; }
|
|
||||||
public string? udp_timeout { get; set; }
|
|
||||||
public int? workers { get; set; }
|
|
||||||
public List<Peer4Sbox> peers { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Peer4Sbox
|
|
||||||
{
|
|
||||||
public string address { get; set; }
|
|
||||||
public int port { get; set; }
|
|
||||||
public string public_key { get; set; }
|
|
||||||
public string? pre_shared_key { get; set; }
|
|
||||||
public List<string> allowed_ips { get; set; }
|
|
||||||
public int? persistent_keepalive_interval { get; set; }
|
|
||||||
public List<int> reserved { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Tls4Sbox
|
public class Tls4Sbox
|
||||||
{
|
{
|
||||||
public bool enabled { get; set; }
|
public bool enabled { get; set; }
|
||||||
|
|
@ -225,25 +191,15 @@ public class HyObfs4Sbox
|
||||||
public string? password { get; set; }
|
public string? password { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Server4Sbox : BaseServer4Sbox
|
public class Server4Sbox
|
||||||
{
|
{
|
||||||
public string? inet4_range { get; set; }
|
public string? tag { get; set; }
|
||||||
public string? inet6_range { get; set; }
|
|
||||||
public string? client_subnet { get; set; }
|
|
||||||
public string? server { get; set; }
|
|
||||||
public new string? domain_resolver { get; set; }
|
|
||||||
[JsonPropertyName("interface")] public string? Interface { get; set; }
|
|
||||||
public int? server_port { get; set; }
|
|
||||||
public string? path { get; set; }
|
|
||||||
public Headers4Sbox? headers { get; set; }
|
|
||||||
// public List<string>? path { get; set; } // hosts
|
|
||||||
public Dictionary<string, object>? predefined { get; set; }
|
|
||||||
// Deprecated
|
|
||||||
public string? address { get; set; }
|
public string? address { get; set; }
|
||||||
public string? address_resolver { get; set; }
|
public string? address_resolver { get; set; }
|
||||||
public string? address_strategy { get; set; }
|
public string? address_strategy { get; set; }
|
||||||
public string? strategy { get; set; }
|
public string? strategy { get; set; }
|
||||||
// Deprecated End
|
public string? detour { get; set; }
|
||||||
|
public string? client_subnet { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Experimental4Sbox
|
public class Experimental4Sbox
|
||||||
|
|
@ -273,6 +229,13 @@ public class Stats4Sbox
|
||||||
public List<string>? users { get; set; }
|
public List<string>? users { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Fakeip4Sbox
|
||||||
|
{
|
||||||
|
public bool enabled { get; set; }
|
||||||
|
public string inet4_range { get; set; }
|
||||||
|
public string inet6_range { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class CacheFile4Sbox
|
public class CacheFile4Sbox
|
||||||
{
|
{
|
||||||
public bool enabled { get; set; }
|
public bool enabled { get; set; }
|
||||||
|
|
@ -291,33 +254,3 @@ public class Ruleset4Sbox
|
||||||
public string? download_detour { get; set; }
|
public string? download_detour { get; set; }
|
||||||
public string? update_interval { get; set; }
|
public string? update_interval { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class DialFields4Sbox
|
|
||||||
{
|
|
||||||
public string? detour { get; set; }
|
|
||||||
public string? bind_interface { get; set; }
|
|
||||||
public string? inet4_bind_address { get; set; }
|
|
||||||
public string? inet6_bind_address { get; set; }
|
|
||||||
public int? routing_mark { get; set; }
|
|
||||||
public bool? reuse_addr { get; set; }
|
|
||||||
public string? netns { get; set; }
|
|
||||||
public string? connect_timeout { get; set; }
|
|
||||||
public bool? tcp_fast_open { get; set; }
|
|
||||||
public bool? tcp_multi_path { get; set; }
|
|
||||||
public bool? udp_fragment { get; set; }
|
|
||||||
public Rule4Sbox? domain_resolver { get; set; } // or string
|
|
||||||
public string? network_strategy { get; set; }
|
|
||||||
public List<string>? network_type { get; set; }
|
|
||||||
public List<string>? fallback_network_type { get; set; }
|
|
||||||
public string? fallback_delay { get; set; }
|
|
||||||
public Tls4Sbox? tls { get; set; }
|
|
||||||
public Multiplex4Sbox? multiplex { get; set; }
|
|
||||||
public Transport4Sbox? transport { get; set; }
|
|
||||||
public HyObfs4Sbox? obfs { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class BaseServer4Sbox : DialFields4Sbox
|
|
||||||
{
|
|
||||||
public string type { get; set; }
|
|
||||||
public string tag { get; set; }
|
|
||||||
}
|
|
||||||
|
|
|
||||||
9
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
9
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
|
|
@ -654,15 +654,6 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查找类似 Add [Anytls] Configuration 的本地化字符串。
|
|
||||||
/// </summary>
|
|
||||||
public static string menuAddAnytlsServer {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("menuAddAnytlsServer", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Add a custom configuration Configuration 的本地化字符串。
|
/// 查找类似 Add a custom configuration Configuration 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1401,7 +1401,4 @@
|
||||||
<data name="TbMldsa65Verify" xml:space="preserve">
|
<data name="TbMldsa65Verify" xml:space="preserve">
|
||||||
<value>Mldsa65Verify</value>
|
<value>Mldsa65Verify</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
|
||||||
<value>Add [Anytls] Configuration</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1401,7 +1401,4 @@
|
||||||
<data name="TbMldsa65Verify" xml:space="preserve">
|
<data name="TbMldsa65Verify" xml:space="preserve">
|
||||||
<value>Mldsa65Verify</value>
|
<value>Mldsa65Verify</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
|
||||||
<value>[Anytls] konfiguráció hozzáadása</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1401,7 +1401,4 @@
|
||||||
<data name="TbMldsa65Verify" xml:space="preserve">
|
<data name="TbMldsa65Verify" xml:space="preserve">
|
||||||
<value>Mldsa65Verify</value>
|
<value>Mldsa65Verify</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
|
||||||
<value>Add [Anytls] Configuration</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1401,7 +1401,4 @@
|
||||||
<data name="TbMldsa65Verify" xml:space="preserve">
|
<data name="TbMldsa65Verify" xml:space="preserve">
|
||||||
<value>Mldsa65Verify</value>
|
<value>Mldsa65Verify</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
|
||||||
<value>Добавить сервер [Anytls]</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1398,7 +1398,4 @@
|
||||||
<data name="TbMldsa65Verify" xml:space="preserve">
|
<data name="TbMldsa65Verify" xml:space="preserve">
|
||||||
<value>Mldsa65Verify</value>
|
<value>Mldsa65Verify</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
|
||||||
<value>添加 [Anytls] 配置文件</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1398,7 +1398,4 @@
|
||||||
<data name="TbMldsa65Verify" xml:space="preserve">
|
<data name="TbMldsa65Verify" xml:space="preserve">
|
||||||
<value>Mldsa65Verify</value>
|
<value>Mldsa65Verify</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
|
||||||
<value>新增 [Anytls] 設定檔</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"log": {
|
"log": {
|
||||||
"level": "debug",
|
"level": "debug",
|
||||||
"timestamp": true
|
"timestamp": true
|
||||||
|
|
@ -14,10 +14,22 @@
|
||||||
{
|
{
|
||||||
"type": "direct",
|
"type": "direct",
|
||||||
"tag": "direct"
|
"tag": "direct"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "block",
|
||||||
|
"tag": "block"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "dns_out",
|
||||||
|
"type": "dns"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"route": {
|
"route": {
|
||||||
"rules": [
|
"rules": [
|
||||||
|
{
|
||||||
|
"protocol": [ "dns" ],
|
||||||
|
"outbound": "dns_out"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,33 +2,28 @@
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"tag": "remote",
|
"tag": "remote",
|
||||||
"type": "tcp",
|
"address": "tcp://8.8.8.8",
|
||||||
"server": "8.8.8.8",
|
"strategy": "prefer_ipv4",
|
||||||
"detour": "proxy"
|
"detour": "proxy"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tag": "local",
|
"tag": "local",
|
||||||
"type": "udp",
|
"address": "223.5.5.5",
|
||||||
"server": "223.5.5.5"
|
"strategy": "prefer_ipv4",
|
||||||
|
"detour": "direct"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "block",
|
||||||
|
"address": "rcode://success"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rules": [
|
"rules": [
|
||||||
{
|
|
||||||
"domain_suffix": [
|
|
||||||
"googleapis.cn",
|
|
||||||
"gstatic.com"
|
|
||||||
],
|
|
||||||
"server": "remote",
|
|
||||||
"strategy": "prefer_ipv4"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule_set": [
|
"rule_set": [
|
||||||
"geosite-cn"
|
"geosite-cn"
|
||||||
],
|
],
|
||||||
"server": "local",
|
"server": "local"
|
||||||
"strategy": "prefer_ipv4"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"final": "remote",
|
"final": "remote"
|
||||||
"strategy": "prefer_ipv4"
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,33 +2,29 @@
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"tag": "remote",
|
"tag": "remote",
|
||||||
"type": "tcp",
|
"address": "tcp://8.8.8.8",
|
||||||
"server": "8.8.8.8",
|
"strategy": "prefer_ipv4",
|
||||||
"detour": "proxy"
|
"detour": "proxy"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tag": "local",
|
"tag": "local",
|
||||||
"type": "udp",
|
"address": "223.5.5.5",
|
||||||
"server": "223.5.5.5"
|
"strategy": "prefer_ipv4",
|
||||||
|
"detour": "direct"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "block",
|
||||||
|
"address": "rcode://success"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rules": [
|
"rules": [
|
||||||
{
|
|
||||||
"domain_suffix": [
|
|
||||||
"googleapis.cn",
|
|
||||||
"gstatic.com"
|
|
||||||
],
|
|
||||||
"server": "remote",
|
|
||||||
"strategy": "prefer_ipv4"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"rule_set": [
|
"rule_set": [
|
||||||
"geosite-cn"
|
"geosite-cn",
|
||||||
|
"geosite-geolocation-cn"
|
||||||
],
|
],
|
||||||
"server": "local",
|
"server": "local"
|
||||||
"strategy": "prefer_ipv4"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"final": "remote",
|
"final": "remote"
|
||||||
"strategy": "prefer_ipv4"
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,13 @@
|
||||||
139,
|
139,
|
||||||
5353
|
5353
|
||||||
],
|
],
|
||||||
"action": "reject"
|
"outbound": "block"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ip_cidr": [
|
"ip_cidr": [
|
||||||
"224.0.0.0/3",
|
"224.0.0.0/3",
|
||||||
"ff00::/8"
|
"ff00::/8"
|
||||||
],
|
],
|
||||||
"action": "reject"
|
"outbound": "block"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -12,7 +12,7 @@ public class CoreConfigClashService
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
|
public async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
|
||||||
{
|
{
|
||||||
var ret = new RetResult();
|
var ret = new RetResult();
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Reactive;
|
|
||||||
using DynamicData;
|
|
||||||
using ServiceLib.Models;
|
|
||||||
|
|
||||||
namespace ServiceLib.Services.CoreConfig;
|
namespace ServiceLib.Services.CoreConfig;
|
||||||
|
|
||||||
|
|
@ -56,18 +53,7 @@ public class CoreConfigSingboxService
|
||||||
|
|
||||||
await GenInbounds(singboxConfig);
|
await GenInbounds(singboxConfig);
|
||||||
|
|
||||||
if (node.ConfigType == EConfigType.WireGuard)
|
await GenOutbound(node, singboxConfig.outbounds.First());
|
||||||
{
|
|
||||||
singboxConfig.outbounds.RemoveAt(0);
|
|
||||||
var endpoints = new Endpoints4Sbox();
|
|
||||||
await GenEndpoint(node, endpoints);
|
|
||||||
endpoints.tag = Global.ProxyTag;
|
|
||||||
singboxConfig.endpoints = new() { endpoints };
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await GenOutbound(node, singboxConfig.outbounds.First());
|
|
||||||
}
|
|
||||||
|
|
||||||
await GenMoreOutbounds(node, singboxConfig);
|
await GenMoreOutbounds(node, singboxConfig);
|
||||||
|
|
||||||
|
|
@ -216,29 +202,16 @@ public class CoreConfigSingboxService
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var server = await GenServer(item);
|
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
||||||
if (server is null)
|
await GenOutbound(item, outbound);
|
||||||
{
|
outbound.tag = Global.ProxyTag + inbound.listen_port.ToString();
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
singboxConfig.outbounds.Add(outbound);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
var tag = Global.ProxyTag + inbound.listen_port.ToString();
|
|
||||||
server.tag = tag;
|
|
||||||
if (server is Endpoints4Sbox endpoint)
|
|
||||||
{
|
|
||||||
singboxConfig.endpoints ??= new();
|
|
||||||
singboxConfig.endpoints.Add(endpoint);
|
|
||||||
}
|
|
||||||
else if (server is Outbound4Sbox outbound)
|
|
||||||
{
|
|
||||||
singboxConfig.outbounds.Add(outbound);
|
|
||||||
}
|
|
||||||
|
|
||||||
//rule
|
//rule
|
||||||
Rule4Sbox rule = new()
|
Rule4Sbox rule = new()
|
||||||
{
|
{
|
||||||
inbound = new List<string> { inbound.tag },
|
inbound = new List<string> { inbound.tag },
|
||||||
outbound = tag
|
outbound = outbound.tag
|
||||||
};
|
};
|
||||||
singboxConfig.route.rules.Add(rule);
|
singboxConfig.route.rules.Add(rule);
|
||||||
}
|
}
|
||||||
|
|
@ -302,18 +275,7 @@ public class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
|
|
||||||
await GenLog(singboxConfig);
|
await GenLog(singboxConfig);
|
||||||
if (node.ConfigType == EConfigType.WireGuard)
|
await GenOutbound(node, singboxConfig.outbounds.First());
|
||||||
{
|
|
||||||
singboxConfig.outbounds.RemoveAt(0);
|
|
||||||
var endpoints = new Endpoints4Sbox();
|
|
||||||
await GenEndpoint(node, endpoints);
|
|
||||||
endpoints.tag = Global.ProxyTag;
|
|
||||||
singboxConfig.endpoints = new() { endpoints };
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await GenOutbound(node, singboxConfig.outbounds.First());
|
|
||||||
}
|
|
||||||
await GenMoreOutbounds(node, singboxConfig);
|
await GenMoreOutbounds(node, singboxConfig);
|
||||||
await GenDnsDomains(null, singboxConfig, null);
|
await GenDnsDomains(null, singboxConfig, null);
|
||||||
|
|
||||||
|
|
@ -572,6 +534,15 @@ public class CoreConfigSingboxService
|
||||||
singboxConfig.inbounds.Add(inbound);
|
singboxConfig.inbounds.Add(inbound);
|
||||||
|
|
||||||
inbound.listen_port = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks);
|
inbound.listen_port = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks);
|
||||||
|
inbound.sniff = _config.Inbound.First().SniffingEnabled;
|
||||||
|
inbound.sniff_override_destination = _config.Inbound.First().RouteOnly ? false : _config.Inbound.First().SniffingEnabled;
|
||||||
|
inbound.domain_strategy = _config.RoutingBasicItem.DomainStrategy4Singbox.IsNullOrEmpty() ? null : _config.RoutingBasicItem.DomainStrategy4Singbox;
|
||||||
|
|
||||||
|
var routing = await ConfigHandler.GetDefaultRouting(_config);
|
||||||
|
if (routing.DomainStrategy4Singbox.IsNotEmpty())
|
||||||
|
{
|
||||||
|
inbound.domain_strategy = routing.DomainStrategy4Singbox;
|
||||||
|
}
|
||||||
|
|
||||||
if (_config.Inbound.First().SecondLocalPortEnabled)
|
if (_config.Inbound.First().SecondLocalPortEnabled)
|
||||||
{
|
{
|
||||||
|
|
@ -616,6 +587,8 @@ public class CoreConfigSingboxService
|
||||||
tunInbound.mtu = _config.TunModeItem.Mtu;
|
tunInbound.mtu = _config.TunModeItem.Mtu;
|
||||||
tunInbound.strict_route = _config.TunModeItem.StrictRoute;
|
tunInbound.strict_route = _config.TunModeItem.StrictRoute;
|
||||||
tunInbound.stack = _config.TunModeItem.Stack;
|
tunInbound.stack = _config.TunModeItem.Stack;
|
||||||
|
tunInbound.sniff = _config.Inbound.First().SniffingEnabled;
|
||||||
|
//tunInbound.sniff_override_destination = _config.inbound.First().routeOnly ? false : _config.inbound.First().sniffingEnabled;
|
||||||
if (_config.TunModeItem.EnableIPv6Address == false)
|
if (_config.TunModeItem.EnableIPv6Address == false)
|
||||||
{
|
{
|
||||||
tunInbound.address = ["172.18.0.1/30"];
|
tunInbound.address = ["172.18.0.1/30"];
|
||||||
|
|
@ -648,17 +621,6 @@ public class CoreConfigSingboxService
|
||||||
outbound.server_port = node.Port;
|
outbound.server_port = node.Port;
|
||||||
outbound.type = Global.ProtocolTypes[node.ConfigType];
|
outbound.type = Global.ProtocolTypes[node.ConfigType];
|
||||||
|
|
||||||
if (Utils.IsDomain(node.Address))
|
|
||||||
{
|
|
||||||
var item = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
|
||||||
var localDnsAddress = string.IsNullOrEmpty(item?.DomainDNSAddress) ? Global.SingboxDomainDNSAddress.FirstOrDefault() : item?.DomainDNSAddress;
|
|
||||||
outbound.domain_resolver = new()
|
|
||||||
{
|
|
||||||
server = localDnsAddress.StartsWith("tag://") ? localDnsAddress.Substring(6) : "local_resolver",
|
|
||||||
strategy = string.IsNullOrEmpty(item?.DomainStrategy4Freedom) ? null : item?.DomainStrategy4Freedom
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (node.ConfigType)
|
switch (node.ConfigType)
|
||||||
{
|
{
|
||||||
case EConfigType.VMess:
|
case EConfigType.VMess:
|
||||||
|
|
@ -768,9 +730,13 @@ public class CoreConfigSingboxService
|
||||||
outbound.congestion_control = node.HeaderType;
|
outbound.congestion_control = node.HeaderType;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EConfigType.Anytls:
|
case EConfigType.WireGuard:
|
||||||
{
|
{
|
||||||
outbound.password = node.Id;
|
outbound.private_key = node.Id;
|
||||||
|
outbound.peer_public_key = node.PublicKey;
|
||||||
|
outbound.reserved = Utils.String2List(node.Path)?.Select(int.Parse).ToList();
|
||||||
|
outbound.local_address = Utils.String2List(node.RequestHost);
|
||||||
|
outbound.mtu = node.ShortId.IsNullOrEmpty() ? Global.TunMtus.First() : node.ShortId.ToInt();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -786,76 +752,6 @@ public class CoreConfigSingboxService
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> GenEndpoint(ProfileItem node, Endpoints4Sbox endpoint)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
endpoint.address = Utils.String2List(node.RequestHost);
|
|
||||||
endpoint.type = Global.ProtocolTypes[node.ConfigType];
|
|
||||||
|
|
||||||
if (Utils.IsDomain(node.Address))
|
|
||||||
{
|
|
||||||
var item = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
|
||||||
var localDnsAddress = string.IsNullOrEmpty(item?.DomainDNSAddress) ? Global.SingboxDomainDNSAddress.FirstOrDefault() : item?.DomainDNSAddress;
|
|
||||||
endpoint.domain_resolver = new()
|
|
||||||
{
|
|
||||||
server = localDnsAddress.StartsWith("tag://") ? localDnsAddress.Substring(6) : "local_resolver",
|
|
||||||
strategy = string.IsNullOrEmpty(item?.DomainStrategy4Freedom) ? null : item?.DomainStrategy4Freedom
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (node.ConfigType)
|
|
||||||
{
|
|
||||||
case EConfigType.WireGuard:
|
|
||||||
{
|
|
||||||
var peer = new Peer4Sbox
|
|
||||||
{
|
|
||||||
public_key = node.PublicKey,
|
|
||||||
reserved = Utils.String2List(node.Path)?.Select(int.Parse).ToList(),
|
|
||||||
address = node.Address,
|
|
||||||
port = node.Port,
|
|
||||||
// TODO default ["0.0.0.0/0", "::/0"]
|
|
||||||
allowed_ips = new() { "0.0.0.0/0", "::/0" },
|
|
||||||
};
|
|
||||||
endpoint.private_key = node.Id;
|
|
||||||
endpoint.mtu = node.ShortId.IsNullOrEmpty() ? Global.TunMtus.First() : node.ShortId.ToInt();
|
|
||||||
endpoint.peers = new() { peer };
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(_tag, ex);
|
|
||||||
}
|
|
||||||
return await Task.FromResult(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<BaseServer4Sbox?> GenServer(ProfileItem node)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
|
|
||||||
if (node.ConfigType == EConfigType.WireGuard)
|
|
||||||
{
|
|
||||||
var endpoint = JsonUtils.Deserialize<Endpoints4Sbox>(txtOutbound);
|
|
||||||
await GenEndpoint(node, endpoint);
|
|
||||||
return endpoint;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
|
||||||
await GenOutbound(node, outbound);
|
|
||||||
return outbound;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(_tag, ex);
|
|
||||||
}
|
|
||||||
return await Task.FromResult<BaseServer4Sbox?>(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<int> GenOutboundMux(ProfileItem node, Outbound4Sbox outbound)
|
private async Task<int> GenOutboundMux(ProfileItem node, Outbound4Sbox outbound)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -1022,8 +918,7 @@ public class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
|
|
||||||
//current proxy
|
//current proxy
|
||||||
BaseServer4Sbox? outbound = singboxConfig.endpoints?.FirstOrDefault(t => t.tag == Global.ProxyTag) == null ? singboxConfig.outbounds.First() : null;
|
var outbound = singboxConfig.outbounds.First();
|
||||||
|
|
||||||
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
|
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
|
||||||
|
|
||||||
//Previous proxy
|
//Previous proxy
|
||||||
|
|
@ -1032,32 +927,17 @@ public class CoreConfigSingboxService
|
||||||
if (prevNode is not null
|
if (prevNode is not null
|
||||||
&& prevNode.ConfigType != EConfigType.Custom)
|
&& prevNode.ConfigType != EConfigType.Custom)
|
||||||
{
|
{
|
||||||
|
var prevOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
||||||
|
await GenOutbound(prevNode, prevOutbound);
|
||||||
prevOutboundTag = $"prev-{Global.ProxyTag}";
|
prevOutboundTag = $"prev-{Global.ProxyTag}";
|
||||||
var prevServer = await GenServer(prevNode);
|
prevOutbound.tag = prevOutboundTag;
|
||||||
prevServer.tag = prevOutboundTag;
|
singboxConfig.outbounds.Add(prevOutbound);
|
||||||
if (prevServer is Endpoints4Sbox endpoint)
|
|
||||||
{
|
|
||||||
singboxConfig.endpoints ??= new();
|
|
||||||
singboxConfig.endpoints.Add(endpoint);
|
|
||||||
}
|
|
||||||
else if (prevServer is Outbound4Sbox outboundPrev)
|
|
||||||
{
|
|
||||||
singboxConfig.outbounds.Add(outboundPrev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var nextServer = await GenChainOutbounds(subItem, outbound, prevOutboundTag);
|
var nextOutbound = await GenChainOutbounds(subItem, outbound, prevOutboundTag);
|
||||||
|
|
||||||
if (nextServer is not null)
|
if (nextOutbound is not null)
|
||||||
{
|
{
|
||||||
if (nextServer is Endpoints4Sbox endpoint)
|
singboxConfig.outbounds.Insert(0, nextOutbound);
|
||||||
{
|
|
||||||
singboxConfig.endpoints ??= new();
|
|
||||||
singboxConfig.endpoints.Insert(0, endpoint);
|
|
||||||
}
|
|
||||||
else if (nextServer is Outbound4Sbox outboundNext)
|
|
||||||
{
|
|
||||||
singboxConfig.outbounds.Insert(0, outboundNext);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -1080,13 +960,11 @@ public class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
|
|
||||||
var resultOutbounds = new List<Outbound4Sbox>();
|
var resultOutbounds = new List<Outbound4Sbox>();
|
||||||
var resultEndpoints = new List<Endpoints4Sbox>(); // For endpoints
|
|
||||||
var prevOutbounds = new List<Outbound4Sbox>(); // Separate list for prev outbounds
|
var prevOutbounds = new List<Outbound4Sbox>(); // Separate list for prev outbounds
|
||||||
var prevEndpoints = new List<Endpoints4Sbox>(); // Separate list for prev endpoints
|
|
||||||
var proxyTags = new List<string>(); // For selector and urltest outbounds
|
var proxyTags = new List<string>(); // For selector and urltest outbounds
|
||||||
|
|
||||||
// Cache for chain proxies to avoid duplicate generation
|
// Cache for chain proxies to avoid duplicate generation
|
||||||
var nextProxyCache = new Dictionary<string, BaseServer4Sbox?>();
|
var nextProxyCache = new Dictionary<string, Outbound4Sbox?>();
|
||||||
var prevProxyTags = new Dictionary<string, string?>(); // Map from profile name to tag
|
var prevProxyTags = new Dictionary<string, string?>(); // Map from profile name to tag
|
||||||
int prevIndex = 0; // Index for prev outbounds
|
int prevIndex = 0; // Index for prev outbounds
|
||||||
|
|
||||||
|
|
@ -1098,18 +976,19 @@ public class CoreConfigSingboxService
|
||||||
|
|
||||||
// Handle proxy chain
|
// Handle proxy chain
|
||||||
string? prevTag = null;
|
string? prevTag = null;
|
||||||
var currentServer = await GenServer(node);
|
var currentOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
||||||
var nextServer = nextProxyCache.GetValueOrDefault(node.Subid, null);
|
var nextOutbound = nextProxyCache.GetValueOrDefault(node.Subid, null);
|
||||||
if (nextServer != null)
|
if (nextOutbound != null)
|
||||||
{
|
{
|
||||||
nextServer = JsonUtils.DeepCopy(nextServer);
|
nextOutbound = JsonUtils.DeepCopy(nextOutbound);
|
||||||
}
|
}
|
||||||
|
|
||||||
var subItem = await AppHandler.Instance.GetSubItem(node.Subid);
|
var subItem = await AppHandler.Instance.GetSubItem(node.Subid);
|
||||||
|
|
||||||
// current proxy
|
// current proxy
|
||||||
currentServer.tag = $"{Global.ProxyTag}-{index}";
|
await GenOutbound(node, currentOutbound);
|
||||||
proxyTags.Add(currentServer.tag);
|
currentOutbound.tag = $"{Global.ProxyTag}-{index}";
|
||||||
|
proxyTags.Add(currentOutbound.tag);
|
||||||
|
|
||||||
if (!node.Subid.IsNullOrEmpty())
|
if (!node.Subid.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
|
|
@ -1132,32 +1011,18 @@ public class CoreConfigSingboxService
|
||||||
prevProxyTags[node.Subid] = prevTag;
|
prevProxyTags[node.Subid] = prevTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextServer = await GenChainOutbounds(subItem, currentServer, prevTag, nextServer);
|
nextOutbound = await GenChainOutbounds(subItem, currentOutbound, prevTag, nextOutbound);
|
||||||
if (!nextProxyCache.ContainsKey(node.Subid))
|
if (!nextProxyCache.ContainsKey(node.Subid))
|
||||||
{
|
{
|
||||||
nextProxyCache[node.Subid] = nextServer;
|
nextProxyCache[node.Subid] = nextOutbound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextServer is not null)
|
if (nextOutbound is not null)
|
||||||
{
|
{
|
||||||
if (nextServer is Endpoints4Sbox nextEndpoint)
|
resultOutbounds.Add(nextOutbound);
|
||||||
{
|
|
||||||
resultEndpoints.Add(nextEndpoint);
|
|
||||||
}
|
|
||||||
else if (nextServer is Outbound4Sbox nextOutbound)
|
|
||||||
{
|
|
||||||
resultOutbounds.Add(nextOutbound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currentServer is Endpoints4Sbox currentEndpoint)
|
|
||||||
{
|
|
||||||
resultEndpoints.Add(currentEndpoint);
|
|
||||||
}
|
|
||||||
else if (currentServer is Outbound4Sbox currentOutbound)
|
|
||||||
{
|
|
||||||
resultOutbounds.Add(currentOutbound);
|
|
||||||
}
|
}
|
||||||
|
resultOutbounds.Add(currentOutbound);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add urltest outbound (auto selection based on latency)
|
// Add urltest outbound (auto selection based on latency)
|
||||||
|
|
@ -1190,9 +1055,6 @@ public class CoreConfigSingboxService
|
||||||
resultOutbounds.AddRange(prevOutbounds);
|
resultOutbounds.AddRange(prevOutbounds);
|
||||||
resultOutbounds.AddRange(singboxConfig.outbounds);
|
resultOutbounds.AddRange(singboxConfig.outbounds);
|
||||||
singboxConfig.outbounds = resultOutbounds;
|
singboxConfig.outbounds = resultOutbounds;
|
||||||
singboxConfig.endpoints ??= new List<Endpoints4Sbox>();
|
|
||||||
resultEndpoints.AddRange(singboxConfig.endpoints);
|
|
||||||
singboxConfig.endpoints = resultEndpoints;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -1214,7 +1076,7 @@ public class CoreConfigSingboxService
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// The outbound configuration for the next proxy in the chain, or null if no next proxy exists.
|
/// The outbound configuration for the next proxy in the chain, or null if no next proxy exists.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
private async Task<BaseServer4Sbox?> GenChainOutbounds(SubItem subItem, BaseServer4Sbox outbound, string? prevOutboundTag, BaseServer4Sbox? nextOutbound = null)
|
private async Task<Outbound4Sbox?> GenChainOutbounds(SubItem subItem, Outbound4Sbox outbound, string? prevOutboundTag, Outbound4Sbox? nextOutbound = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -1230,7 +1092,11 @@ public class CoreConfigSingboxService
|
||||||
if (nextNode is not null
|
if (nextNode is not null
|
||||||
&& nextNode.ConfigType != EConfigType.Custom)
|
&& nextNode.ConfigType != EConfigType.Custom)
|
||||||
{
|
{
|
||||||
nextOutbound ??= await GenServer(nextNode);
|
if (nextOutbound == null)
|
||||||
|
{
|
||||||
|
nextOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
||||||
|
await GenOutbound(nextNode, nextOutbound);
|
||||||
|
}
|
||||||
nextOutbound.tag = outbound.tag;
|
nextOutbound.tag = outbound.tag;
|
||||||
|
|
||||||
outbound.tag = $"mid-{outbound.tag}";
|
outbound.tag = $"mid-{outbound.tag}";
|
||||||
|
|
@ -1249,7 +1115,7 @@ public class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
singboxConfig.route.final = Global.ProxyTag;
|
var dnsOutbound = "dns_out";
|
||||||
|
|
||||||
if (_config.TunModeItem.EnableTun)
|
if (_config.TunModeItem.EnableTun)
|
||||||
{
|
{
|
||||||
|
|
@ -1265,7 +1131,7 @@ public class CoreConfigSingboxService
|
||||||
singboxConfig.route.rules.Add(new()
|
singboxConfig.route.rules.Add(new()
|
||||||
{
|
{
|
||||||
port = new() { 53 },
|
port = new() { 53 },
|
||||||
action = "hijack-dns",
|
outbound = dnsOutbound,
|
||||||
process_name = lstDnsExe
|
process_name = lstDnsExe
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1276,25 +1142,13 @@ public class CoreConfigSingboxService
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_config.Inbound.First().SniffingEnabled)
|
if (!_config.Inbound.First().SniffingEnabled)
|
||||||
{
|
{
|
||||||
singboxConfig.route.rules.Add(new()
|
singboxConfig.route.rules.Add(new()
|
||||||
{
|
{
|
||||||
action = "sniff"
|
port = [53],
|
||||||
});
|
network = ["udp"],
|
||||||
singboxConfig.route.rules.Add(new()
|
outbound = dnsOutbound
|
||||||
{
|
|
||||||
protocol = new() { "dns" },
|
|
||||||
action = "hijack-dns"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
singboxConfig.route.rules.Add(new()
|
|
||||||
{
|
|
||||||
port = new() { 53 },
|
|
||||||
network = new() { "udp" },
|
|
||||||
action = "hijack-dns"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1309,24 +1163,7 @@ public class CoreConfigSingboxService
|
||||||
clash_mode = ERuleMode.Global.ToString()
|
clash_mode = ERuleMode.Global.ToString()
|
||||||
});
|
});
|
||||||
|
|
||||||
var domainStrategy = _config.RoutingBasicItem.DomainStrategy4Singbox.IsNullOrEmpty() ? null : _config.RoutingBasicItem.DomainStrategy4Singbox;
|
|
||||||
var defaultRouting = await ConfigHandler.GetDefaultRouting(_config);
|
|
||||||
if (defaultRouting.DomainStrategy4Singbox.IsNotEmpty())
|
|
||||||
{
|
|
||||||
domainStrategy = defaultRouting.DomainStrategy4Singbox;
|
|
||||||
}
|
|
||||||
var resolveRule = new Rule4Sbox
|
|
||||||
{
|
|
||||||
action = "resolve",
|
|
||||||
strategy = domainStrategy
|
|
||||||
};
|
|
||||||
if (_config.RoutingBasicItem.DomainStrategy == "IPOnDemand")
|
|
||||||
{
|
|
||||||
singboxConfig.route.rules.Add(resolveRule);
|
|
||||||
}
|
|
||||||
|
|
||||||
var routing = await ConfigHandler.GetDefaultRouting(_config);
|
var routing = await ConfigHandler.GetDefaultRouting(_config);
|
||||||
var ipRules = new List<RulesItem>();
|
|
||||||
if (routing != null)
|
if (routing != null)
|
||||||
{
|
{
|
||||||
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
|
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
|
||||||
|
|
@ -1335,21 +1172,9 @@ public class CoreConfigSingboxService
|
||||||
if (item.Enabled)
|
if (item.Enabled)
|
||||||
{
|
{
|
||||||
await GenRoutingUserRule(item, singboxConfig);
|
await GenRoutingUserRule(item, singboxConfig);
|
||||||
if (item.Ip != null && item.Ip.Count > 0)
|
|
||||||
{
|
|
||||||
ipRules.Add(item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_config.RoutingBasicItem.DomainStrategy == "IPIfNonMatch")
|
|
||||||
{
|
|
||||||
singboxConfig.route.rules.Add(resolveRule);
|
|
||||||
foreach (var item in ipRules)
|
|
||||||
{
|
|
||||||
await GenRoutingUserRule(item, singboxConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -1397,15 +1222,10 @@ public class CoreConfigSingboxService
|
||||||
item.OutboundTag = await GenRoutingUserRuleOutbound(item.OutboundTag, singboxConfig);
|
item.OutboundTag = await GenRoutingUserRuleOutbound(item.OutboundTag, singboxConfig);
|
||||||
var rules = singboxConfig.route.rules;
|
var rules = singboxConfig.route.rules;
|
||||||
|
|
||||||
var rule = new Rule4Sbox();
|
var rule = new Rule4Sbox()
|
||||||
if (item.OutboundTag == "block")
|
|
||||||
{
|
{
|
||||||
rule.action = "reject";
|
outbound = item.OutboundTag,
|
||||||
}
|
};
|
||||||
else
|
|
||||||
{
|
|
||||||
rule.outbound = item.OutboundTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.Port.IsNotEmpty())
|
if (item.Port.IsNotEmpty())
|
||||||
{
|
{
|
||||||
|
|
@ -1529,28 +1349,24 @@ public class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (address.StartsWith("geoip:!"))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else if (address.Equals("geoip:private"))
|
else if (address.Equals("geoip:private"))
|
||||||
{
|
{
|
||||||
rule.ip_is_private = true;
|
rule.ip_is_private = true;
|
||||||
}
|
}
|
||||||
else if (address.StartsWith("geoip:"))
|
else if (address.StartsWith("geoip:"))
|
||||||
{
|
{
|
||||||
rule.geoip ??= new();
|
if (rule.geoip is null)
|
||||||
|
{ rule.geoip = new(); }
|
||||||
rule.geoip?.Add(address.Substring(6));
|
rule.geoip?.Add(address.Substring(6));
|
||||||
}
|
}
|
||||||
else if (address.Equals("geoip:!private"))
|
|
||||||
{
|
|
||||||
rule.ip_is_private = false;
|
|
||||||
}
|
|
||||||
else if (address.StartsWith("geoip:!"))
|
|
||||||
{
|
|
||||||
rule.geoip ??= new();
|
|
||||||
rule.geoip?.Add(address.Substring(6));
|
|
||||||
rule.invert = true;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rule.ip_cidr ??= new();
|
if (rule.ip_cidr is null)
|
||||||
|
{ rule.ip_cidr = new(); }
|
||||||
rule.ip_cidr?.Add(address);
|
rule.ip_cidr?.Add(address);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1570,24 +1386,13 @@ public class CoreConfigSingboxService
|
||||||
return Global.ProxyTag;
|
return Global.ProxyTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
var server = await GenServer(node);
|
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
|
||||||
if (server is null)
|
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
|
||||||
{
|
await GenOutbound(node, outbound);
|
||||||
return Global.ProxyTag;
|
outbound.tag = Global.ProxyTag + node.IndexId.ToString();
|
||||||
}
|
singboxConfig.outbounds.Add(outbound);
|
||||||
|
|
||||||
server.tag = Global.ProxyTag + node.IndexId.ToString();
|
return outbound.tag;
|
||||||
if (server is Endpoints4Sbox endpoint)
|
|
||||||
{
|
|
||||||
singboxConfig.endpoints ??= new();
|
|
||||||
singboxConfig.endpoints.Add(endpoint);
|
|
||||||
}
|
|
||||||
else if (server is Outbound4Sbox outbound)
|
|
||||||
{
|
|
||||||
singboxConfig.outbounds.Add(outbound);
|
|
||||||
}
|
|
||||||
|
|
||||||
return server.tag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> GenDns(ProfileItem? node, SingboxConfig singboxConfig)
|
private async Task<int> GenDns(ProfileItem? node, SingboxConfig singboxConfig)
|
||||||
|
|
@ -1612,14 +1417,7 @@ public class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
singboxConfig.dns = dns4Sbox;
|
singboxConfig.dns = dns4Sbox;
|
||||||
|
|
||||||
if (dns4Sbox.servers != null && dns4Sbox.servers.Count > 0 && dns4Sbox.servers.First().address.IsNullOrEmpty())
|
await GenDnsDomains(node, singboxConfig, item);
|
||||||
{
|
|
||||||
await GenDnsDomains(node, singboxConfig, item);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await GenDnsDomainsLegacy(node, singboxConfig, item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -1634,75 +1432,6 @@ public class CoreConfigSingboxService
|
||||||
dns4Sbox.servers ??= [];
|
dns4Sbox.servers ??= [];
|
||||||
dns4Sbox.rules ??= [];
|
dns4Sbox.rules ??= [];
|
||||||
|
|
||||||
var tag = "local_resolver";
|
|
||||||
var localDnsAddress = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.SingboxDomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress;
|
|
||||||
|
|
||||||
if (localDnsAddress.StartsWith("tag://"))
|
|
||||||
{
|
|
||||||
tag = localDnsAddress.Substring(6);
|
|
||||||
|
|
||||||
var localDnsTag = "local_local";
|
|
||||||
|
|
||||||
dns4Sbox.servers.Add(new()
|
|
||||||
{
|
|
||||||
tag = localDnsTag,
|
|
||||||
type = "local"
|
|
||||||
});
|
|
||||||
|
|
||||||
dns4Sbox.rules.Insert(0, new()
|
|
||||||
{
|
|
||||||
server = localDnsTag,
|
|
||||||
clash_mode = ERuleMode.Direct.ToString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var (dnsType, dnsHost, dnsPort, dnsPath) = ParseDnsAddress(localDnsAddress);
|
|
||||||
|
|
||||||
dns4Sbox.servers.Add(new()
|
|
||||||
{
|
|
||||||
tag = tag,
|
|
||||||
type = dnsType,
|
|
||||||
server = dnsHost,
|
|
||||||
Interface = dnsType == "dhcp" ? dnsHost : null,
|
|
||||||
server_port = dnsPort,
|
|
||||||
path = dnsPath
|
|
||||||
});
|
|
||||||
|
|
||||||
dns4Sbox.rules.Insert(0, new()
|
|
||||||
{
|
|
||||||
server = tag,
|
|
||||||
clash_mode = ERuleMode.Direct.ToString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dns4Sbox.rules.Insert(0, new()
|
|
||||||
{
|
|
||||||
server = dns4Sbox.servers.Where(t => t.detour == Global.ProxyTag).Select(t => t.tag).FirstOrDefault() ?? "remote",
|
|
||||||
clash_mode = ERuleMode.Global.ToString()
|
|
||||||
});
|
|
||||||
|
|
||||||
//Tun2SocksAddress
|
|
||||||
if (_config.TunModeItem.EnableTun && node?.ConfigType == EConfigType.SOCKS && Utils.IsDomain(node?.Sni))
|
|
||||||
{
|
|
||||||
dns4Sbox.rules.Insert(0, new()
|
|
||||||
{
|
|
||||||
server = tag,
|
|
||||||
domain = [node?.Sni],
|
|
||||||
strategy = string.IsNullOrEmpty(dNSItem?.DomainStrategy4Freedom) ? null : dNSItem?.DomainStrategy4Freedom
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
singboxConfig.dns = dns4Sbox;
|
|
||||||
return await Task.FromResult(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<int> GenDnsDomainsLegacy(ProfileItem? node, SingboxConfig singboxConfig, DNSItem? dNSItem)
|
|
||||||
{
|
|
||||||
var dns4Sbox = singboxConfig.dns ?? new();
|
|
||||||
dns4Sbox.servers ??= [];
|
|
||||||
dns4Sbox.rules ??= [];
|
|
||||||
|
|
||||||
var tag = "local_local";
|
var tag = "local_local";
|
||||||
dns4Sbox.servers.Add(new()
|
dns4Sbox.servers.Add(new()
|
||||||
{
|
{
|
||||||
|
|
@ -1750,91 +1479,6 @@ public class CoreConfigSingboxService
|
||||||
return await Task.FromResult(0);
|
return await Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private (string type, string? host, int? port, string? path) ParseDnsAddress(string address)
|
|
||||||
{
|
|
||||||
string type = "udp";
|
|
||||||
string? host = null;
|
|
||||||
int? port = null;
|
|
||||||
string? path = null;
|
|
||||||
|
|
||||||
if (address is "local" or "localhost")
|
|
||||||
{
|
|
||||||
return ("local", null, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (address.StartsWith("dhcp://", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
string interface_name = address.Substring(7);
|
|
||||||
return ("dhcp", interface_name == "auto" ? null : interface_name, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!address.Contains("://"))
|
|
||||||
{
|
|
||||||
// udp dns
|
|
||||||
host = address;
|
|
||||||
return (type, host, port, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int protocolEndIndex = address.IndexOf("://", StringComparison.Ordinal);
|
|
||||||
type = address.Substring(0, protocolEndIndex).ToLower();
|
|
||||||
|
|
||||||
var uri = new Uri(address);
|
|
||||||
host = uri.Host;
|
|
||||||
|
|
||||||
if (!uri.IsDefaultPort)
|
|
||||||
{
|
|
||||||
port = uri.Port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((type == "https" || type == "h3") && !string.IsNullOrEmpty(uri.AbsolutePath) && uri.AbsolutePath != "/")
|
|
||||||
{
|
|
||||||
path = uri.AbsolutePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (UriFormatException)
|
|
||||||
{
|
|
||||||
int protocolEndIndex = address.IndexOf("://", StringComparison.Ordinal);
|
|
||||||
if (protocolEndIndex > 0)
|
|
||||||
{
|
|
||||||
type = address.Substring(0, protocolEndIndex).ToLower();
|
|
||||||
string remaining = address.Substring(protocolEndIndex + 3);
|
|
||||||
|
|
||||||
int portIndex = remaining.IndexOf(':');
|
|
||||||
int pathIndex = remaining.IndexOf('/');
|
|
||||||
|
|
||||||
if (portIndex > 0)
|
|
||||||
{
|
|
||||||
host = remaining.Substring(0, portIndex);
|
|
||||||
string portPart = pathIndex > portIndex
|
|
||||||
? remaining.Substring(portIndex + 1, pathIndex - portIndex - 1)
|
|
||||||
: remaining.Substring(portIndex + 1);
|
|
||||||
|
|
||||||
if (int.TryParse(portPart, out int parsedPort))
|
|
||||||
{
|
|
||||||
port = parsedPort;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pathIndex > 0)
|
|
||||||
{
|
|
||||||
host = remaining.Substring(0, pathIndex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
host = remaining;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pathIndex > 0 && (type == "https" || type == "h3"))
|
|
||||||
{
|
|
||||||
path = remaining.Substring(pathIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (type, host, port, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<int> GenExperimental(SingboxConfig singboxConfig)
|
private async Task<int> GenExperimental(SingboxConfig singboxConfig)
|
||||||
{
|
{
|
||||||
//if (_config.guiItem.enableStatistics)
|
//if (_config.guiItem.enableStatistics)
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ public class CoreConfigV2rayService
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (it.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls)
|
if (it.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -640,8 +640,7 @@ public class CoreConfigV2rayService
|
||||||
if (node == null
|
if (node == null
|
||||||
|| node.ConfigType == EConfigType.Custom
|
|| node.ConfigType == EConfigType.Custom
|
||||||
|| node.ConfigType == EConfigType.Hysteria2
|
|| node.ConfigType == EConfigType.Hysteria2
|
||||||
|| node.ConfigType == EConfigType.TUIC
|
|| node.ConfigType == EConfigType.TUIC)
|
||||||
|| node.ConfigType == EConfigType.Anytls)
|
|
||||||
{
|
{
|
||||||
return Global.ProxyTag;
|
return Global.ProxyTag;
|
||||||
}
|
}
|
||||||
|
|
@ -1223,7 +1222,6 @@ public class CoreConfigV2rayService
|
||||||
&& prevNode.ConfigType != EConfigType.Custom
|
&& prevNode.ConfigType != EConfigType.Custom
|
||||||
&& prevNode.ConfigType != EConfigType.Hysteria2
|
&& prevNode.ConfigType != EConfigType.Hysteria2
|
||||||
&& prevNode.ConfigType != EConfigType.TUIC
|
&& prevNode.ConfigType != EConfigType.TUIC
|
||||||
&& prevNode.ConfigType != EConfigType.Anytls
|
|
||||||
&& Utils.IsDomain(prevNode.Address))
|
&& Utils.IsDomain(prevNode.Address))
|
||||||
{
|
{
|
||||||
domainList.Add(prevNode.Address);
|
domainList.Add(prevNode.Address);
|
||||||
|
|
@ -1235,7 +1233,6 @@ public class CoreConfigV2rayService
|
||||||
&& nextNode.ConfigType != EConfigType.Custom
|
&& nextNode.ConfigType != EConfigType.Custom
|
||||||
&& nextNode.ConfigType != EConfigType.Hysteria2
|
&& nextNode.ConfigType != EConfigType.Hysteria2
|
||||||
&& nextNode.ConfigType != EConfigType.TUIC
|
&& nextNode.ConfigType != EConfigType.TUIC
|
||||||
&& nextNode.ConfigType != EConfigType.Anytls
|
|
||||||
&& Utils.IsDomain(nextNode.Address))
|
&& Utils.IsDomain(nextNode.Address))
|
||||||
{
|
{
|
||||||
domainList.Add(nextNode.Address);
|
domainList.Add(nextNode.Address);
|
||||||
|
|
@ -1353,8 +1350,7 @@ public class CoreConfigV2rayService
|
||||||
if (prevNode is not null
|
if (prevNode is not null
|
||||||
&& prevNode.ConfigType != EConfigType.Custom
|
&& prevNode.ConfigType != EConfigType.Custom
|
||||||
&& prevNode.ConfigType != EConfigType.Hysteria2
|
&& prevNode.ConfigType != EConfigType.Hysteria2
|
||||||
&& prevNode.ConfigType != EConfigType.TUIC
|
&& prevNode.ConfigType != EConfigType.TUIC)
|
||||||
&& prevNode.ConfigType != EConfigType.Anytls)
|
|
||||||
{
|
{
|
||||||
var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
|
var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
|
||||||
await GenOutbound(prevNode, prevOutbound);
|
await GenOutbound(prevNode, prevOutbound);
|
||||||
|
|
@ -1429,8 +1425,7 @@ public class CoreConfigV2rayService
|
||||||
if (prevNode is not null
|
if (prevNode is not null
|
||||||
&& prevNode.ConfigType != EConfigType.Custom
|
&& prevNode.ConfigType != EConfigType.Custom
|
||||||
&& prevNode.ConfigType != EConfigType.Hysteria2
|
&& prevNode.ConfigType != EConfigType.Hysteria2
|
||||||
&& prevNode.ConfigType != EConfigType.TUIC
|
&& prevNode.ConfigType != EConfigType.TUIC)
|
||||||
&& prevNode.ConfigType != EConfigType.Anytls)
|
|
||||||
{
|
{
|
||||||
var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
|
var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
|
||||||
await GenOutbound(prevNode, prevOutbound);
|
await GenOutbound(prevNode, prevOutbound);
|
||||||
|
|
@ -1499,8 +1494,7 @@ public class CoreConfigV2rayService
|
||||||
if (nextNode is not null
|
if (nextNode is not null
|
||||||
&& nextNode.ConfigType != EConfigType.Custom
|
&& nextNode.ConfigType != EConfigType.Custom
|
||||||
&& nextNode.ConfigType != EConfigType.Hysteria2
|
&& nextNode.ConfigType != EConfigType.Hysteria2
|
||||||
&& nextNode.ConfigType != EConfigType.TUIC
|
&& nextNode.ConfigType != EConfigType.TUIC)
|
||||||
&& nextNode.ConfigType != EConfigType.Anytls)
|
|
||||||
{
|
{
|
||||||
if (nextOutbound == null)
|
if (nextOutbound == null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -358,8 +358,8 @@ public class SpeedtestService
|
||||||
private List<List<ServerTestItem>> GetTestBatchItem(List<ServerTestItem> lstSelected, int pageSize)
|
private List<List<ServerTestItem>> GetTestBatchItem(List<ServerTestItem> lstSelected, int pageSize)
|
||||||
{
|
{
|
||||||
List<List<ServerTestItem>> lstTest = new();
|
List<List<ServerTestItem>> lstTest = new();
|
||||||
var lst1 = lstSelected.Where(t => t.ConfigType is not (EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls)).ToList();
|
var lst1 = lstSelected.Where(t => t.ConfigType is not (EConfigType.Hysteria2 or EConfigType.TUIC)).ToList();
|
||||||
var lst2 = lstSelected.Where(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.Anytls).ToList();
|
var lst2 = lstSelected.Where(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC).ToList();
|
||||||
|
|
||||||
for (var num = 0; num < (int)Math.Ceiling(lst1.Count * 1.0 / pageSize); num++)
|
for (var num = 0; num < (int)Math.Ceiling(lst1.Count * 1.0 / pageSize); num++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,7 @@ public class ClashProxiesViewModel : MyReactiveObject
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SelectedGroup = _proxyGroups.First();
|
SelectedGroup = _proxyGroups.First();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> AddHysteria2ServerCmd { get; }
|
||||||
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> 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; }
|
||||||
|
|
@ -112,10 +111,6 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
await AddServerAsync(true, EConfigType.WireGuard);
|
await AddServerAsync(true, EConfigType.WireGuard);
|
||||||
});
|
});
|
||||||
AddAnytlsServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
||||||
{
|
|
||||||
await AddServerAsync(true, EConfigType.Anytls);
|
|
||||||
});
|
|
||||||
AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
await AddServerAsync(true, EConfigType.Custom);
|
await AddServerAsync(true, EConfigType.Custom);
|
||||||
|
|
|
||||||
|
|
@ -533,26 +533,6 @@
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Watermark="1500" />
|
Watermark="1500" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
|
||||||
x:Name="gridAnytls"
|
|
||||||
Grid.Row="2"
|
|
||||||
ColumnDefinitions="180,Auto"
|
|
||||||
IsVisible="False"
|
|
||||||
RowDefinitions="Auto,Auto,Auto">
|
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Grid.Row="1"
|
|
||||||
Grid.Column="0"
|
|
||||||
Margin="{StaticResource Margin4}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{x:Static resx:ResUI.TbId3}" />
|
|
||||||
<TextBox
|
|
||||||
x:Name="txtId10"
|
|
||||||
Grid.Row="1"
|
|
||||||
Grid.Column="1"
|
|
||||||
Width="400"
|
|
||||||
Margin="{StaticResource Margin4}" />
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Separator
|
<Separator
|
||||||
x:Name="sepa2"
|
x:Name="sepa2"
|
||||||
|
|
|
||||||
|
|
@ -102,12 +102,6 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||||
gridTls.IsVisible = false;
|
gridTls.IsVisible = false;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.Anytls:
|
|
||||||
gridAnytls.IsVisible = true;
|
|
||||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
|
||||||
cmbCoreType.IsEnabled = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||||
|
|
||||||
|
|
@ -173,10 +167,6 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId9.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId9.Text).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.Anytls:
|
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId10.Text).DisposeWith(disposables);
|
|
||||||
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);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.SelectedValue).DisposeWith(disposables);
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem x:Name="menuAddHysteria2Server" Header="{x:Static resx:ResUI.menuAddHysteria2Server}" />
|
<MenuItem x:Name="menuAddHysteria2Server" Header="{x:Static resx:ResUI.menuAddHysteria2Server}" />
|
||||||
<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>
|
</MenuItem>
|
||||||
|
|
||||||
<MenuItem Padding="8,0">
|
<MenuItem Padding="8,0">
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
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.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.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);
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,6 @@
|
||||||
<ScrollViewer x:Name="msgScrollViewer" VerticalScrollBarVisibility="Auto">
|
<ScrollViewer x:Name="msgScrollViewer" VerticalScrollBarVisibility="Auto">
|
||||||
<SelectableTextBlock
|
<SelectableTextBlock
|
||||||
Name="txtMsg"
|
Name="txtMsg"
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Classes="TextArea"
|
Classes="TextArea"
|
||||||
TextAlignment="Left"
|
TextAlignment="Left"
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ public partial class RoutingSettingWindow : WindowBase<RoutingSettingViewModel>
|
||||||
|
|
||||||
private void linkdomainStrategy4Singbox_Click(object? sender, RoutedEventArgs e)
|
private void linkdomainStrategy4Singbox_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/route/rule_action/#strategy");
|
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnCancel_Click(object? sender, RoutedEventArgs e)
|
private void btnCancel_Click(object? sender, RoutedEventArgs e)
|
||||||
|
|
|
||||||
|
|
@ -707,35 +707,6 @@
|
||||||
materialDesign:HintAssist.Hint="1500"
|
materialDesign:HintAssist.Hint="1500"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
|
||||||
x:Name="gridAnytls"
|
|
||||||
Grid.Row="2"
|
|
||||||
Visibility="Hidden">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<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 Margin4}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
|
||||||
Text="{x:Static resx:ResUI.TbId3}" />
|
|
||||||
<TextBox
|
|
||||||
x:Name="txtId10"
|
|
||||||
Grid.Row="1"
|
|
||||||
Grid.Column="1"
|
|
||||||
Width="400"
|
|
||||||
Margin="{StaticResource Margin4}"
|
|
||||||
Style="{StaticResource DefTextBox}" />
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Separator
|
<Separator
|
||||||
x:Name="sepa2"
|
x:Name="sepa2"
|
||||||
|
|
|
||||||
|
|
@ -96,12 +96,6 @@ public partial class AddServerWindow
|
||||||
gridTls.Visibility = Visibility.Collapsed;
|
gridTls.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.Anytls:
|
|
||||||
gridAnytls.Visibility = Visibility.Visible;
|
|
||||||
cmbCoreType.IsEnabled = false;
|
|
||||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||||
|
|
||||||
|
|
@ -167,10 +161,6 @@ public partial class AddServerWindow
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId9.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId9.Text).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.Anytls:
|
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId10.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);
|
||||||
|
|
|
||||||
|
|
@ -108,10 +108,6 @@
|
||||||
x:Name="menuAddTuicServer"
|
x:Name="menuAddTuicServer"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuAddTuicServer}" />
|
Header="{x:Static resx:ResUI.menuAddTuicServer}" />
|
||||||
<MenuItem
|
|
||||||
x:Name="menuAddAnytlsServer"
|
|
||||||
Height="{StaticResource MenuItemHeight}"
|
|
||||||
Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,6 @@ public partial class MainWindow
|
||||||
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.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.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);
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ public partial class MsgView
|
||||||
menuMsgViewCopy.Click += menuMsgViewCopy_Click;
|
menuMsgViewCopy.Click += menuMsgViewCopy_Click;
|
||||||
menuMsgViewCopyAll.Click += menuMsgViewCopyAll_Click;
|
menuMsgViewCopyAll.Click += menuMsgViewCopyAll_Click;
|
||||||
menuMsgViewClear.Click += menuMsgViewClear_Click;
|
menuMsgViewClear.Click += menuMsgViewClear_Click;
|
||||||
|
|
||||||
cmbMsgFilter.ItemsSource = Global.PresetMsgFilters;
|
cmbMsgFilter.ItemsSource = Global.PresetMsgFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ public partial class RoutingSettingWindow
|
||||||
|
|
||||||
private void linkdomainStrategy4Singbox_Click(object sender, RoutedEventArgs e)
|
private void linkdomainStrategy4Singbox_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/route/rule_action/#strategy");
|
ProcUtils.ProcessStart("https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
|
private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue