mirror of
https://github.com/2dust/v2rayN.git
synced 2025-11-29 11:12:54 +00:00
Compare commits
No commits in common. "ad74b1584d3814e3e51adc52c3b82ff39da64b91" and "20ce35bc30aebd9bd6e28e75ab00833d5d45f69a" have entirely different histories.
ad74b1584d
...
20ce35bc30
13 changed files with 82 additions and 73 deletions
4
.github/workflows/build-linux.yml
vendored
4
.github/workflows/build-linux.yml
vendored
|
|
@ -31,7 +31,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6.0.0
|
uses: actions/checkout@v5.0.1
|
||||||
with:
|
with:
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
fetch-depth: '0'
|
fetch-depth: '0'
|
||||||
|
|
@ -110,7 +110,7 @@ jobs:
|
||||||
dnf -y install sudo git rpm-build rpmdevtools dnf-plugins-core rsync findutils tar gzip unzip which
|
dnf -y install sudo git rpm-build rpmdevtools dnf-plugins-core rsync findutils tar gzip unzip which
|
||||||
|
|
||||||
- name: Checkout repo (for scripts)
|
- name: Checkout repo (for scripts)
|
||||||
uses: actions/checkout@v6.0.0
|
uses: actions/checkout@v5.0.1
|
||||||
with:
|
with:
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
fetch-depth: '0'
|
fetch-depth: '0'
|
||||||
|
|
|
||||||
2
.github/workflows/build-osx.yml
vendored
2
.github/workflows/build-osx.yml
vendored
|
|
@ -26,7 +26,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6.0.0
|
uses: actions/checkout@v5.0.1
|
||||||
with:
|
with:
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
fetch-depth: '0'
|
fetch-depth: '0'
|
||||||
|
|
|
||||||
2
.github/workflows/build-windows-desktop.yml
vendored
2
.github/workflows/build-windows-desktop.yml
vendored
|
|
@ -26,7 +26,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6.0.0
|
uses: actions/checkout@v5.0.1
|
||||||
with:
|
with:
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
fetch-depth: '0'
|
fetch-depth: '0'
|
||||||
|
|
|
||||||
2
.github/workflows/build-windows.yml
vendored
2
.github/workflows/build-windows.yml
vendored
|
|
@ -27,7 +27,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6.0.0
|
uses: actions/checkout@v5.0.1
|
||||||
|
|
||||||
- name: Setup
|
- name: Setup
|
||||||
uses: actions/setup-dotnet@v5.0.0
|
uses: actions/setup-dotnet@v5.0.0
|
||||||
|
|
|
||||||
|
|
@ -73,11 +73,13 @@ public class ShadowsocksFmt : BaseFmt
|
||||||
const string beginMarker = "-----BEGIN CERTIFICATE-----\n";
|
const string beginMarker = "-----BEGIN CERTIFICATE-----\n";
|
||||||
const string endMarker = "\n-----END CERTIFICATE-----";
|
const string endMarker = "\n-----END CERTIFICATE-----";
|
||||||
|
|
||||||
var base64Content = cert.Replace(beginMarker, "").Replace(endMarker, "").Trim();
|
var base64Start = beginMarker.Length;
|
||||||
|
var endIndex = cert.IndexOf(endMarker, base64Start, StringComparison.Ordinal);
|
||||||
|
var base64Content = cert.Substring(base64Start, endIndex - base64Start);
|
||||||
|
|
||||||
// https://github.com/shadowsocks/v2ray-plugin/blob/e9af1cdd2549d528deb20a4ab8d61c5fbe51f306/args.go#L172
|
// https://github.com/shadowsocks/v2ray-plugin/blob/e9af1cdd2549d528deb20a4ab8d61c5fbe51f306/args.go#L172
|
||||||
// Equal signs and commas [and backslashes] must be escaped with a backslash.
|
// Equal signs and commas [and backslashes] must be escaped with a backslash.
|
||||||
base64Content = base64Content.Replace("=", "\\=");
|
base64Content = base64Content.Replace("\\", "\\\\").Replace("=", "\\=").Replace(",", "\\,");
|
||||||
|
|
||||||
pluginArgs += $"certRaw={base64Content};";
|
pluginArgs += $"certRaw={base64Content};";
|
||||||
}
|
}
|
||||||
|
|
@ -249,7 +251,7 @@ public class ShadowsocksFmt : BaseFmt
|
||||||
{
|
{
|
||||||
var certBase64 = certRaw.Replace("certRaw=", "");
|
var certBase64 = certRaw.Replace("certRaw=", "");
|
||||||
|
|
||||||
certBase64 = certBase64.Replace("\\=", "=");
|
certBase64 = certBase64.Replace("\\=", "=").Replace("\\,", ",").Replace("\\\\", "\\");
|
||||||
|
|
||||||
const string beginMarker = "-----BEGIN CERTIFICATE-----\n";
|
const string beginMarker = "-----BEGIN CERTIFICATE-----\n";
|
||||||
const string endMarker = "\n-----END CERTIFICATE-----";
|
const string endMarker = "\n-----END CERTIFICATE-----";
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,6 @@ public class ActionPrecheckManager(Config config)
|
||||||
|
|
||||||
private readonly Config _config = config;
|
private readonly Config _config = config;
|
||||||
|
|
||||||
// sing-box supported transports for different protocol types
|
|
||||||
private static readonly HashSet<string> SingboxUnsupportedTransports = [nameof(ETransport.kcp), nameof(ETransport.xhttp)];
|
|
||||||
private static readonly HashSet<EConfigType> SingboxTransportSupportedProtocols =
|
|
||||||
[EConfigType.VMess, EConfigType.VLESS, EConfigType.Trojan, EConfigType.Shadowsocks];
|
|
||||||
private static readonly HashSet<string> SingboxShadowsocksAllowedTransports =
|
|
||||||
[nameof(ETransport.tcp), nameof(ETransport.ws), nameof(ETransport.quic)];
|
|
||||||
|
|
||||||
public async Task<List<string>> Check(string? indexId)
|
public async Task<List<string>> Check(string? indexId)
|
||||||
{
|
{
|
||||||
if (indexId.IsNullOrEmpty())
|
if (indexId.IsNullOrEmpty())
|
||||||
|
|
@ -181,16 +174,26 @@ public class ActionPrecheckManager(Config config)
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
var net = item.GetNetwork();
|
var net = item.GetNetwork() ?? item.Network;
|
||||||
|
|
||||||
if (coreType == ECoreType.sing_box)
|
if (coreType == ECoreType.sing_box)
|
||||||
{
|
{
|
||||||
var transportError = ValidateSingboxTransport(item.ConfigType, net);
|
// sing-box does not support xhttp / kcp
|
||||||
if (transportError != null)
|
// sing-box does not support transports like ws/http/httpupgrade/etc. when the node is not vmess/trojan/vless
|
||||||
|
if (net is nameof(ETransport.kcp) or nameof(ETransport.xhttp))
|
||||||
{
|
{
|
||||||
errors.Add(transportError);
|
errors.Add(string.Format(ResUI.CoreNotSupportNetwork, nameof(ECoreType.sing_box), net));
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.ConfigType is not (EConfigType.VMess or EConfigType.VLESS or EConfigType.Trojan))
|
||||||
|
{
|
||||||
|
if (net is nameof(ETransport.ws) or nameof(ETransport.http) or nameof(ETransport.h2) or nameof(ETransport.quic) or nameof(ETransport.httpupgrade))
|
||||||
|
{
|
||||||
|
errors.Add(string.Format(ResUI.CoreNotSupportProtocolTransport, nameof(ECoreType.sing_box), item.ConfigType.ToString(), net));
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (coreType is ECoreType.Xray)
|
else if (coreType is ECoreType.Xray)
|
||||||
{
|
{
|
||||||
|
|
@ -206,31 +209,6 @@ public class ActionPrecheckManager(Config config)
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string? ValidateSingboxTransport(EConfigType configType, string net)
|
|
||||||
{
|
|
||||||
// sing-box does not support xhttp / kcp transports
|
|
||||||
if (SingboxUnsupportedTransports.Contains(net))
|
|
||||||
{
|
|
||||||
return string.Format(ResUI.CoreNotSupportNetwork, nameof(ECoreType.sing_box), net);
|
|
||||||
}
|
|
||||||
|
|
||||||
// sing-box does not support non-tcp transports for protocols other than vmess/trojan/vless/shadowsocks
|
|
||||||
if (!SingboxTransportSupportedProtocols.Contains(configType) && net != nameof(ETransport.tcp))
|
|
||||||
{
|
|
||||||
return string.Format(ResUI.CoreNotSupportProtocolTransport,
|
|
||||||
nameof(ECoreType.sing_box), configType.ToString(), net);
|
|
||||||
}
|
|
||||||
|
|
||||||
// sing-box shadowsocks only supports tcp/ws/quic transports
|
|
||||||
if (configType == EConfigType.Shadowsocks && !SingboxShadowsocksAllowedTransports.Contains(net))
|
|
||||||
{
|
|
||||||
return string.Format(ResUI.CoreNotSupportProtocolTransport,
|
|
||||||
nameof(ECoreType.sing_box), configType.ToString(), net);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<List<string>> ValidateRelatedNodesExistAndValid(ProfileItem? item)
|
private async Task<List<string>> ValidateRelatedNodesExistAndValid(ProfileItem? item)
|
||||||
{
|
{
|
||||||
var errors = new List<string>();
|
var errors = new List<string>();
|
||||||
|
|
|
||||||
|
|
@ -62,11 +62,13 @@ public partial class CoreConfigSingboxService
|
||||||
const string beginMarker = "-----BEGIN CERTIFICATE-----\n";
|
const string beginMarker = "-----BEGIN CERTIFICATE-----\n";
|
||||||
const string endMarker = "\n-----END CERTIFICATE-----";
|
const string endMarker = "\n-----END CERTIFICATE-----";
|
||||||
|
|
||||||
var base64Content = cert.Replace(beginMarker, "").Replace(endMarker, "").Trim();
|
var base64Start = beginMarker.Length;
|
||||||
|
var endIndex = cert.IndexOf(endMarker, base64Start, StringComparison.Ordinal);
|
||||||
|
var base64Content = cert.Substring(base64Start, endIndex - base64Start);
|
||||||
|
|
||||||
// https://github.com/shadowsocks/v2ray-plugin/blob/e9af1cdd2549d528deb20a4ab8d61c5fbe51f306/args.go#L172
|
// https://github.com/shadowsocks/v2ray-plugin/blob/e9af1cdd2549d528deb20a4ab8d61c5fbe51f306/args.go#L172
|
||||||
// Equal signs and commas [and backslashes] must be escaped with a backslash.
|
// Equal signs and commas [and backslashes] must be escaped with a backslash.
|
||||||
base64Content = base64Content.Replace("=", "\\=");
|
base64Content = base64Content.Replace("\\", "\\\\").Replace("=", "\\=").Replace(",", "\\,");
|
||||||
|
|
||||||
pluginArgs += $"certRaw={base64Content};";
|
pluginArgs += $"certRaw={base64Content};";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,13 +90,13 @@
|
||||||
<MenuItem x:Name="menuOpenTheFileLocation" Header="{x:Static resx:ResUI.menuOpenTheFileLocation}" />
|
<MenuItem x:Name="menuOpenTheFileLocation" Header="{x:Static resx:ResUI.menuOpenTheFileLocation}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
|
<MenuItem x:Name="menuReload" Header="{x:Static resx:ResUI.menuReload}" />
|
||||||
|
|
||||||
<MenuItem x:Name="menuHelp" Header="{x:Static resx:ResUI.menuHelp}">
|
<MenuItem x:Name="menuHelp" Header="{x:Static resx:ResUI.menuHelp}">
|
||||||
<MenuItem x:Name="menuCheckUpdate" Header="{x:Static resx:ResUI.menuCheckUpdate}" />
|
<MenuItem x:Name="menuCheckUpdate" Header="{x:Static resx:ResUI.menuCheckUpdate}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
<MenuItem x:Name="menuReload" Header="{x:Static resx:ResUI.menuReload}" />
|
|
||||||
|
|
||||||
<MenuItem x:Name="menuPromotion" Header="{x:Static resx:ResUI.menuPromotion}" />
|
<MenuItem x:Name="menuPromotion" Header="{x:Static resx:ResUI.menuPromotion}" />
|
||||||
|
|
||||||
<MenuItem x:Name="menuClose" Header="{x:Static resx:ResUI.menuExit}" />
|
<MenuItem x:Name="menuClose" Header="{x:Static resx:ResUI.menuExit}" />
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<reactiveui:ReactiveUserControl
|
<reactiveui:ReactiveUserControl
|
||||||
x:Class="v2rayN.Views.BackupAndRestoreView"
|
x:Class="v2rayN.Views.BackupAndRestoreView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
|
@ -23,6 +23,15 @@
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
<DockPanel Margin="{StaticResource Margin8}" DockPanel.Dock="Bottom">
|
<DockPanel Margin="{StaticResource Margin8}" DockPanel.Dock="Bottom">
|
||||||
|
<Button
|
||||||
|
Width="100"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
|
||||||
|
Content="{x:Static resx:ResUI.menuClose}"
|
||||||
|
DockPanel.Dock="Right"
|
||||||
|
IsCancel="True"
|
||||||
|
Style="{StaticResource DefButton}" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
x:Name="txtMsg"
|
x:Name="txtMsg"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<reactiveui:ReactiveUserControl
|
<reactiveui:ReactiveUserControl
|
||||||
x:Class="v2rayN.Views.CheckUpdateView"
|
x:Class="v2rayN.Views.CheckUpdateView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
|
@ -39,6 +39,15 @@
|
||||||
Content="{x:Static resx:ResUI.menuCheckUpdate}"
|
Content="{x:Static resx:ResUI.menuCheckUpdate}"
|
||||||
IsDefault="True"
|
IsDefault="True"
|
||||||
Style="{StaticResource DefButton}" />
|
Style="{StaticResource DefButton}" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
Width="100"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
|
||||||
|
Content="{x:Static resx:ResUI.menuClose}"
|
||||||
|
IsCancel="True"
|
||||||
|
Style="{StaticResource DefButton}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@
|
||||||
|
|
||||||
<materialDesign:DialogHost
|
<materialDesign:DialogHost
|
||||||
materialDesign:TransitionAssist.DisableTransitions="True"
|
materialDesign:TransitionAssist.DisableTransitions="True"
|
||||||
CloseOnClickAway="True"
|
|
||||||
Identifier="RootDialog"
|
Identifier="RootDialog"
|
||||||
SnackbarMessageQueue="{Binding ElementName=MainSnackbar, Path=MessageQueue}"
|
SnackbarMessageQueue="{Binding ElementName=MainSnackbar, Path=MessageQueue}"
|
||||||
Style="{StaticResource MaterialDesignEmbeddedDialogHost}">
|
Style="{StaticResource MaterialDesignEmbeddedDialogHost}">
|
||||||
|
|
@ -232,6 +231,23 @@
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
|
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
||||||
|
<MenuItem
|
||||||
|
x:Name="menuReload"
|
||||||
|
Padding="{StaticResource MarginLeftRight8}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuReload}">
|
||||||
|
<MenuItem.Header>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<materialDesign:PackIcon
|
||||||
|
Margin="{StaticResource MarginRight8}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Kind="Reload" />
|
||||||
|
<TextBlock Text="{x:Static resx:ResUI.menuReload}" />
|
||||||
|
</StackPanel>
|
||||||
|
</MenuItem.Header>
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
<Separator />
|
||||||
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuHelp"
|
x:Name="menuHelp"
|
||||||
|
|
@ -251,23 +267,6 @@
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
|
||||||
<MenuItem
|
|
||||||
x:Name="menuReload"
|
|
||||||
Padding="{StaticResource MarginLeftRight8}"
|
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuReload}">
|
|
||||||
<MenuItem.Header>
|
|
||||||
<StackPanel Orientation="Horizontal">
|
|
||||||
<materialDesign:PackIcon
|
|
||||||
Margin="{StaticResource MarginRight8}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Kind="Reload" />
|
|
||||||
<TextBlock Text="{x:Static resx:ResUI.menuReload}" />
|
|
||||||
</StackPanel>
|
|
||||||
</MenuItem.Header>
|
|
||||||
</MenuItem>
|
|
||||||
</Menu>
|
|
||||||
<Separator />
|
|
||||||
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuPromotion"
|
x:Name="menuPromotion"
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,18 @@
|
||||||
<sys:Double x:Key="QrcodeWidth">400</sys:Double>
|
<sys:Double x:Key="QrcodeWidth">400</sys:Double>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<StackPanel Margin="{StaticResource Margin8}">
|
<DockPanel Margin="{StaticResource Margin8}">
|
||||||
|
<StackPanel Margin="{StaticResource Margin8}" DockPanel.Dock="Bottom">
|
||||||
|
<Button
|
||||||
|
Width="100"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
|
||||||
|
Content="{x:Static resx:ResUI.menuClose}"
|
||||||
|
IsCancel="True"
|
||||||
|
IsDefault="True"
|
||||||
|
Style="{StaticResource DefButton}" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<Grid Margin="{StaticResource Margin8}">
|
<Grid Margin="{StaticResource Margin8}">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
|
|
@ -40,5 +51,5 @@
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
VerticalScrollBarVisibility="Auto" />
|
VerticalScrollBarVisibility="Auto" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</DockPanel>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<materialDesign:DialogHost
|
<materialDesign:DialogHost
|
||||||
materialDesign:TransitionAssist.DisableTransitions="True"
|
materialDesign:TransitionAssist.DisableTransitions="True"
|
||||||
CloseOnClickAway="True"
|
|
||||||
Identifier="SubDialog"
|
Identifier="SubDialog"
|
||||||
Style="{StaticResource MaterialDesignEmbeddedDialogHost}">
|
Style="{StaticResource MaterialDesignEmbeddedDialogHost}">
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue