Add Singbox Geo RuleSet setting

This commit is contained in:
GibMeMyPacket 2024-04-15 16:50:22 +00:00 committed by GibMeMyPacket
parent e0cea929ea
commit 24e7258534
16 changed files with 756 additions and 472 deletions

View file

@ -43,6 +43,7 @@ namespace v2rayN
public const string TunSingboxRulesFileName = "v2rayN.Sample.tun_singbox_rules";
public const string DNSV2rayNormalFileName = "v2rayN.Sample.dns_v2ray_normal";
public const string DNSSingboxNormalFileName = "v2rayN.Sample.dns_singbox_normal";
public const string SingboxGeoRuleSetsFileName = "v2rayN.Sample.singbox_geo_rulesets";
public const string DefaultSecurity = "auto";
public const string DefaultNetwork = "tcp";

View file

@ -1780,5 +1780,44 @@ namespace v2rayN.Handler
}
#endregion DNS
#region Sing Geo RuleSets
public static int InitBuiltinSingGeoRuleSets(Config config)
{
var item = LazyConfig.Instance.GetSingGeoRuleSets();
if (item is not null && item.rules != "")
{
return 0;
}
var item2 = new SingGeoRuleSet()
{
id = Utils.GetGUID(false),
remarks = "sing-box",
rules = Utils.GetEmbedText(Global.SingboxGeoRuleSetsFileName),
};
return SaveSingGeoRuleSet(config, item2);
}
public static int SaveSingGeoRuleSet(Config config, SingGeoRuleSet item)
{
if (Utils.IsNullOrEmpty(item.id))
{
item.id = Utils.GetGUID(false);
}
if (SQLiteHelper.Instance.Replace(item) > 0)
{
return 0;
}
else
{
return -1;
}
}
public static SingGeoRuleSet? GetDefaultSingGeoRuleSet(Config config)
{
return LazyConfig.Instance.GetSingGeoRuleSets();
}
#endregion
}
}

View file

@ -1,4 +1,5 @@
using System.Net;
using System.Globalization;
using System.Net;
using System.Net.NetworkInformation;
using v2rayN.Models;
using v2rayN.Resx;
@ -56,6 +57,8 @@ namespace v2rayN.Handler
GenStatistic(singboxConfig);
GenGeoRuleSetFromJson(singboxConfig);
ConvertGeo2Ruleset(singboxConfig);
msg = string.Format(ResUI.SuccessfulConfiguration, "");
@ -886,9 +889,20 @@ namespace v2rayN.Handler
}
//Add ruleset srs
singboxConfig.route.rule_set = [];
if (singboxConfig.route.rule_set is null) singboxConfig.route.rule_set = new();
foreach (var item in new HashSet<string>(ruleSets))
{
var exists = false;
foreach (var ruleSetItem in singboxConfig.route.rule_set)
{
if (ruleSetItem?.url?.EndsWith(item + ".srs", true, CultureInfo.InvariantCulture) ?? false)
{
exists = true;
break;
}
}
if (exists) continue;
singboxConfig.route.rule_set.Add(new()
{
type = "remote",
@ -898,7 +912,27 @@ namespace v2rayN.Handler
download_detour = Global.ProxyTag
});
}
return 0;
}
private int GenGeoRuleSetFromJson(SingboxConfig singboxConfig)
{
var gr = LazyConfig.Instance.GetSingGeoRuleSets();
if (gr == null) return -1;
var rules = gr.rules;
if (gr.rules.Length == 0) return -1;
var parsedRules = JsonUtils.Deserialize<List<Ruleset4Sbox>>(rules);
if (parsedRules is null) return -1;
// manipulate and set defaults
for (int i = 0; i < parsedRules.Count; i++)
{
if (string.IsNullOrEmpty(parsedRules[i].download_detour)) parsedRules[i].download_detour = "proxy";
if (string.IsNullOrEmpty(parsedRules[i].format)) parsedRules[i].format = "binary";
if (string.IsNullOrEmpty(parsedRules[i].type)) parsedRules[i].type = "remote";
}
if (singboxConfig.route.rule_set is null) singboxConfig.route.rule_set = new();
singboxConfig.route.rule_set.AddRange(parsedRules);
return 0;
}

View file

