Compare commits

...

4 commits

Author SHA1 Message Date
2dust
06cec89ec9 up 7.19.3
Some checks failed
release Linux / build (Release) (push) Has been cancelled
release macOS / build (Release) (push) Has been cancelled
release Windows desktop (Avalonia UI) / build (Release) (push) Has been cancelled
release Windows / build (Release) (push) Has been cancelled
release Linux / rpm (push) Has been cancelled
2026-03-10 17:38:03 +08:00
2dust
26f65dd3b2 Code cleanup: pattern matching and minor fixes 2026-03-10 17:19:21 +08:00
2dust
0c2114d2e1 Refactor SRS rule collection and add DNS parsing 2026-03-10 15:29:36 +08:00
DHR60
4af528f8e2
Typo (#8917) 2026-03-10 14:10:23 +08:00
11 changed files with 87 additions and 39 deletions

View file

@ -1,7 +1,7 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<Version>7.19.2</Version> <Version>7.19.3</Version>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>

View file

@ -81,7 +81,9 @@ public class NodeValidator
{ {
var transportError = ValidateSingboxTransport(item.ConfigType, net); var transportError = ValidateSingboxTransport(item.ConfigType, net);
if (transportError != null) if (transportError != null)
{
v.Error(transportError); v.Error(transportError);
}
if (!Global.SingboxSupportConfigType.Contains(item.ConfigType)) if (!Global.SingboxSupportConfigType.Contains(item.ConfigType))
{ {

View file

@ -1040,8 +1040,8 @@ public static class ConfigHandler
if (profileItem.StreamSecurity.IsNotEmpty()) if (profileItem.StreamSecurity.IsNotEmpty())
{ {
if (profileItem.StreamSecurity != Global.StreamSecurity if (profileItem.StreamSecurity is not Global.StreamSecurity
&& profileItem.StreamSecurity != Global.StreamSecurityReality) and not Global.StreamSecurityReality)
{ {
profileItem.StreamSecurity = string.Empty; profileItem.StreamSecurity = string.Empty;
} }

View file

@ -9,6 +9,6 @@ public class ServerTestItem
public EConfigType ConfigType { get; set; } public EConfigType ConfigType { get; set; }
public bool AllowTest { get; set; } public bool AllowTest { get; set; }
public int QueueNum { get; set; } public int QueueNum { get; set; }
public required ProfileItem Profile { get; set; } public ProfileItem Profile { get; set; }
public ECoreType CoreType { get; set; } public ECoreType CoreType { get; set; }
} }

View file

@ -243,7 +243,6 @@ public partial class CoreConfigSingboxService
if (Utils.IsIpv6(predefined)) if (Utils.IsIpv6(predefined))
{ {
rule.answer = new List<string> { $"*. IN AAAA {predefined}" }; rule.answer = new List<string> { $"*. IN AAAA {predefined}" };
} }
else else
{ {

View file

@ -321,19 +321,19 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
{ {
outbound.streamSettings ??= new(); outbound.streamSettings ??= new();
outbound.streamSettings.sockopt ??= new(); outbound.streamSettings.sockopt ??= new();
outbound.streamSettings.sockopt.dialerProxy = "tun-project-ss"; outbound.streamSettings.sockopt.dialerProxy = "tun-protect-ss";
} }
// ech protected // ech protected
foreach (var outbound in _coreConfig.outbounds foreach (var outbound in _coreConfig.outbounds
.Where(outbound => outbound.streamSettings?.tlsSettings?.echConfigList?.IsNullOrEmpty() == false)) .Where(outbound => outbound.streamSettings?.tlsSettings?.echConfigList?.IsNullOrEmpty() == false))
{ {
outbound.streamSettings!.tlsSettings!.echSockopt ??= new(); outbound.streamSettings!.tlsSettings!.echSockopt ??= new();
outbound.streamSettings.tlsSettings.echSockopt.dialerProxy = "tun-project-ss"; outbound.streamSettings.tlsSettings.echSockopt.dialerProxy = "tun-protect-ss";
} }
_coreConfig.outbounds.Add(new CoreConfigV2rayService(context with _coreConfig.outbounds.Add(new CoreConfigV2rayService(context with
{ {
Node = protectNode, Node = protectNode,
}).BuildProxyOutbound("tun-project-ss")); }).BuildProxyOutbound("tun-protect-ss"));
_coreConfig.routing.rules ??= []; _coreConfig.routing.rules ??= [];
var hasBalancer = _coreConfig.routing.balancers is { Count: > 0 }; var hasBalancer = _coreConfig.routing.balancers is { Count: > 0 };

View file

@ -363,44 +363,36 @@ public class UpdateService(Config config, Func<bool, string, Task> updateFunc)
var geoipFiles = new List<string>(); var geoipFiles = new List<string>();
var geoSiteFiles = new List<string>(); var geoSiteFiles = new List<string>();
//Collect used files list // Collect from routing rules
var routingItems = await AppManager.Instance.RoutingItems(); var routingItems = await AppManager.Instance.RoutingItems();
foreach (var routing in routingItems) foreach (var routing in routingItems)
{ {
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
foreach (var item in rules ?? []) foreach (var item in rules ?? [])
{ {
foreach (var ip in item.Ip ?? []) AddPrefixedItems(item.Ip, "geoip:", geoipFiles);
{ AddPrefixedItems(item.Domain, "geosite:", geoSiteFiles);
var prefix = "geoip:";
if (ip.StartsWith(prefix))
{
geoipFiles.Add(ip.Substring(prefix.Length));
}
}
foreach (var domain in item.Domain ?? [])
{
var prefix = "geosite:";
if (domain.StartsWith(prefix))
{
geoSiteFiles.Add(domain.Substring(prefix.Length));
}
}
} }
} }
//append dns items TODO // Collect from DNS configuration
geoSiteFiles.Add("google"); var dnsItem = await AppManager.Instance.GetDNSItem(ECoreType.sing_box);
geoSiteFiles.Add("cn"); if (dnsItem != null)
geoSiteFiles.Add("geolocation-cn"); {
geoSiteFiles.Add("category-ads-all"); ExtractDnsRuleSets(dnsItem.NormalDNS, geoipFiles, geoSiteFiles);
ExtractDnsRuleSets(dnsItem.TunDNS, geoipFiles, geoSiteFiles);
}
// Append default items
geoSiteFiles.AddRange(["google", "cn", "geolocation-cn", "category-ads-all"]);
// Download files
var path = Utils.GetBinPath("srss"); var path = Utils.GetBinPath("srss");
if (!Directory.Exists(path)) if (!Directory.Exists(path))
{ {
Directory.CreateDirectory(path); Directory.CreateDirectory(path);
} }
foreach (var item in geoipFiles.Distinct()) foreach (var item in geoipFiles.Distinct())
{ {
await UpdateSrsFile("geoip", item); await UpdateSrsFile("geoip", item);
@ -412,6 +404,63 @@ public class UpdateService(Config config, Func<bool, string, Task> updateFunc)
} }
} }
private void AddPrefixedItems(List<string>? items, string prefix, List<string> output)
{
if (items == null)
{
return;
}
foreach (var item in items)
{
if (item.StartsWith(prefix))
{
output.Add(item.Substring(prefix.Length));
}
}
}
private void ExtractDnsRuleSets(string? dnsJson, List<string> geoipFiles, List<string> geoSiteFiles)
{
if (string.IsNullOrEmpty(dnsJson))
{
return;
}
try
{
var dns = JsonUtils.Deserialize<Dns4Sbox>(dnsJson);
if (dns?.rules != null)
{
foreach (var rule in dns.rules)
{
ExtractSrsRuleSets(rule, geoipFiles, geoSiteFiles);
}
}
}
catch { }
}
private void ExtractSrsRuleSets(Rule4Sbox? rule, List<string> geoipFiles, List<string> geoSiteFiles)
{
if (rule == null)
{
return;
}
AddPrefixedItems(rule.rule_set, "geosite-", geoSiteFiles);
AddPrefixedItems(rule.rule_set, "geoip-", geoipFiles);
// Handle nested rules recursively
if (rule.rules != null)
{
foreach (var nestedRule in rule.rules)
{
ExtractSrsRuleSets(nestedRule, geoipFiles, geoSiteFiles);
}
}
}
private async Task UpdateSrsFile(string type, string srsName) private async Task UpdateSrsFile(string type, string srsName)
{ {
var srsUrl = string.IsNullOrEmpty(_config.ConstItem.SrsSourceUrl) var srsUrl = string.IsNullOrEmpty(_config.ConstItem.SrsSourceUrl)

View file

@ -97,8 +97,7 @@ public partial class ProfilesSelectWindow
private void LstProfiles_ColumnHeader_Click(object sender, RoutedEventArgs e) private void LstProfiles_ColumnHeader_Click(object sender, RoutedEventArgs e)
{ {
var colHeader = sender as DataGridColumnHeader; if (sender is not DataGridColumnHeader colHeader || colHeader.TabIndex < 0 || colHeader.Column == null)
if (colHeader == null || colHeader.TabIndex < 0 || colHeader.Column == null)
{ {
return; return;
} }

View file

@ -233,8 +233,7 @@ public partial class ProfilesView
private void LstProfiles_ColumnHeader_Click(object sender, RoutedEventArgs e) private void LstProfiles_ColumnHeader_Click(object sender, RoutedEventArgs e)
{ {
var colHeader = sender as DataGridColumnHeader; if (sender is not DataGridColumnHeader colHeader || colHeader.TabIndex < 0 || colHeader.Column == null)
if (colHeader == null || colHeader.TabIndex < 0 || colHeader.Column == null)
{ {
return; return;
} }