Compare commits

...

3 commits

Author SHA1 Message Date
DHR60
e0bf2fdea2
Merge 4301415b4c into 22f0d04f01 2025-10-04 00:52:26 +03:00
2dust
22f0d04f01 Fix
Some checks are pending
release Linux / build (Release) (push) Waiting to run
release macOS / build (Release) (push) Waiting to run
release Windows desktop (Avalonia UI) / build (Release) (push) Waiting to run
release Windows / build (Release) (push) Waiting to run
https://github.com/2dust/v2rayN/issues/8060
2025-10-03 14:13:03 +08:00
DHR60
4301415b4c Add rule type selection to routing rules 2025-09-23 17:59:18 +08:00
17 changed files with 151 additions and 46 deletions

View file

@ -85,13 +85,19 @@ public class Utils
/// Base64 Encode
/// </summary>
/// <param name="plainText"></param>
/// <param name="removePadding"></param>
/// <returns></returns>
public static string Base64Encode(string plainText)
public static string Base64Encode(string plainText, bool removePadding = false)
{
try
{
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(plainTextBytes);
var base64 = Convert.ToBase64String(plainTextBytes);
if (removePadding)
{
base64 = base64.TrimEnd('=');
}
return base64;
}
catch (Exception ex)
{
@ -112,7 +118,7 @@ public class Utils
{
if (plainText.IsNullOrEmpty())
{
return "";
return string.Empty;
}
plainText = plainText.Trim()
@ -947,7 +953,7 @@ public class Utils
if (SetUnixFileMode(fileName))
{
Logging.SaveLog($"Successfully set the file execution permission, {fileName}");
return "";
return string.Empty;
}
if (fileName.Contains(' '))

View file

@ -87,6 +87,8 @@ public class Global
public const string SingboxFinalResolverTag = "final_resolver";
public const string SingboxHostsDNSTag = "hosts_dns";
public const string SingboxFakeDNSTag = "fake_dns";
public const string RoutingRuleType = "Routing";
public const string DNSRuleType = "DNS";
public static readonly List<string> IEProxyProtocols =
[
@ -479,6 +481,12 @@ public class Global
"tcp,udp"
];
public static readonly List<string> RuleTypes =
[
RoutingRuleType,
DNSRuleType
];
public static readonly List<string> destOverrideProtocols =
[
"http",

View file

@ -27,7 +27,7 @@ public class FmtHandler
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
return "";
return string.Empty;
}
}

View file

@ -42,7 +42,7 @@ public class ShadowsocksFmt : BaseFmt
// item.port);
//url = Utile.Base64Encode(url);
//new Sip002
var pw = Utils.Base64Encode($"{item.Security}:{item.Id}");
var pw = Utils.Base64Encode($"{item.Security}:{item.Id}", true);
return ToUri(EConfigType.Shadowsocks, item.Address, item.Port, pw, null, remark);
}

View file

@ -33,7 +33,7 @@ public class SocksFmt : BaseFmt
remark = "#" + Utils.UrlEncode(item.Remarks);
}
//new
var pw = Utils.Base64Encode($"{item.Security}:{item.Id}");
var pw = Utils.Base64Encode($"{item.Security}:{item.Id}", true);
return ToUri(EConfigType.SOCKS, item.Address, item.Port, pw, null, remark);
}

View file

@ -8,7 +8,6 @@ public sealed class AppManager
private Config _config;
private int? _statePort;
private int? _statePort2;
private WindowsJob? _processJob;
public static AppManager Instance => _instance.Value;
public Config Config => _config;
@ -136,21 +135,6 @@ public sealed class AppManager
return localPort + (int)protocol;
}
public void AddProcess(nint processHandle)
{
if (Utils.IsWindows())
{
_processJob ??= new();
try
{
_processJob?.AddProcess(processHandle);
}
catch
{
}
}
}
#endregion Config
#region SqliteHelper

View file

@ -8,6 +8,7 @@ public class CoreManager
private static readonly Lazy<CoreManager> _instance = new(() => new());
public static CoreManager Instance => _instance.Value;
private Config _config;
private WindowsJob? _processJob;
private ProcessService? _processService;
private ProcessService? _processPreService;
private bool _linuxSudo = false;
@ -264,14 +265,28 @@ public class CoreManager
await procService.StartAsync();
await Task.Delay(100);
AppManager.Instance.AddProcess(procService.Handle);
if (procService is null or { HasExited: true })
{
throw new Exception(ResUI.FailedToRunCore);
}
AddProcessJob(procService.Handle);
return procService;
}
private void AddProcessJob(nint processHandle)
{
if (Utils.IsWindows())
{
_processJob ??= new();
try
{
_processJob?.AddProcess(processHandle);
}
catch { }
}
}
#endregion Process
}

View file

@ -15,4 +15,5 @@ public class RulesItem
public List<string>? Process { get; set; }
public bool Enabled { get; set; } = true;
public string? Remarks { get; set; }
public List<string>? RuleTypes { get; set; }
}

View file

@ -253,6 +253,11 @@ public partial class CoreConfigSingboxService
continue;
}
if ((item.RuleTypes?.Count ?? 0) > 0 && !item.RuleTypes.Contains(Global.DNSRuleType))
{
continue;
}
var rule = new Rule4Sbox();
var validDomains = item.Domain.Count(it => ParseV2Domain(it, rule));
if (validDomains <= 0)

View file