@ -36,6 +36,7 @@ namespace v2rayN.Handler
SQLiteHelper.Instance.CreateTable<RoutingItem>();
SQLiteHelper.Instance.CreateTable<ProfileExItem>();
SQLiteHelper.Instance.CreateTable<DNSItem>();
SQLiteHelper.Instance.CreateTable<SingGeoRuleSet>();
}
#region Config
@ -160,6 +161,11 @@ namespace v2rayN.Handler
return SQLiteHelper.Instance.Table<DNSItem>().FirstOrDefault(it => it.coreType == eCoreType);
}
public SingGeoRuleSet? GetSingGeoRuleSets()
{
return SQLiteHelper.Instance.Table<SingGeoRuleSet>().FirstOrDefault();
}
#endregion SqliteHelper
#region Core Type

View file

@ -0,0 +1,15 @@
using SQLite;
namespace v2rayN.Models
{
[Serializable]
public class SingGeoRuleSet
{
[PrimaryKey]
public string id { get; set; }
public string remarks { get; set; }
public string rules { get; set; }
}
}

File diff suppressed because it is too large Load diff

View file

@ -1003,4 +1003,10 @@
<data name="TbSettingsEnableHWA" xml:space="preserve">
<value>فعال‌سازی شتاب‌دهنده سخت‌افزاری (نیاز به راه‌اندازی مجدد)</value>
</data>
<data name="TbRoutingTabRuleSet" xml:space="preserve">
<value>لیست مجموعه فایل های Geo برای Sing-box</value>
</data>
<data name="TbSettingSingGeoImportDefRuleSets" xml:space="preserve">
<value>برای وارد کردن مجموعه قوانین Geo کلیک کنید</value>
</data>
</root>

View file

@ -1207,4 +1207,16 @@
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>Enable fragment</value>
</data>
<data name="TbRoutingTabRuleSet" xml:space="preserve">
<value>Sing-box Geo RuleSets</value>
</data>
<data name="TbSettingsSingGeoRuleSets" xml:space="preserve">
<value>Sing-box Geo RuleSet JSON (Array)</value>
</data>
<data name="TbSettingSingGeoImportDefRuleSets" xml:space="preserve">
<value>Click here to import default geo ruleset(s)</value>
</data>
<data name="TbSingGeoRuleSetDoc" xml:space="preserve">
<value>Please fill in RuleSet structure, click to view the document</value>
</data>
</root>

View file

@ -1204,4 +1204,16 @@
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
<value>使用Xray且非Tun模式启用和分组前置代理冲突</value>
</data>
<data name="TbRoutingTabRuleSet" xml:space="preserve">
<value>Sing-Box Geo规则集</value>
</data>
<data name="TbSettingsSingGeoRuleSets" xml:space="preserve">
<value>Sing-Box Geo Ruleset JSON数组</value>
</data>
<data name="TbSettingSingGeoImportDefRuleSets" xml:space="preserve">
<value>单击此处以导入默认地理规则集</value>
</data>
<data name="TbSingGeoRuleSetDoc" xml:space="preserve">
<value>请填写规则集结构,单击以查看文档</value>
</data>
</root>

View file

@ -1177,4 +1177,16 @@
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
<value>使用Xray且非Tun模式啟用和分組前置代理衝突</value>
</data>
<data name="TbSingGeoRuleSetDoc" xml:space="preserve">
<value>請填寫規則集結構,單擊以查看文檔</value>
</data>
<data name="TbSettingsSingGeoRuleSets" xml:space="preserve">
<value>Sing-Box Geo Ruleset JSON數組</value>
</data>
<data name="TbRoutingTabRuleSet" xml:space="preserve">
<value>Sing-Box Geo規則集</value>
</data>
<data name="TbSettingSingGeoImportDefRuleSets" xml:space="preserve">
<value>單擊此處以導入默認地理規則集</value>
</data>
</root>

View file

@ -0,0 +1,8 @@
[
{
"tag": "geosite-category-ads-all",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-category-ads-all.srs"
}
]

View file

