Add bind interface (#9222)

This commit is contained in:
DHR60
2026-05-04 06:38:32 +00:00
committed by GitHub
parent 37ef25cbfe
commit 8450f2e420
21 changed files with 261 additions and 67 deletions
@@ -47,6 +47,7 @@ public class CoreConfigContextBuilder
ProtectDomainList = [],
RawDnsItem = await AppManager.Instance.GetDNSItem(coreType),
RoutingItem = await ConfigHandler.GetDefaultRouting(config),
IsWindows = Utils.IsWindows(),
};
var validatorResult = NodeValidatorResult.Empty();
var (actNode, nodeValidatorResult) = await ResolveNodeAsync(context, node);
@@ -41,7 +41,6 @@ public static class ConfigHandler
Loglevel = "warning",
MuxEnabled = false,
};
config.CoreBasicItem.SendThrough = config.CoreBasicItem.SendThrough?.TrimEx();
if (config.Inbound == null)
{
+2
View File
@@ -17,6 +17,8 @@ public class CoreBasicItem
public string? SendThrough { get; set; }
public string? BindInterface { get; set; }
public bool EnableFragment { get; set; }
public bool EnableCacheFile4Sbox { get; set; } = true;
@@ -17,4 +17,6 @@ public record CoreConfigContext
// TUN Compatibility
public bool IsTunEnabled { get; init; } = false;
public HashSet<string> ProtectDomainList { get; init; } = [];
public bool IsWindows { get; init; }
}
+18
View File
@@ -3681,6 +3681,24 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Bind Interface 的本地化字符串。
/// </summary>
public static string TbSettingsBindInterface {
get {
return ResourceManager.GetString("TbSettingsBindInterface", resourceCulture);
}
}
/// <summary>
/// 查找类似 For multi-interface environments, enter the name of the interface to bind. Only effective on Windows systems and TUN mode 的本地化字符串。
/// </summary>
public static string TbSettingsBindInterfaceTip {
get {
return ResourceManager.GetString("TbSettingsBindInterfaceTip", resourceCulture);
}
}
/// <summary>
/// 查找类似 Users in China region can ignore this item 的本地化字符串。
/// </summary>
+15 -3
View File
@@ -1689,9 +1689,6 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbLegacyProtect" xml:space="preserve">
<value>Legacy TUN Protect</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>For multi-interface environments, enter the local machine's IPv4 address</value>
</data>
<data name="TbCamouflageDomain" xml:space="preserve">
<value>Camouflage domain</value>
</data>
@@ -1713,4 +1710,19 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbSettingsUdpTestUrl" xml:space="preserve">
<value>UDP Test Url</value>
</data>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>Local outbound address (SendThrough)</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>For multi-interface environments, enter the local machine's IPv4 address</value>
</data>
<data name="FillCorrectSendThroughIPv4" xml:space="preserve">
<value>Please fill in the correct IPv4 address for SendThrough.</value>
</data>
<data name="TbSettingsBindInterface" xml:space="preserve">
<value>Bind Interface</value>
</data>
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
<value>For multi-interface environments, enter the name of the interface to bind. Only effective on Windows systems and TUN mode</value>
</data>
</root>
+15 -9
View File
@@ -1311,15 +1311,6 @@
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>Le mot de passe sera vérifié en ligne de commande. En cas d’échec ou de dysfonctionnement, redémarrez lapplication. Il nest pas stocké et doit être saisi à chaque redémarrage.</value>
</data>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>Adresse sortante locale (SendThrough)</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>Pour environnements multi-interfaces, entrez l'adresse IPv4 de la machine locale.</value>
</data>
<data name="FillCorrectSendThroughIPv4" xml:space="preserve">
<value>Veuillez saisir ladresse IPv4 correcte de SendThrough.</value>
</data>
<data name="TransportHeaderType5" xml:space="preserve">
<value>Mode XHTTP</value>
</data>
@@ -1710,4 +1701,19 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbAllowInsecureCertFetchTips" xml:space="preserve">
<value>Only for fetching self-signed certificates. This may expose you to MITM risks.</value>
</data>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>Adresse sortante locale (SendThrough)</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>Pour environnements multi-interfaces, entrez l'adresse IPv4 de la machine locale</value>
</data>
<data name="FillCorrectSendThroughIPv4" xml:space="preserve">
<value>Veuillez saisir ladresse IPv4 correcte de SendThrough.</value>
</data>
<data name="TbSettingsBindInterface" xml:space="preserve">
<value>Lier l'interface</value>
</data>
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
<value>Pour les environnements multi-interfaces, entrez le nom de l'interface à lier. Ne fonctionne que sur les systèmes Windows et en mode TUN</value>
</data>
</root>
+15 -3
View File
@@ -1689,9 +1689,6 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbLegacyProtect" xml:space="preserve">
<value>Legacy TUN Protect</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>For multi-interface environments, enter the local machine's IPv4 address</value>
</data>
<data name="TbCamouflageDomain" xml:space="preserve">
<value>Álcázási tartomány</value>
</data>
@@ -1713,4 +1710,19 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbSettingsUdpTestUrl" xml:space="preserve">
<value>UDP Test Url</value>
</data>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>Local outbound address (SendThrough)</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>For multi-interface environments, enter the local machine's IPv4 address</value>
</data>
<data name="FillCorrectSendThroughIPv4" xml:space="preserve">
<value>Please fill in the correct IPv4 address for SendThrough.</value>
</data>
<data name="TbSettingsBindInterface" xml:space="preserve">
<value>Bind Interface</value>
</data>
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
<value>For multi-interface environments, enter the name of the interface to bind. Only effective on Windows systems and TUN mode</value>
</data>
</root>
+16 -10
View File
@@ -1314,15 +1314,6 @@
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
</data>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>Local outbound address (SendThrough)</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>For multi-interface environments, enter the local machine's IPv4 address</value>
</data>
<data name="FillCorrectSendThroughIPv4" xml:space="preserve">
<value>Please fill in the correct IPv4 address for SendThrough.</value>
</data>
<data name="TransportHeaderType5" xml:space="preserve">
<value>xhttp mode</value>
</data>
@@ -1719,4 +1710,19 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbSettingsUdpTestUrl" xml:space="preserve">
<value>UDP Test Url</value>
</data>
</root>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>Local outbound address (SendThrough)</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>For multi-interface environments, enter the local machine's IPv4 address</value>
</data>
<data name="FillCorrectSendThroughIPv4" xml:space="preserve">
<value>Please fill in the correct IPv4 address for SendThrough.</value>
</data>
<data name="TbSettingsBindInterface" xml:space="preserve">
<value>Bind Interface</value>
</data>
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
<value>For multi-interface environments, enter the name of the interface to bind. Only effective on Windows systems and TUN mode</value>
</data>
</root>
+13 -7
View File
@@ -1689,9 +1689,6 @@
<data name="TbLegacyProtect" xml:space="preserve">
<value>Устаревшая защита TUN (Legacy Protect)</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>Для среды с несколькими сетевыми интерфейсами укажите IPv4-адрес локального компьютера</value>
</data>
<data name="TbCamouflageDomain" xml:space="preserve">
<value>Камуфляжный домен</value>
</data>
@@ -1713,10 +1710,19 @@
<data name="TbSettingsUdpTestUrl" xml:space="preserve">
<value>URL для UDP-теста</value>
</data>
<data name="FillCorrectSendThroughIPv4" xml:space="preserve">
<value>Укажите корректный IPv4-адрес для SendThrough.</value>
</data>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>Локальный исходящий адрес (SendThrough)</value>
</data>
</root>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>Для среды с несколькими сетевыми интерфейсами укажите IPv4-адрес локального компьютера</value>
</data>
<data name="FillCorrectSendThroughIPv4" xml:space="preserve">
<value>Укажите корректный IPv4-адрес для SendThrough.</value>
</data>
<data name="TbSettingsBindInterface" xml:space="preserve">
<value>Привязать интерфейс</value>
</data>
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
<value>Для среды с несколькими сетевыми интерфейсами укажите имя интерфейса для привязки. Работает только в Windows и режиме TUN</value>
</data>
</root>
+16 -10
View File
@@ -1311,15 +1311,6 @@
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>密码将调用命令行校验,如果因为校验错误导致无法正常运行时,请重启本应用。 密码不会存储,每次重启后都需要再次输入。</value>
</data>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>本地出站地址 (SendThrough)</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>用于多网口环境,请填写本机 IPv4 地址</value>
</data>
<data name="FillCorrectSendThroughIPv4" xml:space="preserve">
<value>请填写正确的 SendThrough IPv4 地址。</value>
</data>
<data name="TransportHeaderType5" xml:space="preserve">
<value>XHTTP 模式</value>
</data>
@@ -1716,4 +1707,19 @@
<data name="TbSettingsUdpTestUrl" xml:space="preserve">
<value>UDP 测试地址</value>
</data>
</root>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>本地出站地址 (SendThrough)</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>用于多网口环境,请填写本机 IPv4 地址</value>
</data>
<data name="FillCorrectSendThroughIPv4" xml:space="preserve">
<value>请填写正确的 SendThrough IPv4 地址。</value>
</data>
<data name="TbSettingsBindInterface" xml:space="preserve">
<value>绑定网口</value>
</data>
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
<value>用于多网口环境,填写要绑定的网口名称,仅生效于 Windows 系统和 TUN 模式</value>
</data>
</root>
+15 -3
View File
@@ -1686,9 +1686,6 @@
<data name="TbLegacyProtect" xml:space="preserve">
<value>Legacy TUN Protect</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>For multi-interface environments, enter the local machine's IPv4 address</value>
</data>
<data name="TbCamouflageDomain" xml:space="preserve">
<value>偽裝域名</value>
</data>
@@ -1710,4 +1707,19 @@
<data name="TbSettingsUdpTestUrl" xml:space="preserve">
<value>UDP Test Url</value>
</data>
<data name="TbSettingsSendThrough" xml:space="preserve">
<value>Local outbound address (SendThrough)</value>
</data>
<data name="TbSettingsSendThroughTip" xml:space="preserve">
<value>For multi-interface environments, enter the local machine's IPv4 address</value>
</data>
<data name="FillCorrectSendThroughIPv4" xml:space="preserve">
<value>Please fill in the correct IPv4 address for SendThrough.</value>
</data>
<data name="TbSettingsBindInterface" xml:space="preserve">
<value>Bind Interface</value>
</data>
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
<value>For multi-interface environments, enter the name of the interface to bind. Only effective on Windows systems and TUN mode</value>
</data>
</root>
@@ -57,6 +57,7 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
ConvertGeo2Ruleset();
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
@@ -170,6 +171,7 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
_coreConfig.route.rules.Add(rule);
}
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
ret.Success = true;
ret.Data = JsonUtils.Serialize(_coreConfig);
@@ -229,6 +231,7 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
listen_port = port,
type = EInboundProtocol.mixed.ToString(),
});
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
@@ -59,22 +59,38 @@ public partial class CoreConfigSingboxService
return JsonUtils.Serialize(fullConfigTemplateNode);
}
private void ApplyOutboundSendThrough()
private void ApplyOutboundBindInterface()
{
var sendThrough = _config.CoreBasicItem.SendThrough?.TrimEx();
var bindInterface = _config.CoreBasicItem.BindInterface?.TrimEx();
if (bindInterface.IsNullOrEmpty())
{
return;
}
if (!(context.IsTunEnabled || context.IsWindows))
{
return;
}
foreach (var outbound in _coreConfig.outbounds ?? [])
{
outbound.inet4_bind_address = ShouldApplySendThrough(outbound, sendThrough) ? sendThrough : null;
outbound.detour = ShouldBindNet(outbound) ? bindInterface : null;
}
}
private static bool ShouldApplySendThrough(Outbound4Sbox outbound, string? sendThrough)
private void ApplyOutboundSendThrough()
{
var sendThrough = _config.CoreBasicItem.SendThrough?.TrimEx();
if (sendThrough.IsNullOrEmpty())
{
return false;
return;
}
foreach (var outbound in _coreConfig.outbounds ?? [])
{
outbound.inet4_bind_address = ShouldBindNet(outbound) ? sendThrough : null;
}
}
private static bool ShouldBindNet(Outbound4Sbox outbound)
{
if (outbound.type is "direct" or "block" or "dns" or "selector" or "urltest")
{
return false;
@@ -60,6 +60,7 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
{
ApplyOutboundFragment();
}
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
var finalRule = BuildFinalRule();
@@ -203,6 +204,7 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
{
ApplyOutboundFragment();
}
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
//ret.Msg =string.Format(ResUI.SuccessfulConfiguration"), node.getSummary());
ret.Success = true;
@@ -274,6 +276,7 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
{
ApplyOutboundFragment();
}
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
@@ -134,22 +134,59 @@ public partial class CoreConfigV2rayService
return JsonUtils.Serialize(fullConfigTemplateNode);
}
private void ApplyOutboundSendThrough()
private void ApplyOutboundBindInterface()
{
var sendThrough = _config.CoreBasicItem.SendThrough?.TrimEx();
var bindInterface = _config.CoreBasicItem.BindInterface?.TrimEx();
if (bindInterface.IsNullOrEmpty())
{
return;
}
if (!(context.IsTunEnabled || context.IsWindows))
{
return;
}
foreach (var outbound in _coreConfig.outbounds ?? [])
{
outbound.sendThrough = ShouldApplySendThrough(outbound, sendThrough) ? sendThrough : null;
if (!ShouldBindNet(outbound))
{
continue;
}
outbound.streamSettings ??= new();
outbound.streamSettings.sockopt ??= new();
outbound.streamSettings.sockopt.Interface = bindInterface;
// xhttp download bind interface
if (outbound?.streamSettings?.xhttpSettings?.extra is null)
{
continue;
}
var xhttpExtra = JsonUtils.ParseJson(JsonUtils.Serialize(outbound.streamSettings.xhttpSettings!.extra));
if (xhttpExtra is not JsonObject xhttpExtraObject
|| xhttpExtraObject["downloadSettings"] is not JsonObject downloadSettings)
{
continue;
}
var sockopt = downloadSettings["sockopt"] as JsonObject ?? new JsonObject();
sockopt["interface"] = bindInterface;
downloadSettings["sockopt"] = sockopt;
outbound.streamSettings.xhttpSettings.extra = xhttpExtraObject;
}
}
private static bool ShouldApplySendThrough(Outbounds4Ray outbound, string? sendThrough)
private void ApplyOutboundSendThrough()
{
var sendThrough = _config.CoreBasicItem.SendThrough?.TrimEx();
if (sendThrough.IsNullOrEmpty())
{
return false;
return;
}
foreach (var outbound in _coreConfig.outbounds ?? [])
{
outbound.sendThrough = ShouldBindNet(outbound) ? sendThrough : null;
}
}
private static bool ShouldBindNet(Outbounds4Ray outbound)
{
if (outbound.protocol is "freedom" or "blackhole" or "dns" or "loopback")
{
return false;
@@ -60,6 +60,11 @@ public partial class CoreConfigV2rayService
{
tunInbound.settings.gateway = ["172.18.0.1/30"];
}
var bindInterface = _config.CoreBasicItem.BindInterface?.TrimEx();
if (!bindInterface.IsNullOrEmpty())
{
tunInbound.settings.autoOutboundsInterface = bindInterface;
}
tunInbound.sniffing = inbound.sniffing;
_coreConfig.inbounds.Add(tunInbound);
}
@@ -21,6 +21,7 @@ public class OptionSettingViewModel : MyReactiveObject
[Reactive] public string defFingerprint { get; set; }
[Reactive] public string defUserAgent { get; set; }
[Reactive] public string sendThrough { get; set; }
[Reactive] public string bindInterface { get; set; }
[Reactive] public string mux4SboxProtocol { get; set; }
[Reactive] public bool enableCacheFile4Sbox { get; set; }
[Reactive] public int? hyUpMbps { get; set; }
@@ -156,7 +157,8 @@ public class OptionSettingViewModel : MyReactiveObject
defAllowInsecure = _config.CoreBasicItem.DefAllowInsecure;
defFingerprint = _config.CoreBasicItem.DefFingerprint;
defUserAgent = _config.CoreBasicItem.DefUserAgent;
sendThrough = _config.CoreBasicItem.SendThrough;
sendThrough = _config.CoreBasicItem.SendThrough ?? string.Empty;
bindInterface = _config.CoreBasicItem.BindInterface ?? string.Empty;
mux4SboxProtocol = _config.Mux4SboxItem.Protocol;
enableCacheFile4Sbox = _config.CoreBasicItem.EnableCacheFile4Sbox;
hyUpMbps = _config.HysteriaItem.UpMbps;
@@ -301,7 +303,7 @@ public class OptionSettingViewModel : MyReactiveObject
NoticeManager.Instance.Enqueue(ResUI.FillLocalListeningPort);
return;
}
var sendThroughValue = sendThrough?.TrimEx();
var sendThroughValue = sendThrough.TrimEx();
if (sendThroughValue.IsNotEmpty() && !Utils.IsIpv4(sendThroughValue))
{
NoticeManager.Instance.Enqueue(ResUI.FillCorrectSendThroughIPv4);
@@ -346,7 +348,8 @@ public class OptionSettingViewModel : MyReactiveObject
_config.CoreBasicItem.DefAllowInsecure = defAllowInsecure;
_config.CoreBasicItem.DefFingerprint = defFingerprint;
_config.CoreBasicItem.DefUserAgent = defUserAgent;
_config.CoreBasicItem.SendThrough = sendThrough?.TrimEx();
_config.CoreBasicItem.SendThrough = sendThrough.TrimEx();
_config.CoreBasicItem.BindInterface = bindInterface.TrimEx();
_config.Mux4SboxItem.Protocol = mux4SboxProtocol;
_config.CoreBasicItem.EnableCacheFile4Sbox = enableCacheFile4Sbox;
_config.HysteriaItem.UpMbps = hyUpMbps ?? 0;
@@ -37,8 +37,8 @@
<ScrollViewer VerticalScrollBarVisibility="Visible">
<Grid
Margin="{StaticResource Margin4}"
ColumnDefinitions="Auto,Auto,Auto"
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
ColumnDefinitions="Auto,Auto,*"
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
<TextBlock
Grid.Row="0"
@@ -331,16 +331,36 @@
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsBindInterface}" />
<TextBox
x:Name="txtbindInterface"
Grid.Row="21"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}" />
<TextBlock
Grid.Row="21"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsBindInterfaceTip}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="22"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsSendThrough}" />
<TextBox
x:Name="txtsendThrough"
Grid.Row="21"
Grid.Row="22"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
Watermark="0.0.0.0" />
<TextBlock
Grid.Row="21"
Grid.Row="22"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
+28 -4
View File
@@ -65,6 +65,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@@ -398,21 +399,44 @@
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsSendThrough}" />
Text="{x:Static resx:ResUI.TbSettingsBindInterface}" />
<TextBox
x:Name="txtsendThrough"
x:Name="txtbindInterface"
Grid.Row="21"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
Style="{StaticResource DefTextBox}"
materialDesign:HintAssist.Hint="0.0.0.0" />
Style="{StaticResource DefTextBox}" />
<TextBlock
Grid.Row="21"
Grid.Column="2"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsBindInterfaceTip}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="22"
Grid.Column="0"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsSendThrough}" />
<TextBox
x:Name="txtsendThrough"
Grid.Row="22"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin8}"
materialDesign:HintAssist.Hint="0.0.0.0"
Style="{StaticResource DefTextBox}" />
<TextBlock
Grid.Row="22"
Grid.Column="2"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsSendThroughTip}"
TextWrapping="Wrap" />
</Grid>
@@ -75,6 +75,7 @@ public partial class OptionSettingWindow
this.Bind(ViewModel, vm => vm.defFingerprint, v => v.cmbdefFingerprint.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.defUserAgent, v => v.cmbdefUserAgent.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.sendThrough, v => v.txtsendThrough.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.bindInterface, v => v.txtbindInterface.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.mux4SboxProtocol, v => v.cmbmux4SboxProtocol.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.enableCacheFile4Sbox, v => v.togenableCacheFile4Sbox.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.hyUpMbps, v => v.txtUpMbps.Text).DisposeWith(disposables);