@ -136,16 +136,24 @@ public partial class CoreConfigSingboxService
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
foreach (var item1 in rules ?? [])
{
if (item1.Enabled)
if (!item1.Enabled)
{
continue;
}
if ((item1.RuleTypes?.Count ?? 0) > 0 && !item1.RuleTypes.Contains(Global.RoutingRuleType))
{
continue;
}
await GenRoutingUserRule(item1, singboxConfig);
if (item1.Ip != null && item1.Ip.Count > 0)
if (item1.Ip?.Count > 0)
{
ipRules.Add(item1);
}
}
}
}
if (_config.RoutingBasicItem.DomainStrategy == Global.IPIfNonMatch)
{
singboxConfig.route.rules.Add(resolveRule);

View file

@ -142,6 +142,11 @@ public partial class CoreConfigV2rayService
continue;
}
if ((item.RuleTypes?.Count ?? 0) > 0 && !item.RuleTypes.Contains(Global.DNSRuleType))
{
continue;
}
foreach (var domain in item.Domain)
{
if (domain.StartsWith('#'))

View file

@ -20,15 +20,22 @@ public partial class CoreConfigV2rayService
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
foreach (var item in rules)
{
if (item.Enabled)
if (!item.Enabled)
{
continue;
}
if ((item.RuleTypes?.Count ?? 0) > 0 && !item.RuleTypes.Contains(Global.RoutingRuleType))
{
continue;
}
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
await GenRoutingUserRule(item2, v2rayConfig);
}
}
}
}
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);

View file

@ -21,6 +21,8 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject
[Reactive]
public string Process { get; set; }
public IList<string> Types { get; set; }
[Reactive]
public bool AutoSort { get; set; }
@ -51,6 +53,11 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject
Domain = Utils.List2String(SelectedSource.Domain, true);
IP = Utils.List2String(SelectedSource.Ip, true);
Process = Utils.List2String(SelectedSource.Process, true);
Types = SelectedSource.RuleTypes?.ToList();
if (Types == null || Types.Count == 0)
{
Types = Global.RuleTypes;
}
}
private async Task SaveRulesAsync()
@ -73,6 +80,7 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject
}
SelectedSource.Protocol = ProtocolItems?.ToList();
SelectedSource.InboundTag = InboundTagItems?.ToList();
SelectedSource.RuleTypes = Types?.ToList();
var hasRule = SelectedSource.Domain?.Count > 0
|| SelectedSource.Ip?.Count > 0

View file

@ -33,13 +33,25 @@
Width="300"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<ToggleSwitch
x:Name="togEnabled"
<StackPanel
Grid.Row="0"
Grid.Column="2"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Horizontal">
<ToggleSwitch
x:Name="togEnabled"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center" />
<ListBox
x:Name="clbRuleTypes"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
SelectionMode="Multiple,Toggle"
Theme="{DynamicResource CardCheckGroupListBox}" />
</StackPanel>
<TextBlock
Grid.Row="1"
@ -58,17 +70,15 @@
Grid.Row="1"
Grid.Column="2"
Margin="{StaticResource Margin4}"
Orientation="Horizontal"
HorizontalAlignment="Left"
VerticalAlignment="Center">
VerticalAlignment="Center"
Orientation="Horizontal">
<Button
x:Name="btnSelectProfile"
Margin="0,0,8,0"
Content="{x:Static resx:ResUI.TbSelectProfile}"
Click="BtnSelectProfile_Click" />
<TextBlock
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbRuleOutboundTagTip}" />
Click="BtnSelectProfile_Click"
Content="{x:Static resx:ResUI.TbSelectProfile}" />
<TextBlock VerticalAlignment="Center" Text="{x:Static resx:ResUI.TbRuleOutboundTagTip}" />
</StackPanel>
<TextBlock

View file

@ -29,6 +29,16 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
clbInboundTag.ItemsSource = Global.InboundTags;
cmbNetwork.ItemsSource = Global.RuleNetworks;
clbRuleTypes.SelectionChanged += ClbRuleTypes_SelectionChanged;
clbRuleTypes.ItemsSource = Global.RuleTypes;
if (ViewModel.Types != null)
{
foreach (var it in ViewModel.Types)
{
clbRuleTypes.SelectedItems.Add(it);
}
}
if (!rulesItem.Id.IsNullOrEmpty())
{
rulesItem.Protocol?.ForEach(it =>
@ -108,4 +118,12 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
}
}
}
private void ClbRuleTypes_SelectionChanged(object? sender, SelectionChangedEventArgs e)
{
if (ViewModel != null)
{
ViewModel.Types = clbRuleTypes.SelectedItems.Cast<string>().ToList();
}
}
}

View file

@ -48,13 +48,25 @@
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
Style="{StaticResource DefTextBox}" />
<ToggleButton
x:Name="togEnabled"
<StackPanel
Grid.Row="0"
Grid.Column="2"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Horizontal">
<ToggleButton
x:Name="togEnabled"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center" />
<ListBox
x:Name="clbRuleTypes"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFilterChipPrimaryListBox}" />
</StackPanel>
<TextBlock
Grid.Row="1"

View file

@ -22,6 +22,16 @@ public partial class RoutingRuleDetailsWindow
clbInboundTag.ItemsSource = Global.InboundTags;
cmbNetwork.ItemsSource = Global.RuleNetworks;
clbRuleTypes.SelectionChanged += ClbRuleTypes_SelectionChanged;
clbRuleTypes.ItemsSource = Global.RuleTypes;
if (ViewModel.Types != null)
{
foreach (var it in ViewModel.Types)
{
clbRuleTypes.SelectedItems.Add(it);
}
}
if (!rulesItem.Id.IsNullOrEmpty())
{
rulesItem.Protocol?.ForEach(it =>
@ -101,4 +111,12 @@ public partial class RoutingRuleDetailsWindow
}
}
}
private void ClbRuleTypes_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (ViewModel != null)
{
ViewModel.Types = clbRuleTypes.SelectedItems.Cast<string>().ToList();
}
}
}