@ -581,6 +581,7 @@ namespace v2rayN.ViewModels
{
ConfigHandler.InitBuiltinRouting(_config);
ConfigHandler.InitBuiltinDNS(_config);
ConfigHandler.InitBuiltinSingGeoRuleSets(_config);
_coreHandler = new CoreHandler(_config, UpdateHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => _coreHandler, typeof(CoreHandler));
@ -1389,6 +1390,7 @@ namespace v2rayN.ViewModels
if (ret == true)
{
ConfigHandler.InitBuiltinRouting(_config);
ConfigHandler.InitBuiltinSingGeoRuleSets(_config);
RefreshRoutingsMenu();
//RefreshServers();
Reload();

View file

@ -62,11 +62,15 @@ namespace v2rayN.ViewModels
[Reactive]
public string BlockIP { get; set; }
[Reactive]
public string SingGeoRuleSets { get; set; }
public ReactiveCommand<Unit, Unit> RoutingBasicImportRulesCmd { get; }
public ReactiveCommand<Unit, Unit> RoutingAdvancedAddCmd { get; }
public ReactiveCommand<Unit, Unit> RoutingAdvancedRemoveCmd { get; }
public ReactiveCommand<Unit, Unit> RoutingAdvancedSetDefaultCmd { get; }
public ReactiveCommand<Unit, Unit> RoutingAdvancedImportRulesCmd { get; }
public ReactiveCommand<Unit, Unit> RoutingImportSingGeoDefRuleSetsCmd { get; }
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public bool IsModified { get; set; }
@ -81,6 +85,7 @@ namespace v2rayN.ViewModels
SelectedSource = new();
ConfigHandler.InitBuiltinRouting(_config);
ConfigHandler.InitBuiltinSingGeoRuleSets(_config);
enableRoutingAdvanced = _config.routingBasicItem.enableRoutingAdvanced;
domainStrategy = _config.routingBasicItem.domainStrategy;
@ -88,6 +93,8 @@ namespace v2rayN.ViewModels
domainStrategy4Singbox = _config.routingBasicItem.domainStrategy4Singbox;
RefreshRoutingItems();
var geoRulesets = LazyConfig.Instance.GetSingGeoRuleSets();
if (geoRulesets != null) SingGeoRuleSets = geoRulesets.rules;
BindingLockedData();
@ -121,6 +128,11 @@ namespace v2rayN.ViewModels
RoutingAdvancedImportRules();
});
RoutingImportSingGeoDefRuleSetsCmd = ReactiveCommand.Create(() =>
{
SingGeoRuleSets = Utils.GetEmbedText(Global.SingboxGeoRuleSetsFileName);
});
SaveCmd = ReactiveCommand.Create(() =>
{
SaveRouting();
@ -165,6 +177,13 @@ namespace v2rayN.ViewModels
ConfigHandler.SaveRoutingItem(_config, _lockedItem);
}
var ruleSet = ConfigHandler.GetDefaultSingGeoRuleSet(_config);
if (ruleSet != null)
{
ruleSet.rules = SingGeoRuleSets;
ConfigHandler.SaveSingGeoRuleSet(_config, ruleSet);
}
}
#endregion locked

View file

