mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-13 20:09:12 +00:00
Compare commits
3 commits
90dedd8a31
...
e0bf2fdea2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e0bf2fdea2 | ||
![]() |
22f0d04f01 | ||
![]() |
4301415b4c |
17 changed files with 151 additions and 46 deletions
|
@ -85,13 +85,19 @@ public class Utils
|
||||||
/// Base64 Encode
|
/// Base64 Encode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plainText"></param>
|
/// <param name="plainText"></param>
|
||||||
|
/// <param name="removePadding"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string Base64Encode(string plainText)
|
public static string Base64Encode(string plainText, bool removePadding = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
|
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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -112,7 +118,7 @@ public class Utils
|
||||||
{
|
{
|
||||||
if (plainText.IsNullOrEmpty())
|
if (plainText.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
return "";
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
plainText = plainText.Trim()
|
plainText = plainText.Trim()
|
||||||
|
@ -947,7 +953,7 @@ public class Utils
|
||||||
if (SetUnixFileMode(fileName))
|
if (SetUnixFileMode(fileName))
|
||||||
{
|
{
|
||||||
Logging.SaveLog($"Successfully set the file execution permission, {fileName}");
|
Logging.SaveLog($"Successfully set the file execution permission, {fileName}");
|
||||||
return "";
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileName.Contains(' '))
|
if (fileName.Contains(' '))
|
||||||
|
|
|
@ -87,6 +87,8 @@ public class Global
|
||||||
public const string SingboxFinalResolverTag = "final_resolver";
|
public const string SingboxFinalResolverTag = "final_resolver";
|
||||||
public const string SingboxHostsDNSTag = "hosts_dns";
|
public const string SingboxHostsDNSTag = "hosts_dns";
|
||||||
public const string SingboxFakeDNSTag = "fake_dns";
|
public const string SingboxFakeDNSTag = "fake_dns";
|
||||||
|
public const string RoutingRuleType = "Routing";
|
||||||
|
public const string DNSRuleType = "DNS";
|
||||||
|
|
||||||
public static readonly List<string> IEProxyProtocols =
|
public static readonly List<string> IEProxyProtocols =
|
||||||
[
|
[
|
||||||
|
@ -479,6 +481,12 @@ public class Global
|
||||||
"tcp,udp"
|
"tcp,udp"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public static readonly List<string> RuleTypes =
|
||||||
|
[
|
||||||
|
RoutingRuleType,
|
||||||
|
DNSRuleType
|
||||||
|
];
|
||||||
|
|
||||||
public static readonly List<string> destOverrideProtocols =
|
public static readonly List<string> destOverrideProtocols =
|
||||||
[
|
[
|
||||||
"http",
|
"http",
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class FmtHandler
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(_tag, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return "";
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class ShadowsocksFmt : BaseFmt
|
||||||
// item.port);
|
// item.port);
|
||||||
//url = Utile.Base64Encode(url);
|
//url = Utile.Base64Encode(url);
|
||||||
//new Sip002
|
//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);
|
return ToUri(EConfigType.Shadowsocks, item.Address, item.Port, pw, null, remark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class SocksFmt : BaseFmt
|
||||||
remark = "#" + Utils.UrlEncode(item.Remarks);
|
remark = "#" + Utils.UrlEncode(item.Remarks);
|
||||||
}
|
}
|
||||||
//new
|
//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);
|
return ToUri(EConfigType.SOCKS, item.Address, item.Port, pw, null, remark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ public sealed class AppManager
|
||||||
private Config _config;
|
private Config _config;
|
||||||
private int? _statePort;
|
private int? _statePort;
|
||||||
private int? _statePort2;
|
private int? _statePort2;
|
||||||
private WindowsJob? _processJob;
|
|
||||||
public static AppManager Instance => _instance.Value;
|
public static AppManager Instance => _instance.Value;
|
||||||
public Config Config => _config;
|
public Config Config => _config;
|
||||||
|
|
||||||
|
@ -136,21 +135,6 @@ public sealed class AppManager
|
||||||
return localPort + (int)protocol;
|
return localPort + (int)protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddProcess(nint processHandle)
|
|
||||||
{
|
|
||||||
if (Utils.IsWindows())
|
|
||||||
{
|
|
||||||
_processJob ??= new();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_processJob?.AddProcess(processHandle);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Config
|
#endregion Config
|
||||||
|
|
||||||
#region SqliteHelper
|
#region SqliteHelper
|
||||||
|
|
|
@ -8,6 +8,7 @@ public class CoreManager
|
||||||
private static readonly Lazy<CoreManager> _instance = new(() => new());
|
private static readonly Lazy<CoreManager> _instance = new(() => new());
|
||||||
public static CoreManager Instance => _instance.Value;
|
public static CoreManager Instance => _instance.Value;
|
||||||
private Config _config;
|
private Config _config;
|
||||||
|
private WindowsJob? _processJob;
|
||||||
private ProcessService? _processService;
|
private ProcessService? _processService;
|
||||||
private ProcessService? _processPreService;
|
private ProcessService? _processPreService;
|
||||||
private bool _linuxSudo = false;
|
private bool _linuxSudo = false;
|
||||||
|
@ -264,14 +265,28 @@ public class CoreManager
|
||||||
await procService.StartAsync();
|
await procService.StartAsync();
|
||||||
|
|
||||||
await Task.Delay(100);
|
await Task.Delay(100);
|
||||||
AppManager.Instance.AddProcess(procService.Handle);
|
|
||||||
if (procService is null or { HasExited: true })
|
if (procService is null or { HasExited: true })
|
||||||
{
|
{
|
||||||
throw new Exception(ResUI.FailedToRunCore);
|
throw new Exception(ResUI.FailedToRunCore);
|
||||||
}
|
}
|
||||||
|
AddProcessJob(procService.Handle);
|
||||||
|
|
||||||
return procService;
|
return procService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddProcessJob(nint processHandle)
|
||||||
|
{
|
||||||
|
if (Utils.IsWindows())
|
||||||
|
{
|
||||||
|
_processJob ??= new();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_processJob?.AddProcess(processHandle);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Process
|
#endregion Process
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,4 +15,5 @@ public class RulesItem
|
||||||
public List<string>? Process { get; set; }
|
public List<string>? Process { get; set; }
|
||||||
public bool Enabled { get; set; } = true;
|
public bool Enabled { get; set; } = true;
|
||||||
public string? Remarks { get; set; }
|
public string? Remarks { get; set; }
|
||||||
|
public List<string>? RuleTypes { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,6 +253,11 @@ public partial class CoreConfigSingboxService
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((item.RuleTypes?.Count ?? 0) > 0 && !item.RuleTypes.Contains(Global.DNSRuleType))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var rule = new Rule4Sbox();
|
var rule = new Rule4Sbox();
|
||||||
var validDomains = item.Domain.Count(it => ParseV2Domain(it, rule));
|
var validDomains = item.Domain.Count(it => ParseV2Domain(it, rule));
|
||||||
if (validDomains <= 0)
|
if (validDomains <= 0)
|
||||||
|
|
|
@ -136,13 +136,21 @@ public partial class CoreConfigSingboxService
|
||||||
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
|
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
|
||||||
foreach (var item1 in rules ?? [])
|
foreach (var item1 in rules ?? [])
|
||||||
{
|
{
|
||||||
if (item1.Enabled)
|
if (!item1.Enabled)
|
||||||
{
|
{
|
||||||
await GenRoutingUserRule(item1, singboxConfig);
|
continue;
|
||||||
if (item1.Ip != null && item1.Ip.Count > 0)
|
}
|
||||||
{
|
|
||||||
ipRules.Add(item1);
|
if ((item1.RuleTypes?.Count ?? 0) > 0 && !item1.RuleTypes.Contains(Global.RoutingRuleType))
|
||||||
}
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await GenRoutingUserRule(item1, singboxConfig);
|
||||||
|
|
||||||
|
if (item1.Ip?.Count > 0)
|
||||||
|
{
|
||||||
|
ipRules.Add(item1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,11 @@ public partial class CoreConfigV2rayService
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((item.RuleTypes?.Count ?? 0) > 0 && !item.RuleTypes.Contains(Global.DNSRuleType))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var domain in item.Domain)
|
foreach (var domain in item.Domain)
|
||||||
{
|
{
|
||||||
if (domain.StartsWith('#'))
|
if (domain.StartsWith('#'))
|
||||||
|
|
|
@ -20,11 +20,18 @@ public partial class CoreConfigV2rayService
|
||||||
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)
|
||||||
{
|
{
|
||||||
if (item.Enabled)
|
if (!item.Enabled)
|
||||||
{
|
{
|
||||||
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
|
continue;
|
||||||
await GenRoutingUserRule(item2, v2rayConfig);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((item.RuleTypes?.Count ?? 0) > 0 && !item.RuleTypes.Contains(Global.RoutingRuleType))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
|
||||||
|
await GenRoutingUserRule(item2, v2rayConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public string Process { get; set; }
|
public string Process { get; set; }
|
||||||
|
|
||||||
|
public IList<string> Types { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public bool AutoSort { get; set; }
|
public bool AutoSort { get; set; }
|
||||||
|
|
||||||
|
@ -51,6 +53,11 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject
|
||||||
Domain = Utils.List2String(SelectedSource.Domain, true);
|
Domain = Utils.List2String(SelectedSource.Domain, true);
|
||||||
IP = Utils.List2String(SelectedSource.Ip, true);
|
IP = Utils.List2String(SelectedSource.Ip, true);
|
||||||
Process = Utils.List2String(SelectedSource.Process, true);
|
Process = Utils.List2String(SelectedSource.Process, true);
|
||||||
|
Types = SelectedSource.RuleTypes?.ToList();
|
||||||
|
if (Types == null || Types.Count == 0)
|
||||||
|
{
|
||||||
|
Types = Global.RuleTypes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveRulesAsync()
|
private async Task SaveRulesAsync()
|
||||||
|
@ -73,6 +80,7 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject
|
||||||
}
|
}
|
||||||
SelectedSource.Protocol = ProtocolItems?.ToList();
|
SelectedSource.Protocol = ProtocolItems?.ToList();
|
||||||
SelectedSource.InboundTag = InboundTagItems?.ToList();
|
SelectedSource.InboundTag = InboundTagItems?.ToList();
|
||||||
|
SelectedSource.RuleTypes = Types?.ToList();
|
||||||
|
|
||||||
var hasRule = SelectedSource.Domain?.Count > 0
|
var hasRule = SelectedSource.Domain?.Count > 0
|
||||||
|| SelectedSource.Ip?.Count > 0
|
|| SelectedSource.Ip?.Count > 0
|
||||||
|
|
|
@ -33,13 +33,25 @@
|
||||||
Width="300"
|
Width="300"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
<ToggleSwitch
|
<StackPanel
|
||||||
x:Name="togEnabled"
|
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Center" />
|
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
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
|
@ -58,17 +70,15 @@
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Orientation="Horizontal"
|
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Center">
|
VerticalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
<Button
|
<Button
|
||||||
x:Name="btnSelectProfile"
|
x:Name="btnSelectProfile"
|
||||||
Margin="0,0,8,0"
|
Margin="0,0,8,0"
|
||||||
Content="{x:Static resx:ResUI.TbSelectProfile}"
|
Click="BtnSelectProfile_Click"
|
||||||
Click="BtnSelectProfile_Click" />
|
Content="{x:Static resx:ResUI.TbSelectProfile}" />
|
||||||
<TextBlock
|
<TextBlock VerticalAlignment="Center" Text="{x:Static resx:ResUI.TbRuleOutboundTagTip}" />
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{x:Static resx:ResUI.TbRuleOutboundTagTip}" />
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
|
|
|
@ -29,6 +29,16 @@ public partial class RoutingRuleDetailsWindow : WindowBase<RoutingRuleDetailsVie
|
||||||
clbInboundTag.ItemsSource = Global.InboundTags;
|
clbInboundTag.ItemsSource = Global.InboundTags;
|
||||||
cmbNetwork.ItemsSource = Global.RuleNetworks;
|
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())
|
if (!rulesItem.Id.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
rulesItem.Protocol?.ForEach(it =>
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,13 +48,25 @@
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
<ToggleButton
|
<StackPanel
|
||||||
x:Name="togEnabled"
|
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Center" />
|
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
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
|
|
|
@ -22,6 +22,16 @@ public partial class RoutingRuleDetailsWindow
|
||||||
clbInboundTag.ItemsSource = Global.InboundTags;
|
clbInboundTag.ItemsSource = Global.InboundTags;
|
||||||
cmbNetwork.ItemsSource = Global.RuleNetworks;
|
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())
|
if (!rulesItem.Id.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
rulesItem.Protocol?.ForEach(it =>
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue