diff --git a/v2rayN/v2rayN/Global.cs b/v2rayN/v2rayN/Global.cs index a6aa202c..7b1a6e8c 100644 --- a/v2rayN/v2rayN/Global.cs +++ b/v2rayN/v2rayN/Global.cs @@ -91,6 +91,39 @@ "" }; + public static readonly List SubConvertUrls = new List { + @"https://sub.xeton.dev/sub?url={0}", + @"https://api.dler.io/sub?url={0}", + @"http://127.0.0.1:25500/sub?url={0}", + "" + }; + + public static readonly List SubConvertConfig = new List { + @"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online.ini" + }; + + public static readonly List SubConvertTargets = new List { + "", + "mixed", + "v2ray", + "clash", + "ss", + }; + + public static readonly List SpeedTestUrls = new() { + @"http://cachefly.cachefly.net/100mb.test", + @"http://cachefly.cachefly.net/10mb.test" + }; + + public static readonly Dictionary userAgentTxt = 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" }, + {"firefox","Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0" }, + {"safari","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" }, + {"edge","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70" }, + {"none",""} + }; + public static readonly List vmessSecuritys = new() { "aes-128-gcm", "chacha20-poly1305", "auto", "none", "zero" }; public static readonly List ssSecuritys = new() { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "none", "plain" }; public static readonly List ssSecuritysInSagerNet = new() { "none", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "rc4", "rc4-md5", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-cfb8", "aes-192-cfb8", "aes-256-cfb8", "aes-128-ofb", "aes-192-ofb", "aes-256-ofb", "bf-cfb", "cast5-cfb", "des-cfb", "idea-cfb", "rc2-cfb", "seed-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb", "camellia-128-cfb8", "camellia-192-cfb8", "camellia-256-cfb8", "salsa20", "chacha20", "chacha20-ietf", "xchacha20" }; @@ -104,15 +137,6 @@ public static readonly List fingerprints = new() { "chrome", "firefox", "safari", "ios", "android", "edge", "360", "qq", "random", "randomized", "" }; public static readonly List userAgent = new() { "chrome", "firefox", "safari", "edge", "none" }; - public static readonly Dictionary userAgentTxt = 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" }, - {"firefox","Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0" }, - {"safari","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" }, - {"edge","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70" }, - {"none",""} - }; - public static readonly List allowInsecures = new() { "true", "false", "" }; public static readonly List domainStrategy4Freedoms = new() { "AsIs", "UseIP", "UseIPv4", "UseIPv6", "" }; public static readonly List Languages = new() { "zh-Hans", "en", "fa-Ir", "ru" }; @@ -123,7 +147,6 @@ public static readonly List TunMtus = new() { "9000", "1500" }; public static readonly List TunStacks = new() { "gvisor", "system" }; public static readonly List PresetMsgFilters = new() { "proxy", "direct", "block", "" }; - public static readonly List SpeedTestUrls = new() { @"http://cachefly.cachefly.net/100mb.test", @"http://cachefly.cachefly.net/10mb.test" }; #endregion const diff --git a/v2rayN/v2rayN/Handler/UpdateHandle.cs b/v2rayN/v2rayN/Handler/UpdateHandle.cs index 68d4947d..01b282fc 100644 --- a/v2rayN/v2rayN/Handler/UpdateHandle.cs +++ b/v2rayN/v2rayN/Handler/UpdateHandle.cs @@ -190,6 +190,20 @@ namespace v2rayN.Handler //one url url = Utils.GetPunycode(url); + //convert + if (!Utils.IsNullOrEmpty(item.convertTarget)) + { + var subConvertUrl = string.IsNullOrEmpty(config.constItem.subConvertUrl) ? Global.SubConvertUrls.FirstOrDefault() : config.constItem.subConvertUrl; + url = string.Format(subConvertUrl!, Utils.UrlEncode(url)); + if (!url.Contains("target=")) + { + url += string.Format("&target={0}", item.convertTarget); + } + if (!url.Contains("config=")) + { + url += string.Format("&config={0}", Global.SubConvertConfig.FirstOrDefault()); + } + } var result = await downloadHandle.TryDownloadString(url, blProxy, userAgent); if (blProxy && Utils.IsNullOrEmpty(result)) { @@ -197,7 +211,7 @@ namespace v2rayN.Handler } //more url - if (!Utils.IsNullOrEmpty(item.moreUrl.TrimEx())) + if (Utils.IsNullOrEmpty(item.convertTarget) && !Utils.IsNullOrEmpty(item.moreUrl.TrimEx())) { if (!Utils.IsNullOrEmpty(result) && Utils.IsBase64String(result)) { diff --git a/v2rayN/v2rayN/Mode/ConfigItems.cs b/v2rayN/v2rayN/Mode/ConfigItems.cs index 92301c45..a8ff86e0 100644 --- a/v2rayN/v2rayN/Mode/ConfigItems.cs +++ b/v2rayN/v2rayN/Mode/ConfigItems.cs @@ -132,6 +132,7 @@ namespace v2rayN.Mode public class ConstItem { public string defIEProxyExceptions { get; set; } + public string subConvertUrl { get; set; } = string.Empty; } [Serializable] diff --git a/v2rayN/v2rayN/Mode/SubItem.cs b/v2rayN/v2rayN/Mode/SubItem.cs index 9f71cbaf..3221e914 100644 --- a/v2rayN/v2rayN/Mode/SubItem.cs +++ b/v2rayN/v2rayN/Mode/SubItem.cs @@ -20,10 +20,12 @@ namespace v2rayN.Mode public int sort { get; set; } - public string filter { get; set; } + public string? filter { get; set; } public int autoUpdateInterval { get; set; } public long updateTime { get; set; } + + public string? convertTarget { get; set; } } } \ No newline at end of file diff --git a/v2rayN/v2rayN/Resx/ResUI.Designer.cs b/v2rayN/v2rayN/Resx/ResUI.Designer.cs index e7ae0d4b..ccec13fb 100644 --- a/v2rayN/v2rayN/Resx/ResUI.Designer.cs +++ b/v2rayN/v2rayN/Resx/ResUI.Designer.cs @@ -375,6 +375,24 @@ namespace v2rayN.Resx { } } + /// + /// 查找类似 Convert target type 的本地化字符串。 + /// + public static string LvConvertTarget { + get { + return ResourceManager.GetString("LvConvertTarget", resourceCulture); + } + } + + /// + /// 查找类似 Please leave blank if no conversion is required 的本地化字符串。 + /// + public static string LvConvertTargetTip { + get { + return ResourceManager.GetString("LvConvertTargetTip", resourceCulture); + } + } + /// /// 查找类似 Count 的本地化字符串。 /// @@ -421,7 +439,7 @@ namespace v2rayN.Resx { } /// - /// 查找类似 More urls, separated by commas 的本地化字符串。 + /// 查找类似 More urls, separated by commas;Subscription conversion will be invalid 的本地化字符串。 /// public static string LvMoreUrl { get { diff --git a/v2rayN/v2rayN/Resx/ResUI.resx b/v2rayN/v2rayN/Resx/ResUI.resx index c1bad109..c31763b6 100644 --- a/v2rayN/v2rayN/Resx/ResUI.resx +++ b/v2rayN/v2rayN/Resx/ResUI.resx @@ -1103,7 +1103,7 @@ Reboot as administrator - More urls, separated by commas + More urls, separated by commas;Subscription conversion will be invalid {0}:{1}/s↑ | {2}/s↓ @@ -1114,4 +1114,10 @@ Enable logging to file + + Convert target type + + + Please leave blank if no conversion is required + \ No newline at end of file diff --git a/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx b/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx index 5d5340ec..bcd876e0 100644 --- a/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx @@ -1103,7 +1103,7 @@ 以管理员身份重启 - 更多地址(url),用逗号(,)分隔 + 更多地址(url),用逗号(,)分隔;订阅转换将失效 自动更新间隔(分钟) @@ -1111,4 +1111,10 @@ 启用日志存到文件 + + 订阅转换目标类型 + + + 不需要转换时请留空 + \ No newline at end of file diff --git a/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs b/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs index 4d809f27..e6d5cfac 100644 --- a/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs @@ -72,6 +72,7 @@ namespace v2rayN.ViewModels [Reactive] public int SpeedTestTimeout { get; set; } [Reactive] public string SpeedTestUrl { get; set; } [Reactive] public bool EnableHWA { get; set; } + [Reactive] public string SubConvertUrl { get; set; } #endregion UI @@ -178,6 +179,7 @@ namespace v2rayN.ViewModels SpeedTestTimeout = _config.speedTestItem.speedTestTimeout; SpeedTestUrl = _config.speedTestItem.speedTestUrl; EnableHWA = _config.guiItem.enableHWA; + SubConvertUrl = _config.constItem.subConvertUrl; #endregion UI @@ -360,6 +362,7 @@ namespace v2rayN.ViewModels _config.speedTestItem.speedTestTimeout = SpeedTestTimeout; _config.speedTestItem.speedTestUrl = SpeedTestUrl; _config.guiItem.enableHWA = EnableHWA; + _config.constItem.subConvertUrl = SubConvertUrl; //systemProxy _config.systemProxyExceptions = systemProxyExceptions; diff --git a/v2rayN/v2rayN/ViewModels/SubEditViewModel.cs b/v2rayN/v2rayN/ViewModels/SubEditViewModel.cs index c7399889..b492347b 100644 --- a/v2rayN/v2rayN/ViewModels/SubEditViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/SubEditViewModel.cs @@ -68,6 +68,7 @@ namespace v2rayN.ViewModels item.userAgent = SelectedSource.userAgent; item.sort = SelectedSource.sort; item.filter = SelectedSource.filter; + item.convertTarget = SelectedSource.convertTarget; } if (ConfigHandler.AddSubItem(ref _config, item) == 0) diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml index a52689f1..87573dce 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml @@ -480,6 +480,7 @@ + @@ -749,6 +750,23 @@ Grid.Column="1" Margin="{StaticResource SettingItemMargin}" HorizontalAlignment="Left" /> + + + diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs index a13bed67..36653c20 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs @@ -72,6 +72,10 @@ namespace v2rayN.Views Global.SpeedTestUrls.ForEach(it => { cmbSpeedTestUrl.Items.Add(it); + }); + Global.SubConvertUrls.ForEach(it => + { + cmbSubConvertUrl.Items.Add(it); }); //fill fonts @@ -162,6 +166,7 @@ namespace v2rayN.Views this.Bind(ViewModel, vm => vm.SpeedTestTimeout, v => v.cmbSpeedTestTimeout.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SpeedTestUrl, v => v.cmbSpeedTestUrl.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableHWA, v => v.togEnableHWA.IsChecked).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.SubConvertUrl, v => v.cmbSubConvertUrl.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.systemProxyExceptions, v => v.txtsystemProxyExceptions.Text).DisposeWith(disposables); diff --git a/v2rayN/v2rayN/Views/SubEditWindow.xaml b/v2rayN/v2rayN/Views/SubEditWindow.xaml index 4e9b7847..43569ddf 100644 --- a/v2rayN/v2rayN/Views/SubEditWindow.xaml +++ b/v2rayN/v2rayN/Views/SubEditWindow.xaml @@ -50,6 +50,7 @@ + @@ -195,16 +196,35 @@ AcceptsReturn="True" Style="{StaticResource MyOutlinedTextBox}" /> + + + + + + { + cmbConvertTarget.Items.Add(it); + }); + this.WhenActivated(disposables => { this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); @@ -26,6 +31,7 @@ namespace v2rayN.Views this.Bind(ViewModel, vm => vm.SelectedSource.userAgent, v => v.txtUserAgent.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.sort, v => v.txtSort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.filter, v => v.txtFilter.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.SelectedSource.convertTarget, v => v.cmbConvertTarget.Text).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); });