Merge pull request #163 from j4587698/main

添加PAC模式
This commit is contained in:
2dust
2022-11-02 14:35:52 +08:00
committed by GitHub
16 changed files with 6204 additions and 5 deletions

View File

@@ -67,6 +67,11 @@ namespace clashN.Handler
config.APIPort = 9090;
}
if (config.PacPort == 0)
{
config.PacPort = 7990;
}
if (config.profileItems == null)
{
config.profileItems = new List<ProfileItem>();

View File

@@ -0,0 +1,78 @@
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Windows;
using clashN.Mode;
using clashN.Properties;
using static System.Net.WebRequestMethods;
using File = System.IO.File;
namespace clashN.Handler;
public class HttpHandler
{
private static TcpListener _tcpListener;
private static string _pacText;
private static bool _isRunning;
public static void Start(Config config)
{
var path = Path.Combine(Utils.GetConfigPath(), "pac.txt");
if (!File.Exists(path))
{
File.AppendAllText(path, Resources.ResourceManager.GetString("pac"));
}
_pacText = File.ReadAllText(path).Replace("__PROXY__", $"PROXY 127.0.0.1:{config.httpPort};DIRECT;");
Stop();
_tcpListener = TcpListener.Create(config.PacPort);
_isRunning = true;
_tcpListener.Start();
Task.Factory.StartNew(() =>
{
while (_isRunning)
{
try
{
var client = _tcpListener.AcceptTcpClient();
Task.Factory.StartNew(() =>
{
var stream = client.GetStream();
var sb = new StringBuilder();
sb.AppendLine("HTTP/1.0 200 OK");
sb.AppendLine("Content-type:text/plain;charset=UTF-8");
sb.AppendLine("Connection:close");
sb.AppendLine("Content-Length:" + Encoding.UTF8.GetByteCount(_pacText));
sb.AppendLine();
sb.Append(_pacText);
var content = Encoding.UTF8.GetBytes(sb.ToString());
stream.Write(content, 0, content.Length);
stream.Flush();
});
}
catch (Exception e)
{
}
}
});
}
public static void Stop()
{
if (_tcpListener != null)
{
try
{
_isRunning = false;
_tcpListener.Stop();
}
catch (Exception e)
{
}
}
}
}

View File

@@ -75,6 +75,17 @@ namespace clashN.Handler
else if (type == ESysProxyType.Unchanged)
{
}
else if (type == ESysProxyType.Pac)
{
HttpHandler.Start(config);
var strProxy = $"http://127.0.0.1:{config.PacPort}/";
SetIEProxy(false, strProxy, "");
}
if (type != ESysProxyType.Pac)
{
HttpHandler.Stop();
}
}
catch (Exception ex)
{

View File

@@ -45,6 +45,11 @@ namespace clashN.Mode
public bool enableMixinContent { get; set; }
/// <summary>
/// Pac监听端口
/// </summary>
public int PacPort { get; set; }
#endregion
#region other entities

View File

@@ -5,6 +5,7 @@ namespace clashN.Mode
{
ForcedClear = 0,
ForcedChange = 1,
Unchanged = 2
Unchanged = 2,
Pac = 3
}
}

View File

@@ -133,4 +133,7 @@
<data name="NotifyIcon3" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\NotifyIcon3.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="pac" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\pac.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;gb2312</value>
</data>
</root>

File diff suppressed because it is too large Load Diff

View File

@@ -537,6 +537,15 @@ namespace clashN.Resx {
}
}
/// <summary>
/// 查找类似 Pac Mode 的本地化字符串。
/// </summary>
public static string menuSystemProxyPac {
get {
return ResourceManager.GetString("menuSystemProxyPac", resourceCulture);
}
}
/// <summary>
/// 查找类似 Set system proxy 的本地化字符串。
/// </summary>
@@ -1420,6 +1429,15 @@ namespace clashN.Resx {
}
}
/// <summary>
/// 查找类似 Pac listen port 的本地化字符串。
/// </summary>
public static string TbSettingsPacListenPort {
get {
return ResourceManager.GetString("TbSettingsPacListenPort", resourceCulture);
}
}
/// <summary>
/// 查找类似 After modifying the following parameters, click Save to take effect 的本地化字符串。
/// </summary>

View File

@@ -640,4 +640,10 @@
<data name="TbSortingDefault" xml:space="preserve">
<value>Default</value>
</data>
<data name="menuSystemProxyPac" xml:space="preserve">
<value>Pac Mode</value>
</data>
<data name="TbSettingsPacListenPort" xml:space="preserve">
<value>Pac listen port</value>
</data>
</root>

View File

@@ -640,4 +640,13 @@
<data name="TbSortingDefault" xml:space="preserve">
<value>默认</value>
</data>
<data name="menuSystemProxyPac" xml:space="preserve">
<value>Pac模式</value>
</data>
<data name="pacListenPort" xml:space="preserve">
<value>Pac监听端口号</value>
</data>
<data name="TbSettingsPacListenPort" xml:space="preserve">
<value>Pac监听端口号</value>
</data>
</root>

View File