@ -155,20 +155,20 @@
<DockPanel>
<TabControl x:Name="tabAdvanced">
<TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbRoutingTabRuleList}">
<TabItem Header="{x:Static resx:ResUI.TbRoutingTabRuleList}">
<DataGrid
x:Name="lstRoutings"
Margin="2,0"
AutoGenerateColumns="False"
BorderThickness="1"
CanUserAddRows="False"
CanUserResizeRows="False"
CanUserSortColumns="False"
EnableRowVirtualization="True"
GridLinesVisibility="All"
HeadersVisibility="Column"
IsReadOnly="True"
Style="{StaticResource DefDataGrid}">
x:Name="lstRoutings"
Margin="2,0"
AutoGenerateColumns="False"
BorderThickness="1"
CanUserAddRows="False"
CanUserResizeRows="False"
CanUserSortColumns="False"
EnableRowVirtualization="True"
GridLinesVisibility="All"
HeadersVisibility="Column"
IsReadOnly="True"
Style="{StaticResource DefDataGrid}">
<DataGrid.ContextMenu>
<ContextMenu Style="{StaticResource DefContextMenu}">
<MenuItem
@ -230,6 +230,41 @@
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem Header="{x:Static resx:ResUI.TbRoutingTabRuleSet}">
<DockPanel Margin="{StaticResource SettingItemMargin}">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock
Margin="8,0,0,0"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}">
<Hyperlink Click="linkSingGeoRuleSetDoc_Click">
<TextBlock Text="{x:Static resx:ResUI.TbSingGeoRuleSetDoc}" />
</Hyperlink>
</TextBlock>
<Button
x:Name="btnImportDefSingGeoRuleSets"
Margin="8,0,0,0"
Content="{x:Static resx:ResUI.TbSettingSingGeoImportDefRuleSets}"
Cursor="Hand"
Style="{StaticResource DefButton}" />
</StackPanel>
<Grid>
<TextBox
Name="txtSingGeoRuleSets"
Width="940"
DockPanel.Dock="Bottom"
VerticalAlignment="Stretch"
Margin="{StaticResource SettingItemMargin}"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.TbSettingsSingGeoRuleSets}"
AcceptsReturn="True"
BorderThickness="1"
Style="{StaticResource MaterialDesignOutlinedTextBox}"
TextWrapping="Wrap" HorizontalAlignment="Stretch"
VerticalScrollBarVisibility="Auto" />
</Grid>
</DockPanel>
</TabItem>
</TabControl>
<TabControl x:Name="tabBasic">
@ -331,6 +366,41 @@
</GroupBox>
</Grid>
</TabItem>
<TabItem Header="{x:Static resx:ResUI.TbRoutingTabRuleSet}">
<DockPanel Margin="{StaticResource SettingItemMargin}">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock
Margin="8,0,0,0"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}">
<Hyperlink Click="linkSingGeoRuleSetDoc_Click">
<TextBlock Text="{x:Static resx:ResUI.TbSingGeoRuleSetDoc}" />
</Hyperlink>
</TextBlock>
<Button
x:Name="btnImportDefSingGeoRuleSets2"
Margin="8,0,0,0"
Content="{x:Static resx:ResUI.TbSettingSingGeoImportDefRuleSets}"
Cursor="Hand"
Style="{StaticResource DefButton}" />
</StackPanel>
<Grid>
<TextBox
Name="txtSingGeoRuleSets2"
Width="940"
DockPanel.Dock="Bottom"
VerticalAlignment="Stretch"
Margin="{StaticResource SettingItemMargin}"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.TbSettingsSingGeoRuleSets}"
AcceptsReturn="True"
BorderThickness="1"
Style="{StaticResource MaterialDesignOutlinedTextBox}"
TextWrapping="Wrap" HorizontalAlignment="Stretch"
VerticalScrollBarVisibility="Auto" />
</Grid>
</DockPanel>
</TabItem>
</TabControl>
</DockPanel>
</DockPanel>

View file

@ -60,6 +60,8 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.DirectIP, v => v.txtDirectIP.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.BlockDomain, v => v.txtBlockDomain.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.BlockIP, v => v.txtBlockIP.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingGeoRuleSets, v => v.txtSingGeoRuleSets.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SingGeoRuleSets, v => v.txtSingGeoRuleSets2.Text).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.enableRoutingBasic, v => v.menuRoutingBasic.Visibility).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.enableRoutingAdvanced, v => v.menuRoutingAdvanced.Visibility).DisposeWith(disposables);
@ -73,6 +75,8 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedSetDefaultCmd, v => v.menuRoutingAdvancedSetDefault).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules2).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RoutingImportSingGeoDefRuleSetsCmd, v => v.btnImportDefSingGeoRuleSets).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RoutingImportSingGeoDefRuleSetsCmd, v => v.btnImportDefSingGeoRuleSets2).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
});
@ -146,5 +150,10 @@ namespace v2rayN.Views
this.Close();
}
}
private void linkSingGeoRuleSetDoc_Click(object sender, RoutedEventArgs e)
{
Utils.ProcessStart("https://sing-box.sagernet.org/configuration/rule-set/");
}
}
}

View file

@ -30,6 +30,9 @@
<ItemGroup>
<AdditionalFiles Include="app.manifest" />
<EmbeddedResource Include="Sample\singbox_geo_rulesets">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Sample\SingboxSampleOutbound" />
<EmbeddedResource Include="Sample\SingboxSampleClientConfig">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>