diff --git a/.gitignore b/.gitignore index 7d5416b6..d0d8fe2b 100644 --- a/.gitignore +++ b/.gitignore @@ -84,6 +84,9 @@ StyleCopReport.xml *.rsp # but not Directory.Build.rsp, as it configures directory-level build defaults !Directory.Build.rsp +bin/ +obj/ +build/ *.sbr *.tlb *.tli diff --git a/v2rayN/ServiceLib/Common/Utils.cs b/v2rayN/ServiceLib/Common/Utils.cs index 05d7c621..8237e952 100644 --- a/v2rayN/ServiceLib/Common/Utils.cs +++ b/v2rayN/ServiceLib/Common/Utils.cs @@ -576,6 +576,58 @@ public class Utils } } + public static bool TryParseRange(string? input, int min, int max, out int from, out int to) + { + from = to = 0; + if (string.IsNullOrWhiteSpace(input)) + { + return true; + } + var parts = input.Split('-'); + if (parts.Length == 1) + { + if (!int.TryParse(parts[0], out from)) + { + return false; + } + to = from; + return from >= min && to <= max; + } + if (parts.Length != 2 + || !int.TryParse(parts[0], out from) + || !int.TryParse(parts[1], out to)) + { + return false; + } + return from >= min && to <= max && from <= to; + } + + public static bool TryParseMaxSplit(string? input, int min, int max, out int from, out int to) + { + from = to = 0; + if (string.IsNullOrWhiteSpace(input)) + { + return true; + } + var parts = input.Split('-'); + if (parts.Length == 1) + { + if (!int.TryParse(parts[0], out from)) + { + return false; + } + to = from; + return from >= min && to <= max; + } + if (parts.Length != 2 + || !int.TryParse(parts[0], out from) + || !int.TryParse(parts[1], out to)) + { + return false; + } + return from >= min && to <= max && from <= to; + } + public static bool IsPrivateNetwork(string ip) { if (IPAddress.TryParse(ip, out var address)) diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs index c8a2b033..437ceeee 100644 --- a/v2rayN/ServiceLib/Global.cs +++ b/v2rayN/ServiceLib/Global.cs @@ -406,6 +406,16 @@ public class Global "" ]; + public static readonly List FragmentPacketsOptions = + [ + "tlshello", + "1-1", + "1-2", + "1-3", + "1-4", + "1-5" + ]; + public static readonly List UserAgent = [ "chrome", diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs index 3956ca9f..30efbfc4 100644 --- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs +++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs @@ -169,7 +169,8 @@ public static class ConfigHandler { Packets = "tlshello", Length = "50-100", - Interval = "10-20" + Interval = "10-20", + MaxSplit = "0" }; config.GlobalHotkeys ??= []; diff --git a/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs b/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs index 8a63aac9..1cddf707 100644 --- a/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs +++ b/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs @@ -249,6 +249,7 @@ public class Fragment4RayItem public string? Packets { get; set; } public string? Length { get; set; } public string? Interval { get; set; } + public string? MaxSplit { get; set; } } [Serializable] diff --git a/v2rayN/ServiceLib/Models/CoreConfigs/V2rayConfig.cs b/v2rayN/ServiceLib/Models/CoreConfigs/V2rayConfig.cs index ffe9060b..7db4b0fb 100644 --- a/v2rayN/ServiceLib/Models/CoreConfigs/V2rayConfig.cs +++ b/v2rayN/ServiceLib/Models/CoreConfigs/V2rayConfig.cs @@ -512,6 +512,7 @@ public class MaskSettings4Ray public string? length { get; set; } public string? delay { get; set; } + public int? maxSplit { get; set; } // noise public int? reset { get; set; } diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index e35be02b..47360c37 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -231,6 +231,15 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 Fragment parameter format error. Please check Length (e.g. 50-100), Interval (1-100 range), and MaxSplit (0-10000). 的本地化字符串。 + /// + public static string FillFragmentParameterError { + get { + return ResourceManager.GetString("FillFragmentParameterError", resourceCulture); + } + } + /// /// 查找类似 Please enter the local listening port. 的本地化字符串。 /// @@ -4086,6 +4095,114 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 Fragment Length 的本地化字符串。 + /// + public static string TbSettingsFragmentLength { + get { + return ResourceManager.GetString("TbSettingsFragmentLength", resourceCulture); + } + } + + /// + /// 查找类似 Fragment size range in bytes (e.g., 50-100). First value must be <= second. Empty = default. 的本地化字符串。 + /// + public static string TbSettingsFragmentLengthTip { + get { + return ResourceManager.GetString("TbSettingsFragmentLengthTip", resourceCulture); + } + } + + /// + /// 查找类似 Fragment Interval 的本地化字符串。 + /// + public static string TbSettingsFragmentInterval { + get { + return ResourceManager.GetString("TbSettingsFragmentInterval", resourceCulture); + } + } + + /// + /// 查找类似 Delay between fragments in ms (e.g., 10-20). Range 1-100. First value must be <= second. Empty = default. 的本地化字符串。 + /// + public static string TbSettingsFragmentIntervalTip { + get { + return ResourceManager.GetString("TbSettingsFragmentIntervalTip", resourceCulture); + } + } + + /// + /// 查找类似 Max Split 的本地化字符串。 + /// + public static string TbSettingsFragmentMaxSplit { + get { + return ResourceManager.GetString("TbSettingsFragmentMaxSplit", resourceCulture); + } + } + + /// + /// 查找类似 Maximum number of splits (0 = unlimited, 0-10000). Only effective for Xray-core. Empty = default. 的本地化字符串。 + /// + public static string TbSettingsFragmentMaxSplitTip { + get { + return ResourceManager.GetString("TbSettingsFragmentMaxSplitTip", resourceCulture); + } + } + + /// + /// 查找类似 Fragment Packets 的本地化字符串。 + /// + public static string TbSettingsFragmentPackets { + get { + return ResourceManager.GetString("TbSettingsFragmentPackets", resourceCulture); + } + } + + /// + /// 查找类似 Packets to fragment: tlshello (TLS ClientHello) or 1-1 to 1-5 (first N TCP packets) 的本地化字符串。 + /// + public static string TbSettingsFragmentPacketsTip { + get { + return ResourceManager.GetString("TbSettingsFragmentPacketsTip", resourceCulture); + } + } + + /// + /// 查找类似 Sing-box Fragment Strategy 的本地化字符串。 + /// + public static string TbSettingsFragmentSingboxStrategy { + get { + return ResourceManager.GetString("TbSettingsFragmentSingboxStrategy", resourceCulture); + } + } + + /// + /// 查找类似 TLS Fragment: standard TLS record splitting. TCP Bypass: fragment TCP packets. Double: both modes combined. sing-box only. 的本地化字符串。 + /// + public static string TbSettingsFragmentSingboxStrategyTip { + get { + return ResourceManager.GetString("TbSettingsFragmentSingboxStrategyTip", resourceCulture); + } + } + + /// + /// 查找类似 Fallback Delay 的本地化字符串。 + /// + public static string TbSettingsFragmentFallbackDelay { + get { + return ResourceManager.GetString("TbSettingsFragmentFallbackDelay", resourceCulture); + } + } + + /// + /// 查找类似 Fallback delay for TLS fragment. Only effective for sing-box. Empty = default. 的本地化字符串。 + /// + public static string TbSettingsFragmentFallbackDelayTip { + get { + return ResourceManager.GetString("TbSettingsFragmentFallbackDelayTip", resourceCulture); + } + } + /// /// 查找类似 Enable hardware acceleration (requires restart) 的本地化字符串。 /// diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa.resx b/v2rayN/ServiceLib/Resx/ResUI.fa.resx index 104d4dab..6c55b7de 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fa.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fa.resx @@ -1104,6 +1104,39 @@ فعال کردن فرگمنت + + پکت‌های فرگمنت + + + پکت‌های قابل فرگمنت: tlshello (TLS ClientHello) یا 1-1 تا 1-5 (N اول پکت TCP) + + + طول فرگمنت + + + محدوده اندازه فرگمنت بایت (مثلا 50-100). اول ≤ دوم. خالی = پیش‌فرض. + + + فاصله فرگمنت + + + تأخیر بین فرگمنت‌ها میلی‌ثانیه (مثلا 10-20). بازه 1-100. اول ≤ دوم. خالی = پیش‌فرض. + + + حداکثر تقسیم + + + مکسیمم تعداد تقسیم (0 = نامحدود، 0-10000). فقط Xray-core. خالی = پیش‌فرض. + + + تأخیر فول‌بک + + + تأخیر فول‌بک فرگمنت TLS. فقط sing-box. خالی = پیش‌فرض. + + + فرمت محدوده نامعتبر. از 'from-to' استفاده کنید (مثلا 50-100). + فعال کردن کش فایل مجموعه قوانین برای sing-box diff --git a/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayN/ServiceLib/Resx/ResUI.fr.resx index 532a422b..cfee0bd9 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fr.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fr.resx @@ -1101,6 +1101,39 @@ Activer le fragmentation (Fragment) + + Paquets fragmentés + + + Paquets à fragmenter : tlshello (TLS ClientHello) ou 1-1 à 1-5 (premiers N paquets TCP) + + + Longueur fragment + + + Plage de taille fragment (ex: 50-100). Première valeur ≤ seconde. Vide = défaut. + + + Intervalle fragment + + + Délai entre fragments en ms (ex: 10-20). Plage 1-100. Première valeur ≤ seconde. Vide = défaut. + + + Max Split + + + Nb max de splits (0 = illimité, 0-10000). Xray-core seulement. Vide = défaut. + + + Délai fallback + + + Délai fallback pour fragment TLS. sing-box seulement. Vide = défaut. + + + Format de plage invalide. Utilisez 'from-to' (ex: 50-100). + Activer le fichier de cache de sing-box (fichiers règles) diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx index 51fbad89..756e8e32 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1104,6 +1104,39 @@ Fragment engedélyezése + + Fragmentált csomagok + + + Fragmentálandó csomagok: tlshello (TLS ClientHello) vagy 1-1 – 1-5 (az első N TCP csomag) + + + Fragment hossz + + + Fragment méret tartománya bájtokban (pl. 50-100). Az első érték ≤ második. Üres = alapértelmezett. + + + Fragment intervallum + + + Késleltetés a fragmented csomagok között ms-ben (pl. 10-20). Tartomány 1-100. Az első érték ≤ második. Üres = alapértelmezett. + + + Max darabolás + + + Maximális darabolások száma (0 = korlátlan, 0-10000). Csak Xray-core. Üres = alapértelmezett. + + + Fallback késleltetés + + + TLS fragment fallback késleltetés. Csak sing-box. Üres = alapértelmezett. + + + Érvénytelen tartomány formátum. Használja 'from-to' (pl. 50-100). + Gyorsítótár fájl engedélyezése sing-boxhoz (szabálykészlet fájlok) diff --git a/v2rayN/ServiceLib/Resx/ResUI.id.resx b/v2rayN/ServiceLib/Resx/ResUI.id.resx index db630764..73c26704 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.id.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.id.resx @@ -1104,6 +1104,39 @@ Aktifkan fragment + + Paket Fragment + + + Paket untuk difragmentasikan: tlshello (TLS ClientHello) atau 1-1 s.d. 1-5 (N paket TCP pertama) + + + Panjang Fragment + + + Rentang ukuran fragment (byte), cth: 50-100. Nilai pertama harus ≤ kedua. Kosong = default. + + + Interval Fragment + + + Jeda antar fragment (ms), cth: 10-20. Rentang 1-100. Nilai pertama harus ≤ kedua. Kosong = default. + + + Maks Split + + + Maks jumlah split (0 = unlimited, 0-10000). Hanya Xray-core. Kosong = default. + + + Fallback Delay + + + Delay fallback untuk TLS fragment. Hanya sing-box. Kosong = default. + + + Format range tidak valid. Gunakan 'from-to' (cth: 50-100). + Aktifkan file cache untuk sing-box (file ruleset) diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index f0048800..e911aae0 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1104,6 +1104,39 @@ Enable fragment + + Fragment Packets + + + Packets to fragment: tlshello (TLS ClientHello) or 1-1 to 1-5 (first N TCP packets) + + + Fragment Length + + + Fragment size range in bytes (e.g., 50-100). First value must be <= second. Empty = default. + + + Fragment Interval + + + Delay between fragments in ms (e.g., 10-20). Range 1-100. First value must be <= second. Empty = default. + + + Max Split + + + Maximum number of fragments per packet (0-10000, 0 = unlimited). Xray only. Empty = default. + + + Fallback Delay + + + Fallback delay when ACK detection unavailable (e.g., 500ms). sing-box only. Empty = default. + + + Invalid range format. Use 'from-to' (e.g., 50-100). + Enable cache file for sing-box (ruleset files) diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx index 0791d45c..9007514e 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1104,6 +1104,39 @@ Включить фрагментацию (Fragment) + + Пакеты для фрагментации + + + Пакеты для фрагментации: tlshello (TLS ClientHello) или 1-1 — 1-5 (первые N TCP-пакетов) + + + Длина фрагмента + + + Диапазон размера фрагмента в байтах (например, 50-100). Первое значение не больше второго. Пусто = по умолчанию. + + + Интервал фрагментации + + + Задержка между фрагментами в мс (например, 10-20). Диапазон 1-100. Первое значение не больше второго. Пусто = по умолчанию. + + + Макс. разделение + + + Максимальное число разделений (0 = без лимита, 0-10000). Только для Xray-core. Пусто = по умолчанию. + + + Резервная задержка + + + Резервная задержка для TLS-фрагмента. Только для sing-box. Пусто = по умолчанию. + + + Неверный формат диапазона. Используйте 'from-to' (например, 50-100). + Включить файл кэша для sing-box (файлы наборов правил) diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index ec25431d..4367efce 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1101,6 +1101,39 @@ 启用分片 (Fragment) + + 分片包类型 + + + 要分片的包类型: tlshello (TLS ClientHello) 或 1-1 到 1-5 (前 N 个 TCP 包) + + + 分片长度 + + + 分片大小范围(字节), 如 50-100. 第一个值必须 <= 第二个值. 留空使用默认值. + + + 分片间隔 + + + 分片间延迟(毫秒), 如 10-20. 范围 1-100. 第一个值必须 <= 第二个值. 留空使用默认值. + + + 最大分片数 + + + 每个包最大分片数 (0-10000, 0=无限制). 仅 Xray. 留空使用默认值. + + + 回退延迟 + + + ACK 检测不可用时的回退延迟 (如 500ms). 仅 sing-box. 留空使用默认值. + + + 无效的范围格式。请使用 'from-to' (如 50-100)。 + 启用 sing-box (规则集文件) 的缓存文件 diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index 04740fdb..61771c75 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1101,6 +1101,39 @@ 啟用分片(Fragment) + + 分片封包類型 + + + 要分片的封包類型:tlshello (TLS ClientHello) 或 1-1 到 1-5 (前 N 個 TCP 封包) + + + 分片長度 + + + 分片大小範圍(位元組),如 50-100。第一個值必須 <= 第二個值。留空使用預設值。 + + + 分片間隔 + + + 分片間延遲(毫秒),如 10-20。範圍 1-100。第一個值必須 <= 第二個值。留空使用預設值。 + + + 最大分片數 + + + 每個封包最大分片數 (0-10000, 0=無限制)。僅 Xray。留空使用預設值。 + + + 回退延遲 + + + ACK 偵測不可用時的回退延遲 (如 500ms)。僅 sing-box。留空使用預設值。 + + + 無效的範圍格式。請使用 'from-to' (如 50-100)。 + 啟用 sing-box(規則集檔案)的快取檔案 diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs index a94dbcba..b03f78fa 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs @@ -896,9 +896,17 @@ public partial class CoreConfigV2rayService private (Mask4Ray tcpFragment, Mask4Ray udpNoise) BuildFragmentsMasks() { - var configPackets = _config.Fragment4RayItem?.Packets ?? "tlshello"; - var configLength = _config.Fragment4RayItem?.Length ?? "50-100"; - var configDelay = _config.Fragment4RayItem?.Interval ?? "10-20"; + var configPackets = _config.Fragment4RayItem?.Packets.NullIfEmpty() ?? "tlshello"; + var configLength = _config.Fragment4RayItem?.Length.NullIfEmpty() ?? "50-100"; + var configDelay = _config.Fragment4RayItem?.Interval.NullIfEmpty() ?? "10-20"; + var configMaxSplit = _config.Fragment4RayItem?.MaxSplit.NullIfEmpty() ?? "0"; + + var maxSplit = 0; + var parts = configMaxSplit.Split('-'); + if (parts.Length > 0 && int.TryParse(parts[0], out var ms)) + { + maxSplit = ms; + } var fragmentMask = new Mask4Ray { @@ -908,6 +916,7 @@ public partial class CoreConfigV2rayService packets = configPackets, length = configLength, delay = configDelay, + maxSplit = maxSplit, } }; var noiseMask = new Mask4Ray diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index d15a3c07..04514847 100644 --- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -26,6 +26,10 @@ public class OptionSettingViewModel : MyReactiveObject [Reactive] public int? HyDownMbps { get; set; } [Reactive] public bool EnableFragment { get; set; } [Reactive] public bool EnableFinalFragment { get; set; } + [Reactive] public string FragmentPackets { get; set; } + [Reactive] public string FragmentLength { get; set; } + [Reactive] public string FragmentInterval { get; set; } + [Reactive] public string FragmentMaxSplit { get; set; } #endregion Core @@ -163,6 +167,10 @@ public class OptionSettingViewModel : MyReactiveObject HyDownMbps = _config.HysteriaItem.DownMbps; EnableFragment = _config.CoreBasicItem.EnableFragment; EnableFinalFragment = _config.CoreBasicItem.EnableFinalFragment; + FragmentPackets = _config.Fragment4RayItem?.Packets; + FragmentLength = _config.Fragment4RayItem?.Length; + FragmentInterval = _config.Fragment4RayItem?.Interval; + FragmentMaxSplit = _config.Fragment4RayItem?.MaxSplit; #endregion Core @@ -343,8 +351,31 @@ public class OptionSettingViewModel : MyReactiveObject _config.CoreBasicItem.EnableCacheFile4Sbox = EnableCacheFile4Sbox; _config.HysteriaItem.UpMbps = HyUpMbps ?? 0; _config.HysteriaItem.DownMbps = HyDownMbps ?? 0; + if (EnableFragment) + { + if (!Utils.TryParseRange(FragmentLength, 0, int.MaxValue, out _, out _)) + { + NoticeManager.Instance.Enqueue(ResUI.FillFragmentParameterError); + return; + } + if (!Utils.TryParseRange(FragmentInterval, 1, 100, out _, out _)) + { + NoticeManager.Instance.Enqueue(ResUI.FillFragmentParameterError); + return; + } + if (FragmentMaxSplit.IsNotEmpty() + && !Utils.TryParseMaxSplit(FragmentMaxSplit, 0, 10000, out _, out _)) + { + NoticeManager.Instance.Enqueue(ResUI.FillFragmentParameterError); + return; + } + } _config.CoreBasicItem.EnableFragment = EnableFragment; _config.CoreBasicItem.EnableFinalFragment = EnableFinalFragment; + _config.Fragment4RayItem.Packets = FragmentPackets; + _config.Fragment4RayItem.Length = FragmentLength; + _config.Fragment4RayItem.Interval = FragmentInterval; + _config.Fragment4RayItem.MaxSplit = FragmentMaxSplit; _config.GuiItem.AutoRun = AutoRun; _config.GuiItem.EnableStatistics = EnableStatistics; diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml index f4e8fbc8..dedb36ae 100644 --- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml @@ -300,6 +300,115 @@ Margin="{StaticResource Margin4}" HorizontalAlignment="Left" /> + + cmbMtu.ItemsSource = Global.TunMtus; cmbStack.ItemsSource = Global.TunStacks; cmbIcmpRoutingPolicy.ItemsSource = Global.TunIcmpRoutingPolicies; + cmbFragmentPackets.ItemsSource = Global.FragmentPacketsOptions; cmbCoreType1.ItemsSource = Global.CoreTypes; cmbCoreType2.ItemsSource = Global.CoreTypes; @@ -84,6 +84,10 @@ public partial class OptionSettingWindow : WindowBase this.Bind(ViewModel, vm => vm.HyDownMbps, v => v.txtDownMbps.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableFragment, v => v.togenableFragment.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableFinalFragment, v => v.togenableFinalFragment.IsChecked).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.FragmentPackets, v => v.cmbFragmentPackets.SelectedItem).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.FragmentLength, v => v.txtFragmentLength.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.FragmentInterval, v => v.txtFragmentInterval.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.FragmentMaxSplit, v => v.txtFragmentMaxSplit.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoRun, v => v.togAutoRun.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableStatistics, v => v.togEnableStatistics.IsChecked).DisposeWith(disposables); diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml index da42494c..7a6b0256 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml @@ -17,6 +17,13 @@ Style="{StaticResource WindowGlobal}" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + vm.HyDownMbps, v => v.txtDownMbps.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableFragment, v => v.togenableFragment.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableFinalFragment, v => v.togenableFinalFragment.IsChecked).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.FragmentPackets, v => v.cmbFragmentPackets.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.FragmentLength, v => v.txtFragmentLength.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.FragmentInterval, v => v.txtFragmentInterval.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.FragmentMaxSplit, v => v.txtFragmentMaxSplit.Text).DisposeWith(disposables); //this.Bind(ViewModel, vm => vm.Kcpmtu, v => v.txtKcpmtu.Text).DisposeWith(disposables); //this.Bind(ViewModel, vm => vm.Kcptti, v => v.txtKcptti.Text).DisposeWith(disposables);