@@ -51,9 +51,13 @@ namespace clashN.ViewModels
public bool BlSystemProxySet { get; set; }
[Reactive]
public bool BlSystemProxyNothing { get; set; }
[Reactive]
public bool BlSystemProxyPac { get; set; }
public ReactiveCommand<Unit, Unit> SystemProxyClearCmd { get; }
public ReactiveCommand<Unit, Unit> SystemProxySetCmd { get; }
public ReactiveCommand<Unit, Unit> SystemProxyNothingCmd { get; }
public ReactiveCommand<Unit, Unit> SystemProxyPacCmd { get; }
#endregion
#region Rule mode
@@ -129,6 +133,10 @@ namespace clashN.ViewModels
{
SetListenerType(ESysProxyType.Unchanged);
});//, this.WhenAnyValue(x => x.BlSystemProxyNothing, y => !y));
SystemProxyPacCmd = ReactiveCommand.Create(() =>
{
SetListenerType(ESysProxyType.Pac);
});//, this.WhenAnyValue(x => x.BlSystemProxyNothing, y => !y));
//Rule mode
ModeRuleCmd = ReactiveCommand.Create(() =>
@@ -368,6 +376,7 @@ namespace clashN.ViewModels
BlSystemProxyClear = (type == ESysProxyType.ForcedClear);
BlSystemProxySet = (type == ESysProxyType.ForcedChange);
BlSystemProxyNothing = (type == ESysProxyType.Unchanged);
BlSystemProxyPac = (type == ESysProxyType.Pac);
_noticeHandler?.SendMessage($"Change system proxy", true);

View File

@@ -56,6 +56,8 @@ namespace clashN.ViewModels
public string SubConvertUrl { get; set; }
public ReactiveCommand<Unit, Unit> SetLoopbackCmd { get; }
public ReactiveCommand<Unit, Unit> SetGlobalHotkeyCmd { get; }
[Reactive]
public int PacListenPort { get; set; }
#endregion
#region System proxy
@@ -107,6 +109,7 @@ namespace clashN.ViewModels
autoUpdateSubInterval = _config.autoUpdateSubInterval;
autoDelayTestInterval = _config.autoDelayTestInterval;
SubConvertUrl = _config.constItem.subConvertUrl;
PacListenPort = _config.PacPort;
SetLoopbackCmd = ReactiveCommand.Create(() =>
{
Utils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
@@ -202,6 +205,7 @@ namespace clashN.ViewModels
_config.autoUpdateSubInterval = autoUpdateSubInterval;
_config.autoDelayTestInterval = autoDelayTestInterval;
_config.constItem.subConvertUrl = SubConvertUrl;
_config.PacPort = PacListenPort;
//System proxy
_config.systemProxyExceptions = systemProxyExceptions;

View File

@@ -242,6 +242,17 @@
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem x:Name="menuSystemProxyPac">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon
x:Name="menuSystemProxyPac2"
Margin="0,0,8,0"
Kind="Check" />
<TextBlock Text="{x:Static resx:ResUI.menuSystemProxyPac}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<Separator />
<MenuItem x:Name="menuModeRule">

View File

@@ -39,8 +39,10 @@ namespace clashN.Views
this.OneWayBind(ViewModel, vm => vm.BlSystemProxyClear, v => v.menuSystemProxyClear2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.BlSystemProxySet, v => v.menuSystemProxySet2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.BlSystemProxyNothing, v => v.menuSystemProxyNothing2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.BlSystemProxyPac, v => v.menuSystemProxyPac2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SystemProxyClearCmd, v => v.menuSystemProxyClear).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SystemProxySetCmd, v => v.menuSystemProxySet).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SystemProxyPacCmd, v => v.menuSystemProxyPac).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SystemProxyNothingCmd, v => v.menuSystemProxyNothing).DisposeWith(disposables);

View File

@@ -44,6 +44,7 @@
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyNothing}" />
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyPac}" />
</ComboBox>
<Separator />
<TextBlock

View File

@@ -221,6 +221,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@@ -303,17 +304,29 @@
Grid.Column="1"
Width="300"
Margin="8" />
<TextBlock
Grid.Row="8"
Grid.Column="0"
Margin="8"
VerticalAlignment="Center"
Style="{StaticResource ListItemTitle}"
Text="{x:Static resx:ResUI.TbSettingsPacListenPort}" />
<TextBox
x:Name="txtPacPort"
Grid.Row="8"
Grid.Column="1"
Width="300"
Margin="8" />
<TextBlock
Grid.Row="9"
Grid.Column="0"
Margin="8"
VerticalAlignment="Center"
Style="{StaticResource ListItemTitle}"
Text="{x:Static resx:ResUI.TbSettingsSubConvert}" />
<ComboBox
x:Name="cmbSubConvertUrl"
Grid.Row="8"
Grid.Row="9"
Grid.Column="1"
Width="300"
Margin="8"
@@ -322,14 +335,14 @@
<Button
x:Name="btnSetLoopback"
Grid.Row="9"
Grid.Row="10"
Grid.Column="0"
Margin="8"
Content="{x:Static resx:ResUI.TbSettingsSetUWP}"
Style="{StaticResource DefButton}" />
<Button
x:Name="btnSetGlobalHotkey"
Grid.Row="10"
Grid.Row="11"
Grid.Column="0"
Margin="8"
Content="{x:Static resx:ResUI.TbGlobalHotkeySetting}"