mirror of
https://github.com/2dust/v2rayN.git
synced 2026-07-26 09:52:05 +03:00
Remove NetBridge
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
|||||||
[submodule "v2rayN/GlobalHotKeys"]
|
[submodule "v2rayN/GlobalHotKeys"]
|
||||||
path = v2rayN/GlobalHotKeys
|
path = v2rayN/GlobalHotKeys
|
||||||
url = https://github.com/2dust/GlobalHotKeys
|
url = https://github.com/2dust/GlobalHotKeys
|
||||||
[submodule "v2rayN/NetBridge"]
|
|
||||||
path = v2rayN/NetBridge
|
|
||||||
url = https://github.com/2dust/NetBridge
|
|
||||||
|
|||||||
Submodule v2rayN/NetBridge deleted from e9b16cd187
@@ -161,10 +161,6 @@ public static class ConfigHandler
|
|||||||
config.SystemProxyItem ??= new();
|
config.SystemProxyItem ??= new();
|
||||||
config.WebDavItem ??= new();
|
config.WebDavItem ??= new();
|
||||||
config.CheckUpdateItem ??= new();
|
config.CheckUpdateItem ??= new();
|
||||||
config.NetBridgeItem ??= new()
|
|
||||||
{
|
|
||||||
RuleProcess = string.Empty
|
|
||||||
};
|
|
||||||
config.Fragment4RayItem ??= new()
|
config.Fragment4RayItem ??= new()
|
||||||
{
|
{
|
||||||
Packets = "tlshello",
|
Packets = "tlshello",
|
||||||
|
|||||||
@@ -1,239 +0,0 @@
|
|||||||
using NetBridgeLib.Services;
|
|
||||||
|
|
||||||
namespace ServiceLib.Manager;
|
|
||||||
|
|
||||||
public sealed class NetBridgeManager
|
|
||||||
{
|
|
||||||
private static readonly Lazy<NetBridgeManager> _instance = new(() => new());
|
|
||||||
public static NetBridgeManager Instance => _instance.Value;
|
|
||||||
private readonly Config _config = AppManager.Instance.Config;
|
|
||||||
private NetBridgeService? _netBridgeService;
|
|
||||||
private bool _isProxyRunning;
|
|
||||||
private bool _isInitialized;
|
|
||||||
private List<NetBridgeRuleConfig> _ruleConfigs = [];
|
|
||||||
private Func<bool, string, Task>? _updateFunc;
|
|
||||||
private uint _proxyConfigId;
|
|
||||||
|
|
||||||
public async Task Init(Func<bool, string, Task>? updateFunc = null)
|
|
||||||
{
|
|
||||||
if (_isInitialized)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateFunc = updateFunc;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_netBridgeService = new NetBridgeService();
|
|
||||||
_netBridgeService.LogReceived += msg =>
|
|
||||||
{
|
|
||||||
var message = $"NetBridge Log: {msg}";
|
|
||||||
_ = _updateFunc?.Invoke(false, message);
|
|
||||||
};
|
|
||||||
|
|
||||||
_netBridgeService.ConnectionReceived += (processName, pid, destIp, destPort, proxyInfo) =>
|
|
||||||
{
|
|
||||||
var message = $"NetBridge Connection: {processName} (PID: {pid}) -> {destIp}:{destPort} -> {proxyInfo}";
|
|
||||||
_ = _updateFunc?.Invoke(false, message);
|
|
||||||
};
|
|
||||||
|
|
||||||
_ruleConfigs = BuildRuleConfigs(_config.NetBridgeItem?.RuleProcess);
|
|
||||||
_isInitialized = true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var error = $"Failed to initialize NetBridgeService: {ex.Message}";
|
|
||||||
await _updateFunc?.Invoke(true, error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<bool> Start()
|
|
||||||
{
|
|
||||||
if (_isProxyRunning)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_netBridgeService == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var started = _netBridgeService.Start();
|
|
||||||
if (!started)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_isProxyRunning = true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var error = $"Failed to start NetBridgeService: {ex.Message}";
|
|
||||||
await _updateFunc?.Invoke(true, error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<bool> Stop()
|
|
||||||
{
|
|
||||||
if (!_isProxyRunning)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_netBridgeService == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var stopped = _netBridgeService.Stop();
|
|
||||||
if (!stopped)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_isProxyRunning = false;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var error = $"Failed to stop NetBridgeService: {ex.Message}";
|
|
||||||
await _updateFunc?.Invoke(true, error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<bool> UpdateRoutes(string? ruleProcess)
|
|
||||||
{
|
|
||||||
var newRuleConfigs = BuildRuleConfigs(ruleProcess);
|
|
||||||
|
|
||||||
_ruleConfigs = newRuleConfigs;
|
|
||||||
|
|
||||||
if (!_isProxyRunning)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return await ApplyRoutesInternal();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<bool> UpdateProxyConfig(string proxyHost, int proxyPort)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_netBridgeService == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var proxyType = "SOCKS5";
|
|
||||||
var username = "";
|
|
||||||
var password = "";
|
|
||||||
|
|
||||||
if (_proxyConfigId > 0)
|
|
||||||
{
|
|
||||||
var edited = _netBridgeService.EditProxyConfig(_proxyConfigId, proxyType, proxyHost, (ushort)proxyPort, username, password);
|
|
||||||
if (!edited)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_proxyConfigId = _netBridgeService.AddProxyConfig(proxyType, proxyHost, (ushort)proxyPort, username, password);
|
|
||||||
if (_proxyConfigId == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Task.FromResult(true);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var error = $"Failed to update proxy config: {ex.Message}";
|
|
||||||
await _updateFunc?.Invoke(true, error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<bool> SetDnsViaProxy(bool enable)
|
|
||||||
{
|
|
||||||
if (_netBridgeService == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_netBridgeService.SetDnsViaProxy(enable);
|
|
||||||
|
|
||||||
return await Task.FromResult(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<bool> ApplyRoutesInternal()
|
|
||||||
{
|
|
||||||
if (_netBridgeService == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<NetBridgeRuleConfig> rules;
|
|
||||||
|
|
||||||
rules = _ruleConfigs.Select(JsonUtils.DeepCopy).ToList();
|
|
||||||
|
|
||||||
foreach (var rule in rules.Where(x => x.RuleId > 0))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_ = _netBridgeService.DeleteRule(rule.RuleId);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < rules.Count; i++)
|
|
||||||
{
|
|
||||||
var rule = rules[i];
|
|
||||||
var newRuleId = _netBridgeService.AddRule(rule.ProcessName, rule.TargetHosts, rule.TargetPorts, rule.Protocol, rule.Action, rule.ProxyConfigId);
|
|
||||||
if (newRuleId == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
rules[i].RuleId = newRuleId;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ruleConfigs = rules;
|
|
||||||
|
|
||||||
return await Task.FromResult(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<NetBridgeRuleConfig> BuildRuleConfigs(string? ruleProcess)
|
|
||||||
{
|
|
||||||
if (ruleProcess.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
return new();
|
|
||||||
}
|
|
||||||
|
|
||||||
var processNames = Utils.String2List(Utils.Convert2Comma(ruleProcess));
|
|
||||||
return processNames.Select(processName => new NetBridgeRuleConfig
|
|
||||||
{
|
|
||||||
ProcessName = processName,
|
|
||||||
TargetHosts = "*",
|
|
||||||
TargetPorts = "*",
|
|
||||||
Protocol = "BOTH",
|
|
||||||
Action = "PROXY",
|
|
||||||
ProxyConfigId = 0
|
|
||||||
}).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -29,7 +29,6 @@ public class Config
|
|||||||
public SystemProxyItem SystemProxyItem { get; set; }
|
public SystemProxyItem SystemProxyItem { get; set; }
|
||||||
public WebDavItem WebDavItem { get; set; }
|
public WebDavItem WebDavItem { get; set; }
|
||||||
public CheckUpdateItem CheckUpdateItem { get; set; }
|
public CheckUpdateItem CheckUpdateItem { get; set; }
|
||||||
public NetBridgeItem NetBridgeItem { get; set; }
|
|
||||||
public Fragment4RayItem? Fragment4RayItem { get; set; }
|
public Fragment4RayItem? Fragment4RayItem { get; set; }
|
||||||
public List<InItem> Inbound { get; set; }
|
public List<InItem> Inbound { get; set; }
|
||||||
public List<KeyEventItem> GlobalHotkeys { get; set; }
|
public List<KeyEventItem> GlobalHotkeys { get; set; }
|
||||||
|
|||||||
@@ -278,10 +278,3 @@ public class SimpleDNSItem
|
|||||||
public string? Hosts { get; set; }
|
public string? Hosts { get; set; }
|
||||||
public string? DirectExpectedIPs { get; set; }
|
public string? DirectExpectedIPs { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class NetBridgeItem
|
|
||||||
{
|
|
||||||
public string? RuleProcess { get; set; }
|
|
||||||
public bool EnableDnsViaProxy { get; set; }
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
namespace ServiceLib.Models.Dto;
|
|
||||||
|
|
||||||
public sealed class NetBridgeRuleConfig
|
|
||||||
{
|
|
||||||
public uint RuleId { get; set; }
|
|
||||||
public string ProcessName { get; set; }
|
|
||||||
public string TargetHosts { get; set; }
|
|
||||||
public string TargetPorts { get; set; }
|
|
||||||
public string Protocol { get; set; }
|
|
||||||
public string Action { get; set; }
|
|
||||||
public uint ProxyConfigId { get; set; }
|
|
||||||
}
|
|
||||||
36
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
36
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
@@ -1329,15 +1329,6 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查找类似 Process traffic hijacking (experimental) 的本地化字符串。
|
|
||||||
/// </summary>
|
|
||||||
public static string menuNetBridge {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("menuNetBridge", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 New Update 的本地化字符串。
|
/// 查找类似 New Update 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -2328,15 +2319,6 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查找类似 The process names that need to be proxied; separate multiple processes with commas. Processes not in the list will also be hijacked, but will connect directly. 的本地化字符串。
|
|
||||||
/// </summary>
|
|
||||||
public static string NetBridgeRuleTips {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("NetBridgeRuleTips", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Non-VMess or SS protocol 的本地化字符串。
|
/// 查找类似 Non-VMess or SS protocol 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -3069,15 +3051,6 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查找类似 Enables process traffic hijacking (experimental), similar to Proxifer; can coexist with system proxy; conflicts with TUN mode, please do not enable them simultaneously;please allow v2rayN to use a private network in your firewall. 的本地化字符串。
|
|
||||||
/// </summary>
|
|
||||||
public static string TbEnableNetBridge {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("TbEnableNetBridge", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 DNS via Bridge 的本地化字符串。
|
/// 查找类似 DNS via Bridge 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -3753,15 +3726,6 @@ namespace ServiceLib.Resx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查找类似 Save rules 的本地化字符串。
|
|
||||||
/// </summary>
|
|
||||||
public static string TbSaveNetBridgeRule {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("TbSaveNetBridgeRule", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 sing-box Full Config Template 的本地化字符串。
|
/// 查找类似 sing-box Full Config Template 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1794,21 +1794,9 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
|||||||
<data name="TbEnableFinalFragmentTip" xml:space="preserve">
|
<data name="TbEnableFinalFragmentTip" xml:space="preserve">
|
||||||
<value>Split the tail of packets into smaller fragments. This may affect throughput and latency.</value>
|
<value>Split the tail of packets into smaller fragments. This may affect throughput and latency.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbEnableNetBridge" xml:space="preserve">
|
|
||||||
<value>Enables process traffic hijacking (experimental), similar to Proxifer; can coexist with system proxy; conflicts with TUN mode, please do not enable them simultaneously;please allow v2rayN to use a private network in your firewall.</value>
|
|
||||||
</data>
|
|
||||||
<data name="NetBridgeRuleTips" xml:space="preserve">
|
|
||||||
<value>The process names that need to be proxied; separate multiple processes with commas. Processes not in the list will also be hijacked, but will connect directly.</value>
|
|
||||||
</data>
|
|
||||||
<data name="menuNetBridge" xml:space="preserve">
|
|
||||||
<value>Process traffic hijacking (experimental)</value>
|
|
||||||
</data>
|
|
||||||
<data name="TbEnabletDnsViaProxy" xml:space="preserve">
|
<data name="TbEnabletDnsViaProxy" xml:space="preserve">
|
||||||
<value>DNS via Bridge</value>
|
<value>DNS via Bridge</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSaveNetBridgeRule" xml:space="preserve">
|
|
||||||
<value>Save rules</value>
|
|
||||||
</data>
|
|
||||||
<data name="MsgInsecureConfiguration" xml:space="preserve">
|
<data name="MsgInsecureConfiguration" xml:space="preserve">
|
||||||
<value>Insecure configuration detected: AllowInsecure is enabled but no certificate is provided. This may cause MITM attacks.</value>
|
<value>Insecure configuration detected: AllowInsecure is enabled but no certificate is provided. This may cause MITM attacks.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -1791,21 +1791,9 @@
|
|||||||
<data name="TbEnableFinalFragmentTip" xml:space="preserve">
|
<data name="TbEnableFinalFragmentTip" xml:space="preserve">
|
||||||
<value>将数据包末端拆分为更小片段发送,可能影响吞吐与延迟。</value>
|
<value>将数据包末端拆分为更小片段发送,可能影响吞吐与延迟。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbEnableNetBridge" xml:space="preserve">
|
|
||||||
<value>启用进程流量劫持(实验性),类似 Proxifer 功能;可以和系统代理并存;和 TUN 模式冲突,请不要同时开启;请在防火墙中允许 v2rayN 使用专用网络</value>
|
|
||||||
</data>
|
|
||||||
<data name="NetBridgeRuleTips" xml:space="preserve">
|
|
||||||
<value>需要代理的进程名,多个进程请用逗号分隔;不在列表中的进程也会被劫持,但是会直连</value>
|
|
||||||
</data>
|
|
||||||
<data name="menuNetBridge" xml:space="preserve">
|
|
||||||
<value>进程流量劫持(实验性)</value>
|
|
||||||
</data>
|
|
||||||
<data name="TbEnabletDnsViaProxy" xml:space="preserve">
|
<data name="TbEnabletDnsViaProxy" xml:space="preserve">
|
||||||
<value>DNS 通过 Bridge</value>
|
<value>DNS 通过 Bridge</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSaveNetBridgeRule" xml:space="preserve">
|
|
||||||
<value>保存规则</value>
|
|
||||||
</data>
|
|
||||||
<data name="MsgInsecureConfiguration" xml:space="preserve">
|
<data name="MsgInsecureConfiguration" xml:space="preserve">
|
||||||
<value>检测到不安全配置:AllowInsecure 已启用,但未提供证书。这可能会导致中间人攻击。</value>
|
<value>检测到不安全配置:AllowInsecure 已启用,但未提供证书。这可能会导致中间人攻击。</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -1791,19 +1791,7 @@
|
|||||||
<data name="TbEnableFinalFragmentTip" xml:space="preserve">
|
<data name="TbEnableFinalFragmentTip" xml:space="preserve">
|
||||||
<value>將封包末端拆分為更小的片段進行傳送,可能會影響吞吐量與延遲</value>
|
<value>將封包末端拆分為更小的片段進行傳送,可能會影響吞吐量與延遲</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbEnableNetBridge" xml:space="preserve">
|
|
||||||
<value>啟用進程流量劫持(實驗性),類似 Proxifer 功能;可以和系統代理並存;和 TUN 模式衝突,請不要同時開啟;請在防火牆中允許 v2rayN 使用專用網絡</value>
|
|
||||||
</data>
|
|
||||||
<data name="NetBridgeRuleTips" xml:space="preserve">
|
|
||||||
<value>需要代理程式的進程名,多個進程請用逗號分隔;不在清單中的進程也會被劫持,但是會直連</value>
|
|
||||||
</data>
|
|
||||||
<data name="menuNetBridge" xml:space="preserve">
|
|
||||||
<value>進程流量劫持(實驗性)</value>
|
|
||||||
</data>
|
|
||||||
<data name="TbEnabletDnsViaProxy" xml:space="preserve">
|
<data name="TbEnabletDnsViaProxy" xml:space="preserve">
|
||||||
<value>DNS 透過 Bridge</value>
|
<value>DNS 透過 Bridge</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSaveNetBridgeRule" xml:space="preserve">
|
|
||||||
<value>保存規則</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
</root>
|
||||||
@@ -90,7 +90,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\NetBridge\src\NetBridgeLib\NetBridgeLib.csproj" />
|
|
||||||
<ProjectReference Include="..\ServiceLib.UdpTest\ServiceLib.UdpTest.csproj" />
|
<ProjectReference Include="..\ServiceLib.UdpTest\ServiceLib.UdpTest.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
namespace ServiceLib.ViewModels;
|
|
||||||
|
|
||||||
public class NetBridgeViewModel : MyReactiveObject
|
|
||||||
{
|
|
||||||
[Reactive]
|
|
||||||
public bool EnableNetBridge { get; set; }
|
|
||||||
|
|
||||||
[Reactive]
|
|
||||||
public bool EnabletDnsViaProxy { get; set; }
|
|
||||||
|
|
||||||
[Reactive]
|
|
||||||
public string RuleProcess { get; set; }
|
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> SaveRulesCmd { get; }
|
|
||||||
|
|
||||||
public NetBridgeViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
|
||||||
{
|
|
||||||
_config = AppManager.Instance.Config;
|
|
||||||
_updateView = updateView;
|
|
||||||
|
|
||||||
SaveRulesCmd = ReactiveCommand.CreateFromTask(async () =>
|
|
||||||
{
|
|
||||||
await SaveRulesAsync();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.WhenAnyValue(x => x.EnableNetBridge)
|
|
||||||
.Skip(1)
|
|
||||||
.Subscribe(async enabled =>
|
|
||||||
{
|
|
||||||
await ToggleNetBridgeAsync(enabled);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.WhenAnyValue(x => x.EnabletDnsViaProxy)
|
|
||||||
.Skip(1)
|
|
||||||
.Subscribe(async enabled =>
|
|
||||||
{
|
|
||||||
await ToggleDnsViaProxyAsync(enabled);
|
|
||||||
});
|
|
||||||
|
|
||||||
_ = Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Init()
|
|
||||||
{
|
|
||||||
EnabletDnsViaProxy = _config.NetBridgeItem.EnableDnsViaProxy;
|
|
||||||
|
|
||||||
_config.NetBridgeItem ??= new()
|
|
||||||
{
|
|
||||||
RuleProcess = string.Empty
|
|
||||||
};
|
|
||||||
|
|
||||||
EnableNetBridge = false;
|
|
||||||
if (_config.NetBridgeItem.RuleProcess.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
_config.NetBridgeItem.RuleProcess = "Chrome.exe";
|
|
||||||
}
|
|
||||||
RuleProcess = _config.NetBridgeItem.RuleProcess;
|
|
||||||
|
|
||||||
await Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ToggleNetBridgeAsync(bool enabled)
|
|
||||||
{
|
|
||||||
await NetBridgeManager.Instance.Init(UpdateViewHandler);
|
|
||||||
|
|
||||||
if (enabled)
|
|
||||||
{
|
|
||||||
var succeed = await NetBridgeManager.Instance.Start();
|
|
||||||
if (succeed)
|
|
||||||
{
|
|
||||||
await NetBridgeManager.Instance.UpdateProxyConfig(Global.Loopback, AppManager.Instance.GetLocalPort(EInboundProtocol.socks));
|
|
||||||
await NetBridgeManager.Instance.UpdateRoutes(RuleProcess);
|
|
||||||
await NetBridgeManager.Instance.SetDnsViaProxy(EnabletDnsViaProxy);
|
|
||||||
}
|
|
||||||
NoticeManager.Instance.Enqueue(succeed ? ResUI.OperationSuccess : ResUI.OperationFailed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var succeed = await NetBridgeManager.Instance.Stop();
|
|
||||||
NoticeManager.Instance.Enqueue(succeed ? ResUI.OperationSuccess : ResUI.OperationFailed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ToggleDnsViaProxyAsync(bool enabled)
|
|
||||||
{
|
|
||||||
_config.NetBridgeItem.EnableDnsViaProxy = enabled;
|
|
||||||
|
|
||||||
await NetBridgeManager.Instance.SetDnsViaProxy(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// </summary>
|
|
||||||
private async Task SaveRulesAsync()
|
|
||||||
{
|
|
||||||
_config.NetBridgeItem ??= new();
|
|
||||||
|
|
||||||
var normalizedRuleProcess = RuleProcess;
|
|
||||||
_config.NetBridgeItem.RuleProcess = normalizedRuleProcess;
|
|
||||||
RuleProcess = normalizedRuleProcess;
|
|
||||||
|
|
||||||
if (await ConfigHandler.SaveConfig(_config) != 0)
|
|
||||||
{
|
|
||||||
NoticeManager.Instance.Enqueue(ResUI.OperationFailed);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await NetBridgeManager.Instance.Init(UpdateViewHandler);
|
|
||||||
if (EnableNetBridge)
|
|
||||||
{
|
|
||||||
var routesUpdated = await NetBridgeManager.Instance.UpdateRoutes(normalizedRuleProcess);
|
|
||||||
NoticeManager.Instance.Enqueue(routesUpdated ? ResUI.OperationSuccess : ResUI.OperationFailed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<bool> UpdateViewHandler(bool isError, string msg)
|
|
||||||
{
|
|
||||||
NoticeManager.Instance.SendMessageEx(msg);
|
|
||||||
|
|
||||||
return await Task.FromResult(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -89,7 +89,6 @@
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem x:Name="menuBackupAndRestore" Header="{x:Static resx:ResUI.menuBackupAndRestore}" />
|
<MenuItem x:Name="menuBackupAndRestore" Header="{x:Static resx:ResUI.menuBackupAndRestore}" />
|
||||||
<MenuItem x:Name="menuOpenTheFileLocation" Header="{x:Static resx:ResUI.menuOpenTheFileLocation}" />
|
<MenuItem x:Name="menuOpenTheFileLocation" Header="{x:Static resx:ResUI.menuOpenTheFileLocation}" />
|
||||||
<MenuItem x:Name="menuNetBridge" Header="{x:Static resx:ResUI.menuNetBridge}" />
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
<MenuItem x:Name="menuHelp" Header="{x:Static resx:ResUI.menuHelp}">
|
<MenuItem x:Name="menuHelp" Header="{x:Static resx:ResUI.menuHelp}">
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
|||||||
private readonly WindowNotificationManager? _manager;
|
private readonly WindowNotificationManager? _manager;
|
||||||
private CheckUpdateView? _checkUpdateView;
|
private CheckUpdateView? _checkUpdateView;
|
||||||
private BackupAndRestoreView? _backupAndRestoreView;
|
private BackupAndRestoreView? _backupAndRestoreView;
|
||||||
private NetBridgeView? _netBridgeView;
|
|
||||||
private bool _blCloseByUser = false;
|
private bool _blCloseByUser = false;
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
@@ -29,7 +28,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
|||||||
btnNewUpdate.Click += MenuCheckUpdate_Click;
|
btnNewUpdate.Click += MenuCheckUpdate_Click;
|
||||||
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
||||||
menuClose.Click += MenuClose_Click;
|
menuClose.Click += MenuClose_Click;
|
||||||
menuNetBridge.Click += MenuNetBridge_Click;
|
|
||||||
|
|
||||||
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
@@ -167,7 +165,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
|||||||
{
|
{
|
||||||
Title = $"{Utils.GetVersion()}";
|
Title = $"{Utils.GetVersion()}";
|
||||||
menuAddServerViaScan.IsVisible = false;
|
menuAddServerViaScan.IsVisible = false;
|
||||||
menuNetBridge.IsVisible = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_config.UiItem.AutoHideStartup && Utils.IsWindows())
|
if (_config.UiItem.AutoHideStartup && Utils.IsWindows())
|
||||||
@@ -382,19 +379,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
|||||||
DialogHost.Show(_backupAndRestoreView);
|
DialogHost.Show(_backupAndRestoreView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MenuNetBridge_Click(object? sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
if (Utils.IsAdministrator())
|
|
||||||
{
|
|
||||||
_netBridgeView ??= new NetBridgeView();
|
|
||||||
DialogHost.Show(_netBridgeView);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NoticeManager.Instance.SendMessageAndEnqueue(ResUI.RunAsAdmin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void MenuClose_Click(object? sender, RoutedEventArgs e)
|
private async void MenuClose_Click(object? sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (await UI.ShowYesNo(this, ResUI.menuExitTips) != ButtonResult.Yes)
|
if (await UI.ShowYesNo(this, ResUI.menuExitTips) != ButtonResult.Yes)
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
<UserControl
|
|
||||||
x:Class="v2rayN.Desktop.Views.NetBridgeView"
|
|
||||||
xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
|
||||||
d:DesignHeight="400"
|
|
||||||
d:DesignWidth="600"
|
|
||||||
x:DataType="vms:NetBridgeViewModel"
|
|
||||||
mc:Ignorable="d">
|
|
||||||
<Border
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Theme="{DynamicResource CardBorder}">
|
|
||||||
|
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
|
||||||
<StackPanel
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
DockPanel.Dock="Top"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
|
|
||||||
<ToggleSwitch
|
|
||||||
x:Name="togEnableNetBridge"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
HorizontalAlignment="Left" />
|
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Width="500"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{x:Static resx:ResUI.TbEnableNetBridge}"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<StackPanel
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
DockPanel.Dock="Top"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
|
|
||||||
<ToggleSwitch
|
|
||||||
x:Name="togEnabletDnsViaProxy"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
HorizontalAlignment="Left" />
|
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Width="500"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{x:Static resx:ResUI.TbEnabletDnsViaProxy}"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
|
|
||||||
<DockPanel>
|
|
||||||
<StackPanel
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
DockPanel.Dock="Top"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Width="500"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{x:Static resx:ResUI.NetBridgeRuleTips}"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<StackPanel
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
DockPanel.Dock="Bottom"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
x:Name="btnSave"
|
|
||||||
Width="100"
|
|
||||||
Content="{x:Static resx:ResUI.TbSaveNetBridgeRule}"
|
|
||||||
IsDefault="True" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<TextBox
|
|
||||||
x:Name="txtRuleProcess"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
AcceptsReturn="True"
|
|
||||||
BorderThickness="1"
|
|
||||||
Classes="TextArea"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</DockPanel>
|
|
||||||
</DockPanel>
|
|
||||||
</Border>
|
|
||||||
</UserControl>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
namespace v2rayN.Desktop.Views;
|
|
||||||
|
|
||||||
public partial class NetBridgeView : ReactiveUserControl<NetBridgeViewModel>
|
|
||||||
{
|
|
||||||
public NetBridgeView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
ViewModel = new NetBridgeViewModel(UpdateViewHandler);
|
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
|
||||||
{
|
|
||||||
this.BindCommand(ViewModel, vm => vm.SaveRulesCmd, v => v.btnSave).DisposeWith(disposables);
|
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.EnableNetBridge, v => v.togEnableNetBridge.IsChecked).DisposeWith(disposables);
|
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.RuleProcess, v => v.txtRuleProcess.Text).DisposeWith(disposables);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
|
||||||
{
|
|
||||||
return await Task.FromResult(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -35,8 +35,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceLib.Tests", "Service
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceLib.UdpTest", "ServiceLib.UdpTest\ServiceLib.UdpTest.csproj", "{CE9D9298-0289-4718-2522-B236489F2912}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceLib.UdpTest", "ServiceLib.UdpTest\ServiceLib.UdpTest.csproj", "{CE9D9298-0289-4718-2522-B236489F2912}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetBridgeLib", "NetBridge\src\NetBridgeLib\NetBridgeLib.csproj", "{4AF81950-DD4E-A636-6BD5-B4A7839D87B0}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -71,10 +69,6 @@ Global
|
|||||||
{CE9D9298-0289-4718-2522-B236489F2912}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{CE9D9298-0289-4718-2522-B236489F2912}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{CE9D9298-0289-4718-2522-B236489F2912}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{CE9D9298-0289-4718-2522-B236489F2912}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{CE9D9298-0289-4718-2522-B236489F2912}.Release|Any CPU.Build.0 = Release|Any CPU
|
{CE9D9298-0289-4718-2522-B236489F2912}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{4AF81950-DD4E-A636-6BD5-B4A7839D87B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4AF81950-DD4E-A636-6BD5-B4A7839D87B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4AF81950-DD4E-A636-6BD5-B4A7839D87B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4AF81950-DD4E-A636-6BD5-B4A7839D87B0}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
</Folder>
|
</Folder>
|
||||||
<Project Path="AmazTool/AmazTool.csproj" />
|
<Project Path="AmazTool/AmazTool.csproj" />
|
||||||
<Project Path="GlobalHotKeys/src/GlobalHotKeys/GlobalHotKeys.csproj" />
|
<Project Path="GlobalHotKeys/src/GlobalHotKeys/GlobalHotKeys.csproj" />
|
||||||
<Project Path="NetBridge/src/NetBridgeLib/NetBridgeLib.csproj" />
|
|
||||||
<Project Path="ServiceLib.Tests/ServiceLib.Tests.csproj" />
|
<Project Path="ServiceLib.Tests/ServiceLib.Tests.csproj" />
|
||||||
<Project Path="ServiceLib.UdpTest/ServiceLib.UdpTest.csproj" Id="77930428-4dc4-4130-9031-6b9e714f5d20" />
|
<Project Path="ServiceLib.UdpTest/ServiceLib.UdpTest.csproj" Id="77930428-4dc4-4130-9031-6b9e714f5d20" />
|
||||||
<Project Path="ServiceLib/ServiceLib.csproj" />
|
<Project Path="ServiceLib/ServiceLib.csproj" />
|
||||||
|
|||||||
@@ -233,10 +233,6 @@
|
|||||||
x:Name="menuOpenTheFileLocation"
|
x:Name="menuOpenTheFileLocation"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuOpenTheFileLocation}" />
|
Header="{x:Static resx:ResUI.menuOpenTheFileLocation}" />
|
||||||
<MenuItem
|
|
||||||
x:Name="menuNetBridge"
|
|
||||||
Height="{StaticResource MenuItemHeight}"
|
|
||||||
Header="{x:Static resx:ResUI.menuNetBridge}" />
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ public partial class MainWindow
|
|||||||
private static Config _config;
|
private static Config _config;
|
||||||
private CheckUpdateView? _checkUpdateView;
|
private CheckUpdateView? _checkUpdateView;
|
||||||
private BackupAndRestoreView? _backupAndRestoreView;
|
private BackupAndRestoreView? _backupAndRestoreView;
|
||||||
private NetBridgeView? _netBridgeView;
|
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
@@ -28,7 +27,6 @@ public partial class MainWindow
|
|||||||
menuCheckUpdate.Click += MenuCheckUpdate_Click;
|
menuCheckUpdate.Click += MenuCheckUpdate_Click;
|
||||||
btnNewUpdate.Click += MenuCheckUpdate_Click;
|
btnNewUpdate.Click += MenuCheckUpdate_Click;
|
||||||
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
||||||
menuNetBridge.Click += MenuNetBridge_Click;
|
|
||||||
|
|
||||||
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
@@ -378,19 +376,6 @@ public partial class MainWindow
|
|||||||
DialogHost.Show(_backupAndRestoreView, "RootDialog");
|
DialogHost.Show(_backupAndRestoreView, "RootDialog");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MenuNetBridge_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
if (Utils.IsAdministrator())
|
|
||||||
{
|
|
||||||
_netBridgeView ??= new NetBridgeView();
|
|
||||||
DialogHost.Show(_netBridgeView, "RootDialog");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NoticeManager.Instance.SendMessageAndEnqueue(ResUI.RunAsAdmin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Event
|
#endregion Event
|
||||||
|
|
||||||
#region UI
|
#region UI
|
||||||
|
|||||||
@@ -1,98 +0,0 @@
|
|||||||
<reactiveui:ReactiveUserControl
|
|
||||||
x:Class="v2rayN.Views.NetBridgeView"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:converters="clr-namespace:v2rayN.Converters"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
|
||||||
Height="400"
|
|
||||||
d:DesignHeight="400"
|
|
||||||
d:DesignWidth="600"
|
|
||||||
x:TypeArguments="vms:NetBridgeViewModel"
|
|
||||||
Style="{StaticResource ViewGlobal}"
|
|
||||||
mc:Ignorable="d">
|
|
||||||
<DockPanel Margin="{StaticResource Margin8}">
|
|
||||||
<StackPanel
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
DockPanel.Dock="Top"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
|
|
||||||
<ToggleButton
|
|
||||||
x:Name="togEnableNetBridge"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
HorizontalAlignment="Left" />
|
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Width="500"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
|
||||||
Text="{x:Static resx:ResUI.TbEnableNetBridge}"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<StackPanel
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
DockPanel.Dock="Top"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
|
|
||||||
<ToggleButton
|
|
||||||
x:Name="togEnabletDnsViaProxy"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
HorizontalAlignment="Left" />
|
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Width="500"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
|
||||||
Text="{x:Static resx:ResUI.TbEnabletDnsViaProxy}"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<DockPanel>
|
|
||||||
<StackPanel
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
DockPanel.Dock="Top"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Width="500"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Style="{StaticResource ToolbarTextBlock}"
|
|
||||||
Text="{x:Static resx:ResUI.NetBridgeRuleTips}"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<StackPanel
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
DockPanel.Dock="Bottom"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
x:Name="btnSave"
|
|
||||||
Width="100"
|
|
||||||
Content="{x:Static resx:ResUI.TbSaveNetBridgeRule}"
|
|
||||||
IsDefault="True"
|
|
||||||
Style="{StaticResource DefButton}" />
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<TextBox
|
|
||||||
x:Name="txtRuleProcess"
|
|
||||||
Margin="{StaticResource Margin8}"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
AcceptsReturn="True"
|
|
||||||
BorderThickness="1"
|
|
||||||
Style="{StaticResource DefTextBox}"
|
|
||||||
TextWrapping="Wrap"
|
|
||||||
VerticalScrollBarVisibility="Auto" />
|
|
||||||
|
|
||||||
</DockPanel>
|
|
||||||
</DockPanel>
|
|
||||||
</reactiveui:ReactiveUserControl>
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
namespace v2rayN.Views;
|
|
||||||
|
|
||||||
public partial class NetBridgeView
|
|
||||||
{
|
|
||||||
public NetBridgeView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
ViewModel = new NetBridgeViewModel(UpdateViewHandler);
|
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
|
||||||
{
|
|
||||||
this.BindCommand(ViewModel, vm => vm.SaveRulesCmd, v => v.btnSave).DisposeWith(disposables);
|
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.EnableNetBridge, v => v.togEnableNetBridge.IsChecked).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.EnabletDnsViaProxy, v => v.togEnabletDnsViaProxy.IsChecked).DisposeWith(disposables);
|
|
||||||
this.Bind(ViewModel, vm => vm.RuleProcess, v => v.txtRuleProcess.Text).DisposeWith(disposables);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
|
||||||
{
|
|
||||||
return await Task.FromResult(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user