Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

External routing rules templates + regional presets support #5840

Merged
merged 2 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions v2rayN/ServiceLib/Enums/EPresetType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace ServiceLib.Enums
{
public enum EPresetType
{
Default = 0,
Russia = 1,
}
}
5 changes: 5 additions & 0 deletions v2rayN/ServiceLib/Global.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ public class Global
@"https://raw.githubusercontent.com/runetfreedom/russia-v2ray-rules-dat/refs/heads/release/sing-box/rule-set-{0}/{1}.srs",
};

public static readonly List<string> RoutingRulesSources = new() {
"", //Default
@"https://raw.githubusercontent.com/runetfreedom/russia-v2ray-custom-routing-list/refs/heads/main/template.json",
};

public static readonly Dictionary<string, string> UserAgentTexts = new()
{
{"chrome","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36" },
Expand Down
114 changes: 102 additions & 12 deletions v2rayN/ServiceLib/Handler/ConfigHandler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Data;
using ServiceLib.Common;
using System.Data;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;

namespace ServiceLib.Handler
Expand Down Expand Up @@ -1616,6 +1618,79 @@ public static RoutingItem GetDefaultRouting(Config config)
return item;
}

public static int InitRouting(Config config, bool blImportAdvancedRules = false)
{
if (!String.IsNullOrEmpty(config.constItem.routeRulesTemplateSourceUrl))
{
InitExternalRouting(config, blImportAdvancedRules);
}
else
{
InitBuiltinRouting(config, blImportAdvancedRules);
}

if (GetLockedRoutingItem(config) == null)
{
var item1 = new RoutingItem()
{
remarks = "locked",
url = string.Empty,
locked = true,
};
AddBatchRoutingRules(ref item1, Utils.GetEmbedText(Global.CustomRoutingFileName + "locked"));
}

return 0;
}

public static int InitExternalRouting(Config config, bool blImportAdvancedRules = false)
{
DownloadService downloadHandle = new DownloadService();
var templateContent = Task.Run(() => downloadHandle.TryDownloadString(config.constItem.routeRulesTemplateSourceUrl, false, "")).Result;
if (String.IsNullOrEmpty(templateContent))
return InitBuiltinRouting(config, blImportAdvancedRules); // fallback

var template = JsonUtils.Deserialize<RoutingTemplate>(templateContent);
if (template == null)
return InitBuiltinRouting(config, blImportAdvancedRules); // fallback

var items = AppHandler.Instance.RoutingItems();
var maxSort = items.Count;

if (blImportAdvancedRules || items.Where(t => t.remarks.StartsWith(template.version)).ToList().Count <= 0)
{
for (var i = 0; i < template.routingItems.Length; i++)
{
var item = template.routingItems[i];

if (String.IsNullOrEmpty(item.url) && String.IsNullOrEmpty(item.ruleSet))
continue;

var ruleSetsString = !String.IsNullOrEmpty(item.ruleSet)
? item.ruleSet
: Task.Run(() => downloadHandle.TryDownloadString(item.url, false, "")).Result;

if (String.IsNullOrEmpty(ruleSetsString))
continue;

item.remarks = $"{template.version}-{item.remarks}";
item.enabled = true;
item.sort = ++maxSort;
item.url = string.Empty;

AddBatchRoutingRules(ref item, ruleSetsString);

//first rule as default at first startup
if (!blImportAdvancedRules && i == 0)
{
SetDefaultRouting(config, item);
}
}
}

return 0;
}

public static int InitBuiltinRouting(Config config, bool blImportAdvancedRules = false)
{
var ver = "V3-";
Expand Down Expand Up @@ -1655,17 +1730,6 @@ public static int InitBuiltinRouting(Config config, bool blImportAdvancedRules =
SetDefaultRouting(config, item2);
}
}

if (GetLockedRoutingItem(config) == null)
{
var item1 = new RoutingItem()
{
remarks = "locked",
url = string.Empty,
locked = true,
};
AddBatchRoutingRules(ref item1, Utils.GetEmbedText(Global.CustomRoutingFileName + "locked"));
}
return 0;
}

Expand Down Expand Up @@ -1724,5 +1788,31 @@ public static int SaveDNSItems(Config config, DNSItem item)
}

#endregion DNS

#region Presets

public static bool ApplyPreset(Config config, EPresetType type)
{
switch (type)
{
case EPresetType.Default:
config.constItem.geoSourceUrl = "";
config.constItem.srsSourceUrl = "";
config.constItem.routeRulesTemplateSourceUrl = "";

return true;

case EPresetType.Russia:
config.constItem.geoSourceUrl = Global.GeoFilesSources[1];
config.constItem.srsSourceUrl = Global.SingboxRulesetSources[1];
config.constItem.routeRulesTemplateSourceUrl = Global.RoutingRulesSources[1];

return true;
}

return false;
}

#endregion
}
}
1 change: 1 addition & 0 deletions v2rayN/ServiceLib/Models/ConfigItems.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ public class ConstItem
public string subConvertUrl { get; set; } = string.Empty;
public string? geoSourceUrl { get; set; }
public string? srsSourceUrl { get; set; }
public string? routeRulesTemplateSourceUrl { get; set; }
}

[Serializable]
Expand Down
9 changes: 9 additions & 0 deletions v2rayN/ServiceLib/Models/RoutingTemplate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace ServiceLib.Models
{
[Serializable]
public class RoutingTemplate
{
public string version { get; set; }
public RoutingItem[] routingItems { get; set; }
}
}
38 changes: 38 additions & 0 deletions v2rayN/ServiceLib/Resx/ResUI.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions v2rayN/ServiceLib/Resx/ResUI.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1336,4 +1336,16 @@
<data name="UpgradeAppNotExistTip" xml:space="preserve">
<value>UpgradeApp does not exist</value>
</data>
<data name="TbSettingsRoutingRulesSource" xml:space="preserve">
<value>Routing rules source (optional)</value>
</data>
<data name="menuPresets" xml:space="preserve">
<value>Regional presets</value>
</data>
<data name="menuPresetsDefault" xml:space="preserve">
<value>Default</value>
</data>
<data name="menuPresetsRussia" xml:space="preserve">
<value>Russia</value>
</data>
</root>
35 changes: 33 additions & 2 deletions v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public class MainWindowViewModel : MyReactiveObject
public ReactiveCommand<Unit, Unit> ClearServerStatisticsCmd { get; }
public ReactiveCommand<Unit, Unit> OpenTheFileLocationCmd { get; }

//Presets
public ReactiveCommand<Unit, Unit> PresetDefaultCmd { get; }
public ReactiveCommand<Unit, Unit> PresetRussiaCmd { get; }

public ReactiveCommand<Unit, Unit> ReloadCmd { get; }

[Reactive]
Expand Down Expand Up @@ -181,14 +185,24 @@ public MainWindowViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
await Reload();
});

PresetDefaultCmd = ReactiveCommand.CreateFromTask(async () =>
{
await ApplyPreset(EPresetType.Default);
});

PresetRussiaCmd = ReactiveCommand.CreateFromTask(async () =>
{
await ApplyPreset(EPresetType.Russia);
});

#endregion WhenAnyValue && ReactiveCommand

AutoHideStartup();
}

private void Init()
{
ConfigHandler.InitBuiltinRouting(_config);
ConfigHandler.InitRouting(_config);
ConfigHandler.InitBuiltinDNS(_config);
CoreHandler.Instance.Init(_config, UpdateHandler);
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
Expand Down Expand Up @@ -431,7 +445,7 @@ private async Task RoutingSettingAsync()
var ret = await _updateView?.Invoke(EViewAction.RoutingSettingWindow, null);
if (ret == true)
{
ConfigHandler.InitBuiltinRouting(_config);
ConfigHandler.InitRouting(_config);
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
Reload();
}
Expand Down Expand Up @@ -542,5 +556,22 @@ private void AutoHideStartup()
}

#endregion core job

#region Presets

public async Task ApplyPreset(EPresetType type)
{
ConfigHandler.ApplyPreset(_config, type);

await new UpdateService().UpdateGeoFileAll(_config, UpdateHandler);

ConfigHandler.InitRouting(_config);
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();

ConfigHandler.SaveConfig(_config, false);
Reload();
}

#endregion
}
}
3 changes: 3 additions & 0 deletions v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class OptionSettingViewModel : MyReactiveObject
[Reactive] public int MainGirdOrientation { get; set; }
[Reactive] public string GeoFileSourceUrl { get; set; }
[Reactive] public string SrsFileSourceUrl { get; set; }
[Reactive] public string RoutingRulesSourceUrl { get; set; }

#endregion UI

Expand Down Expand Up @@ -168,6 +169,7 @@ public OptionSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView
MainGirdOrientation = (int)_config.uiItem.mainGirdOrientation;
GeoFileSourceUrl = _config.constItem.geoSourceUrl;
SrsFileSourceUrl = _config.constItem.srsSourceUrl;
RoutingRulesSourceUrl = _config.constItem.routeRulesTemplateSourceUrl;

#endregion UI

Expand Down Expand Up @@ -322,6 +324,7 @@ private async Task SaveSettingAsync()
_config.uiItem.mainGirdOrientation = (EGirdOrientation)MainGirdOrientation;
_config.constItem.geoSourceUrl = GeoFileSourceUrl;
_config.constItem.srsSourceUrl = SrsFileSourceUrl;
_config.constItem.routeRulesTemplateSourceUrl = RoutingRulesSourceUrl;

//systemProxy
_config.systemProxyItem.systemProxyExceptions = systemProxyExceptions;
Expand Down
4 changes: 2 additions & 2 deletions v2rayN/ServiceLib/ViewModels/RoutingSettingViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public RoutingSettingViewModel(Func<EViewAction, object?, Task<bool>>? updateVie
_updateView = updateView;
SelectedSource = new();

ConfigHandler.InitBuiltinRouting(_config);
ConfigHandler.InitRouting(_config);

enableRoutingAdvanced = _config.routingBasicItem.enableRoutingAdvanced;
domainStrategy = _config.routingBasicItem.domainStrategy;
Expand Down Expand Up @@ -286,7 +286,7 @@ public async Task RoutingAdvancedSetDefault()

private async Task RoutingAdvancedImportRules()
{
if (ConfigHandler.InitBuiltinRouting(_config, true) == 0)
if (ConfigHandler.InitRouting(_config, true) == 0)
{
RefreshRoutingItems();
IsModified = true;
Expand Down
4 changes: 4 additions & 0 deletions v2rayN/v2rayN.Desktop/Views/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@
<MenuItem x:Name="menuRoutingSetting" Header="{x:Static resx:ResUI.menuRoutingSetting}" />
<MenuItem x:Name="menuDNSSetting" Header="{x:Static resx:ResUI.menuDNSSetting}" />
<MenuItem x:Name="menuGlobalHotkeySetting" Header="{x:Static resx:ResUI.menuGlobalHotkeySetting}" />
<MenuItem Header="{x:Static resx:ResUI.menuPresets}">
<MenuItem x:Name="menuPresetsDefault" Header="{x:Static resx:ResUI.menuPresetsDefault}" />
<MenuItem x:Name="menuPresetsRussia" Header="{x:Static resx:ResUI.menuPresetsRussia}" />
</MenuItem>
<Separator />
<MenuItem x:Name="menuRebootAsAdmin" Header="{x:Static resx:ResUI.menuRebootAsAdmin}" />
<MenuItem x:Name="menuSettingsSetUWP" Header="{x:Static resx:ResUI.TbSettingsSetUWP}" />
Expand Down
2 changes: 2 additions & 0 deletions v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ public MainWindow()
this.BindCommand(ViewModel, vm => vm.RebootAsAdminCmd, v => v.menuRebootAsAdmin).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ClearServerStatisticsCmd, v => v.menuClearServerStatistics).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.OpenTheFileLocationCmd, v => v.menuOpenTheFileLocation).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.PresetDefaultCmd, v => v.menuPresetsDefault).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.PresetRussiaCmd, v => v.menuPresetsRussia).DisposeWith(disposables);

this.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).DisposeWith(disposables);
Expand Down
Loading