改了一堆屎山代码
This commit is contained in:
24
README.md
24
README.md
@@ -1,4 +1,4 @@
|
|||||||
# clashN
|
# ClashN
|
||||||
A clash client for Windows, supports [Clash core](https://github.com/Dreamacro/clash) and [Clash.Meta core](https://github.com/MetaCubeX/Clash.Meta)
|
A clash client for Windows, supports [Clash core](https://github.com/Dreamacro/clash) and [Clash.Meta core](https://github.com/MetaCubeX/Clash.Meta)
|
||||||
|
|
||||||
[](https://github.com/2dust/clashn/commits/master)
|
[](https://github.com/2dust/clashn/commits/master)
|
||||||
@@ -6,14 +6,30 @@ A clash client for Windows, supports [Clash core](https://github.com/Dreamacro/c
|
|||||||
|
|
||||||
|
|
||||||
### How to use
|
### How to use
|
||||||
- Please download clashN.zip from [releases](https://github.com/2dust/clashN/releases)
|
1. Download `clashN.zip` from [releases](https://github.com/2dust/clashN/releases)
|
||||||
- Unzip to folder
|
2. Unzip to any folder you want
|
||||||
- Run clashN.exe
|
3. Run ClashN.exe
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Tips
|
||||||
|
|
||||||
|
- You can also add `v2ray` subscription to `ClashN`, just enable `Subcription conversion` when you add a profile.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
- Microsoft [.NET 6.0 Desktop Runtime](https://dotnet.microsoft.com/zh-cn/download/dotnet/6.0/runtime) (or download this file directly: [windowsdesktop-runtime-6.0.9-win-x64.exe](https://download.visualstudio.microsoft.com/download/pr/fe8415d4-8a35-4af9-80a5-51306a96282d/05f9b2a1b4884238e69468e49b3a5453/windowsdesktop-runtime-6.0.9-win-x64.exe))
|
- Microsoft [.NET 6.0 Desktop Runtime](https://dotnet.microsoft.com/zh-cn/download/dotnet/6.0/runtime) (or download this file directly: [windowsdesktop-runtime-6.0.9-win-x64.exe](https://download.visualstudio.microsoft.com/download/pr/fe8415d4-8a35-4af9-80a5-51306a96282d/05f9b2a1b4884238e69468e49b3a5453/windowsdesktop-runtime-6.0.9-win-x64.exe))
|
||||||
- Clash core [https://github.com/Dreamacro/clash/releases](https://github.com/Dreamacro/clash/releases)
|
- Clash core [https://github.com/Dreamacro/clash/releases](https://github.com/Dreamacro/clash/releases)
|
||||||
- Clash.Meta core [https://github.com/MetaCubeX/Clash.Meta/releases](https://github.com/MetaCubeX/Clash.Meta/releases)
|
- Clash.Meta core [https://github.com/MetaCubeX/Clash.Meta/releases](https://github.com/MetaCubeX/Clash.Meta/releases)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Telegram Channel
|
### Telegram Channel
|
||||||
[github_2dust](https://t.me/github_2dust)
|
[github_2dust](https://t.me/github_2dust)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Contribute
|
||||||
|
|
||||||
|
To build this project, you should clone both '[ClashN](https://github.com/2dust/clashN)' and '[v2rayN]([2dust/v2rayN: A V2Ray client for Windows, support Xray core and v2fly core (github.com)](https://github.com/2dust/v2rayN))' to the same folder
|
||||||
|
|||||||
@@ -11,8 +11,21 @@ namespace ClashN
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
public static EventWaitHandle ProgramStarted;
|
public static EventWaitHandle? ProgramStarted;
|
||||||
private static Config _config;
|
private Config? _config;
|
||||||
|
|
||||||
|
static App()
|
||||||
|
{
|
||||||
|
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, "ProgramStartedEvent", out bool bCreatedNew);
|
||||||
|
if (!bCreatedNew)
|
||||||
|
{
|
||||||
|
ProgramStarted.Set();
|
||||||
|
App.Current.Shutdown();
|
||||||
|
Environment.Exit(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
// Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetCallingAssembly());
|
// Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetCallingAssembly());
|
||||||
@@ -34,14 +47,6 @@ namespace ClashN
|
|||||||
Utils.SetClipboardData(arg);
|
Utils.SetClipboardData(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, "ProgramStartedEvent", out bool bCreatedNew);
|
|
||||||
if (!bCreatedNew)
|
|
||||||
{
|
|
||||||
ProgramStarted.Set();
|
|
||||||
App.Current.Shutdown();
|
|
||||||
Environment.Exit(-1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Global.processJob = new Job();
|
Global.processJob = new Job();
|
||||||
|
|
||||||
Logging.Setup();
|
Logging.Setup();
|
||||||
@@ -58,7 +63,7 @@ namespace ClashN
|
|||||||
|
|
||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
if (ConfigHandler.LoadConfig(ref _config) != 0)
|
if (ConfigProc.LoadConfig(ref _config) != 0)
|
||||||
{
|
{
|
||||||
UI.ShowWarning($"Loading GUI configuration file is abnormal,please restart the application{Environment.NewLine}加载GUI配置文件异常,请重启应用");
|
UI.ShowWarning($"Loading GUI configuration file is abnormal,please restart the application{Environment.NewLine}加载GUI配置文件异常,请重启应用");
|
||||||
Application.Current.Shutdown();
|
Application.Current.Shutdown();
|
||||||
@@ -80,7 +85,7 @@ namespace ClashN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
|
private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.SaveLog("TaskScheduler_UnobservedTaskException", e.Exception);
|
Utils.SaveLog("TaskScheduler_UnobservedTaskException", e.Exception);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,13 @@ namespace ClashN.Base
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private HttpClientHelper() { }
|
private HttpClientHelper()
|
||||||
|
{
|
||||||
|
httpClient = new HttpClient(new HttpClientHandler()
|
||||||
|
{
|
||||||
|
UseCookies = false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -34,26 +40,26 @@ namespace ClashN.Base
|
|||||||
return httpClientHelper;
|
return httpClientHelper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async Task<string> GetAsync(string url)
|
|
||||||
|
public async Task<string?> TryGetAsync(string url)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(url))
|
if (string.IsNullOrEmpty(url))
|
||||||
{
|
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HttpResponseMessage response = await httpClient.GetAsync(url);
|
HttpResponseMessage response = await httpClient.GetAsync(url);
|
||||||
|
|
||||||
return await response.Content.ReadAsStringAsync();
|
return await response.Content.ReadAsStringAsync();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(string, HttpResponseHeaders)> GetAsync(HttpClient client, string url, CancellationToken token)
|
public async Task<(string, HttpResponseHeaders)> GetAsync(HttpClient client, string url, CancellationToken token)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(url))
|
if (string.IsNullOrEmpty(url))
|
||||||
{
|
{
|
||||||
return (null, null);
|
return (null, null);
|
||||||
}
|
}
|
||||||
@@ -97,77 +103,63 @@ namespace ClashN.Base
|
|||||||
|
|
||||||
public async Task DownloadFileAsync(HttpClient client, string url, string fileName, IProgress<double> progress, CancellationToken token)
|
public async Task DownloadFileAsync(HttpClient client, string url, string fileName, IProgress<double> progress, CancellationToken token)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(url))
|
if (string.IsNullOrEmpty(url))
|
||||||
{
|
throw new ArgumentNullException(nameof(url));
|
||||||
throw new ArgumentNullException("url");
|
if (string.IsNullOrEmpty(fileName))
|
||||||
}
|
throw new ArgumentNullException(nameof(fileName));
|
||||||
if (Utils.IsNullOrEmpty(fileName))
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("fileName");
|
|
||||||
}
|
|
||||||
if (File.Exists(fileName))
|
|
||||||
{
|
|
||||||
File.Delete(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
|
HttpResponseMessage response =
|
||||||
|
await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
if (!response.IsSuccessStatusCode)
|
||||||
{
|
|
||||||
throw new Exception(string.Format("The request returned with HTTP status code {0}", response.StatusCode));
|
throw new Exception(string.Format("The request returned with HTTP status code {0}", response.StatusCode));
|
||||||
}
|
|
||||||
|
|
||||||
var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;
|
var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;
|
||||||
var canReportProgress = total != -1 && progress != null;
|
var canReportProgress = total != -1 && progress != null;
|
||||||
|
|
||||||
using (var stream = await response.Content.ReadAsStreamAsync())
|
using var stream = await response.Content.ReadAsStreamAsync();
|
||||||
|
using var file = File.Create(fileName);
|
||||||
|
|
||||||
|
var totalRead = 0L;
|
||||||
|
var buffer = new byte[1024 * 1024];
|
||||||
|
var isMoreToRead = true;
|
||||||
|
progressPercentage = -1;
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
using (var file = File.Create(fileName))
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
var read = await stream.ReadAsync(buffer, 0, buffer.Length, token);
|
||||||
|
|
||||||
|
if (read == 0)
|
||||||
{
|
{
|
||||||
var totalRead = 0L;
|
isMoreToRead = false;
|
||||||
var buffer = new byte[1024 * 1024];
|
}
|
||||||
var isMoreToRead = true;
|
else
|
||||||
progressPercentage = -1;
|
{
|
||||||
|
var data = new byte[read];
|
||||||
|
buffer.ToList().CopyTo(0, data, 0, read);
|
||||||
|
|
||||||
do
|
// TODO: put here the code to write the file to disk
|
||||||
{
|
file.Write(data, 0, read);
|
||||||
token.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
var read = await stream.ReadAsync(buffer, 0, buffer.Length, token);
|
totalRead += read;
|
||||||
|
|
||||||
if (read == 0)
|
|
||||||
{
|
|
||||||
isMoreToRead = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var data = new byte[read];
|
|
||||||
buffer.ToList().CopyTo(0, data, 0, read);
|
|
||||||
|
|
||||||
// TODO: put here the code to write the file to disk
|
|
||||||
file.Write(data, 0, read);
|
|
||||||
|
|
||||||
totalRead += read;
|
|
||||||
|
|
||||||
if (canReportProgress)
|
|
||||||
{
|
|
||||||
var percent = Convert.ToInt32((totalRead * 1d) / (total * 1d) * 100);
|
|
||||||
if (progressPercentage != percent && percent % 10 == 0)
|
|
||||||
{
|
|
||||||
progressPercentage = percent;
|
|
||||||
progress.Report(percent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (isMoreToRead);
|
|
||||||
file.Close();
|
|
||||||
if (canReportProgress)
|
if (canReportProgress)
|
||||||
{
|
{
|
||||||
progress.Report(101);
|
var percent = Convert.ToInt32((totalRead * 1d) / (total * 1d) * 100);
|
||||||
|
if (progressPercentage != percent && percent % 10 == 0)
|
||||||
|
{
|
||||||
|
progressPercentage = percent;
|
||||||
|
progress?.Report(percent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} while (isMoreToRead);
|
||||||
|
|
||||||
|
|
||||||
|
if (canReportProgress)
|
||||||
|
progress?.Report(101);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace ClashN.Converters
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var fontFamily = LazyConfig.Instance.GetConfig().uiItem.currentFontFamily;
|
var fontFamily = LazyConfig.Instance.Config.UiItem.currentFontFamily;
|
||||||
if (!string.IsNullOrEmpty(fontFamily))
|
if (!string.IsNullOrEmpty(fontFamily))
|
||||||
{
|
{
|
||||||
var fontPath = Utils.GetFontsPath();
|
var fontPath = Utils.GetFontsPath();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace ClashN.Handler
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 本软件配置文件处理类
|
/// 本软件配置文件处理类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class ConfigHandler
|
class ConfigProc
|
||||||
{
|
{
|
||||||
private static string configRes = Global.ConfigFileName;
|
private static string configRes = Global.ConfigFileName;
|
||||||
private static readonly object objLock = new object();
|
private static readonly object objLock = new object();
|
||||||
@@ -20,11 +20,11 @@ namespace ClashN.Handler
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="config"></param>
|
/// <param name="config"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static int LoadConfig(ref Config config)
|
public static int LoadConfig(ref Config? config)
|
||||||
{
|
{
|
||||||
//载入配置文件
|
//载入配置文件
|
||||||
string result = Utils.LoadResource(Utils.GetConfigPath(configRes));
|
string result = Utils.LoadResource(Utils.GetConfigPath(configRes));
|
||||||
if (!Utils.IsNullOrEmpty(result))
|
if (!string.IsNullOrEmpty(result))
|
||||||
{
|
{
|
||||||
//转成Json
|
//转成Json
|
||||||
config = Utils.FromJson<Config>(result);
|
config = Utils.FromJson<Config>(result);
|
||||||
@@ -42,71 +42,59 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
config = new Config
|
config = new Config
|
||||||
{
|
{
|
||||||
logLevel = "warning",
|
LogLevel = "warning",
|
||||||
profileItems = new List<ProfileItem>(),
|
EnableStatistics = true,
|
||||||
|
|
||||||
enableStatistics = true,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//本地监听
|
//本地监听
|
||||||
if (config.mixedPort == 0)
|
if (config.MixedPort == 0)
|
||||||
{
|
config.MixedPort = 7888;
|
||||||
config.mixedPort = 7888;
|
|
||||||
}
|
if (config.HttpPort == 0)
|
||||||
if (config.httpPort == 0)
|
config.HttpPort = 7890;
|
||||||
{
|
|
||||||
config.httpPort = 7890;
|
if (config.SocksPort == 0)
|
||||||
}
|
config.SocksPort = 7891;
|
||||||
if (config.socksPort == 0)
|
|
||||||
{
|
if (config.ApiPort == 0)
|
||||||
config.socksPort = 7891;
|
config.ApiPort = 9090;
|
||||||
}
|
|
||||||
if (config.APIPort == 0)
|
|
||||||
{
|
|
||||||
config.APIPort = 9090;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.PacPort == 0)
|
if (config.PacPort == 0)
|
||||||
{
|
{
|
||||||
config.PacPort = 7990;
|
config.PacPort = 7990;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.profileItems == null)
|
if (config.UiItem == null)
|
||||||
{
|
{
|
||||||
config.profileItems = new List<ProfileItem>();
|
config.UiItem = new UIItem()
|
||||||
}
|
|
||||||
|
|
||||||
if (config.uiItem == null)
|
|
||||||
{
|
|
||||||
config.uiItem = new UIItem()
|
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.constItem == null)
|
if (config.ConstItem == null)
|
||||||
{
|
{
|
||||||
config.constItem = new ConstItem();
|
config.ConstItem = new ConstItem();
|
||||||
}
|
}
|
||||||
//if (Utils.IsNullOrEmpty(config.constItem.subConvertUrl))
|
//if (string.IsNullOrEmpty(config.constItem.subConvertUrl))
|
||||||
//{
|
//{
|
||||||
// config.constItem.subConvertUrl = Global.SubConvertUrl;
|
// config.constItem.subConvertUrl = Global.SubConvertUrl;
|
||||||
//}
|
//}
|
||||||
if (Utils.IsNullOrEmpty(config.constItem.speedTestUrl))
|
if (string.IsNullOrEmpty(config.ConstItem.speedTestUrl))
|
||||||
{
|
{
|
||||||
config.constItem.speedTestUrl = Global.SpeedTestUrl;
|
config.ConstItem.speedTestUrl = Global.SpeedTestUrl;
|
||||||
}
|
}
|
||||||
if (Utils.IsNullOrEmpty(config.constItem.speedPingTestUrl))
|
if (string.IsNullOrEmpty(config.ConstItem.speedPingTestUrl))
|
||||||
{
|
{
|
||||||
config.constItem.speedPingTestUrl = Global.SpeedPingTestUrl;
|
config.ConstItem.speedPingTestUrl = Global.SpeedPingTestUrl;
|
||||||
}
|
}
|
||||||
if (Utils.IsNullOrEmpty(config.constItem.defIEProxyExceptions))
|
if (string.IsNullOrEmpty(config.ConstItem.defIEProxyExceptions))
|
||||||
{
|
{
|
||||||
config.constItem.defIEProxyExceptions = Global.IEProxyExceptions;
|
config.ConstItem.defIEProxyExceptions = Global.IEProxyExceptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config == null
|
if (config == null
|
||||||
|| config.profileItems.Count <= 0
|
|| config.ProfileItems.Count <= 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Global.reloadCore = false;
|
Global.reloadCore = false;
|
||||||
@@ -115,11 +103,11 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
Global.reloadCore = true;
|
Global.reloadCore = true;
|
||||||
|
|
||||||
for (int i = 0; i < config.profileItems.Count; i++)
|
for (int i = 0; i < config.ProfileItems.Count; i++)
|
||||||
{
|
{
|
||||||
ProfileItem profileItem = config.profileItems[i];
|
ProfileItem profileItem = config.ProfileItems[i];
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(profileItem.indexId))
|
if (string.IsNullOrEmpty(profileItem.indexId))
|
||||||
{
|
{
|
||||||
profileItem.indexId = Utils.GetGUID(false);
|
profileItem.indexId = Utils.GetGUID(false);
|
||||||
}
|
}
|
||||||
@@ -134,7 +122,7 @@ namespace ClashN.Handler
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="config"></param>
|
/// <param name="config"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static int SaveConfig(ref Config config, bool reload = true)
|
public static int SaveConfig(Config config, bool reload = true)
|
||||||
{
|
{
|
||||||
Global.reloadCore = reload;
|
Global.reloadCore = reload;
|
||||||
|
|
||||||
@@ -215,7 +203,7 @@ namespace ClashN.Handler
|
|||||||
profileItem.indexId = string.Empty;
|
profileItem.indexId = string.Empty;
|
||||||
profileItem.remarks = string.Format("{0}-clone", item.remarks);
|
profileItem.remarks = string.Format("{0}-clone", item.remarks);
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(profileItem.address) || !File.Exists(Utils.GetConfigPath(profileItem.address)))
|
if (string.IsNullOrEmpty(profileItem.address) || !File.Exists(Utils.GetConfigPath(profileItem.address)))
|
||||||
{
|
{
|
||||||
profileItem.address = string.Empty;
|
profileItem.address = string.Empty;
|
||||||
AddProfileCommon(ref config, profileItem);
|
AddProfileCommon(ref config, profileItem);
|
||||||
@@ -246,7 +234,7 @@ namespace ClashN.Handler
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.indexId = item.indexId;
|
config.IndexId = item.indexId;
|
||||||
Global.reloadCore = true;
|
Global.reloadCore = true;
|
||||||
|
|
||||||
ToJsonFile(config);
|
ToJsonFile(config);
|
||||||
@@ -256,11 +244,11 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
public static int SetDefaultProfile(Config config, List<ProfileItem> lstProfile)
|
public static int SetDefaultProfile(Config config, List<ProfileItem> lstProfile)
|
||||||
{
|
{
|
||||||
if (lstProfile.Exists(t => t.indexId == config.indexId))
|
if (lstProfile.Exists(t => t.indexId == config.IndexId))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (config.profileItems.Exists(t => t.indexId == config.indexId))
|
if (config.ProfileItems.Exists(t => t.indexId == config.IndexId))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -268,26 +256,26 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
return SetDefaultProfile(ref config, lstProfile[0]);
|
return SetDefaultProfile(ref config, lstProfile[0]);
|
||||||
}
|
}
|
||||||
if (config.profileItems.Count > 0)
|
if (config.ProfileItems.Count > 0)
|
||||||
{
|
{
|
||||||
return SetDefaultProfile(ref config, config.profileItems[0]);
|
return SetDefaultProfile(ref config, config.ProfileItems[0]);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
public static ProfileItem GetDefaultProfile(ref Config config)
|
public static ProfileItem GetDefaultProfile(ref Config config)
|
||||||
{
|
{
|
||||||
if (config.profileItems.Count <= 0)
|
if (config.ProfileItems.Count <= 0)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var index = config.FindIndexId(config.indexId);
|
var index = config.FindIndexId(config.IndexId);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
SetDefaultProfile(ref config, config.profileItems[0]);
|
SetDefaultProfile(ref config, config.ProfileItems[0]);
|
||||||
return config.profileItems[0];
|
return config.ProfileItems[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.profileItems[index];
|
return config.ProfileItems[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -297,9 +285,9 @@ namespace ClashN.Handler
|
|||||||
/// <param name="index"></param>
|
/// <param name="index"></param>
|
||||||
/// <param name="eMove"></param>
|
/// <param name="eMove"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static int MoveProfile(ref Config config, int index, EMove eMove, int pos = -1)
|
public static int MoveProfile(ref Config config, int index, MovementTarget eMove, int pos = -1)
|
||||||
{
|
{
|
||||||
List<ProfileItem> lstProfile = config.profileItems.OrderBy(it => it.sort).ToList();
|
List<ProfileItem> lstProfile = config.ProfileItems.OrderBy(it => it.sort).ToList();
|
||||||
int count = lstProfile.Count;
|
int count = lstProfile.Count;
|
||||||
if (index < 0 || index > lstProfile.Count - 1)
|
if (index < 0 || index > lstProfile.Count - 1)
|
||||||
{
|
{
|
||||||
@@ -313,48 +301,48 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
switch (eMove)
|
switch (eMove)
|
||||||
{
|
{
|
||||||
case EMove.Top:
|
case MovementTarget.Top:
|
||||||
|
{
|
||||||
|
if (index == 0)
|
||||||
{
|
{
|
||||||
if (index == 0)
|
return 0;
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lstProfile[index].sort = lstProfile[0].sort - 1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case EMove.Up:
|
lstProfile[index].sort = lstProfile[0].sort - 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MovementTarget.Up:
|
||||||
|
{
|
||||||
|
if (index == 0)
|
||||||
{
|
{
|
||||||
if (index == 0)
|
return 0;
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lstProfile[index].sort = lstProfile[index - 1].sort - 1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
lstProfile[index].sort = lstProfile[index - 1].sort - 1;
|
||||||
|
|
||||||
case EMove.Down:
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MovementTarget.Down:
|
||||||
|
{
|
||||||
|
if (index == count - 1)
|
||||||
{
|
{
|
||||||
if (index == count - 1)
|
return 0;
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lstProfile[index].sort = lstProfile[index + 1].sort + 1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case EMove.Bottom:
|
lstProfile[index].sort = lstProfile[index + 1].sort + 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MovementTarget.Bottom:
|
||||||
|
{
|
||||||
|
if (index == count - 1)
|
||||||
{
|
{
|
||||||
if (index == count - 1)
|
return 0;
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lstProfile[index].sort = lstProfile[lstProfile.Count - 1].sort + 1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case EMove.Position:
|
lstProfile[index].sort = lstProfile[lstProfile.Count - 1].sort + 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MovementTarget.Position:
|
||||||
lstProfile[index].sort = pos * 10 + 1;
|
lstProfile[index].sort = pos * 10 + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -366,19 +354,19 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
public static int AddProfileViaContent(ref Config config, ProfileItem profileItem, string content)
|
public static int AddProfileViaContent(ref Config config, ProfileItem profileItem, string content)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(content))
|
if (string.IsNullOrEmpty(content))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
string newFileName = profileItem.address;
|
string newFileName = profileItem.address;
|
||||||
if (Utils.IsNullOrEmpty(newFileName))
|
if (string.IsNullOrEmpty(newFileName))
|
||||||
{
|
{
|
||||||
var ext = ".yaml";
|
var ext = ".yaml";
|
||||||
newFileName = string.Format("{0}{1}", Utils.GetGUID(), ext);
|
newFileName = string.Format("{0}{1}", Utils.GetGUID(), ext);
|
||||||
profileItem.address = newFileName;
|
profileItem.address = newFileName;
|
||||||
}
|
}
|
||||||
if (Utils.IsNullOrEmpty(profileItem.remarks))
|
if (string.IsNullOrEmpty(profileItem.remarks))
|
||||||
{
|
{
|
||||||
profileItem.remarks = "clash_local_file";
|
profileItem.remarks = "clash_local_file";
|
||||||
}
|
}
|
||||||
@@ -392,7 +380,7 @@ namespace ClashN.Handler
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(profileItem.remarks))
|
if (string.IsNullOrEmpty(profileItem.remarks))
|
||||||
{
|
{
|
||||||
profileItem.remarks = string.Format("import custom@{0}", DateTime.Now.ToShortDateString());
|
profileItem.remarks = string.Format("import custom@{0}", DateTime.Now.ToShortDateString());
|
||||||
}
|
}
|
||||||
@@ -416,7 +404,7 @@ namespace ClashN.Handler
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.Copy(fileName, Path.Combine(Utils.GetConfigPath(), newFileName));
|
File.Copy(fileName, Path.Combine(Utils.GetConfigPath(), newFileName));
|
||||||
if (!Utils.IsNullOrEmpty(profileItem.address))
|
if (!string.IsNullOrEmpty(profileItem.address))
|
||||||
{
|
{
|
||||||
File.Delete(Path.Combine(Utils.GetConfigPath(), profileItem.address));
|
File.Delete(Path.Combine(Utils.GetConfigPath(), profileItem.address));
|
||||||
}
|
}
|
||||||
@@ -427,7 +415,7 @@ namespace ClashN.Handler
|
|||||||
}
|
}
|
||||||
|
|
||||||
profileItem.address = newFileName;
|
profileItem.address = newFileName;
|
||||||
if (Utils.IsNullOrEmpty(profileItem.remarks))
|
if (string.IsNullOrEmpty(profileItem.remarks))
|
||||||
{
|
{
|
||||||
profileItem.remarks = string.Format("import custom@{0}", DateTime.Now.ToShortDateString());
|
profileItem.remarks = string.Format("import custom@{0}", DateTime.Now.ToShortDateString());
|
||||||
}
|
}
|
||||||
@@ -441,7 +429,7 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
public static int EditProfile(ref Config config, ProfileItem profileItem)
|
public static int EditProfile(ref Config config, ProfileItem profileItem)
|
||||||
{
|
{
|
||||||
if (!Utils.IsNullOrEmpty(profileItem.indexId) && config.indexId == profileItem.indexId)
|
if (!string.IsNullOrEmpty(profileItem.indexId) && config.IndexId == profileItem.indexId)
|
||||||
{
|
{
|
||||||
Global.reloadCore = true;
|
Global.reloadCore = true;
|
||||||
}
|
}
|
||||||
@@ -449,7 +437,7 @@ namespace ClashN.Handler
|
|||||||
AddProfileCommon(ref config, profileItem);
|
AddProfileCommon(ref config, profileItem);
|
||||||
|
|
||||||
//TODO auto update via url
|
//TODO auto update via url
|
||||||
//if (!Utils.IsNullOrEmpty(profileItem.url))
|
//if (!string.IsNullOrEmpty(profileItem.url))
|
||||||
//{
|
//{
|
||||||
// var httpClient = new HttpClient();
|
// var httpClient = new HttpClient();
|
||||||
// string result = httpClient.GetStringAsync(profileItem.url).Result;
|
// string result = httpClient.GetStringAsync(profileItem.url).Result;
|
||||||
@@ -502,20 +490,20 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
public static int AddProfileCommon(ref Config config, ProfileItem profileItem)
|
public static int AddProfileCommon(ref Config config, ProfileItem profileItem)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(profileItem.indexId))
|
if (string.IsNullOrEmpty(profileItem.indexId))
|
||||||
{
|
{
|
||||||
profileItem.indexId = Utils.GetGUID(false);
|
profileItem.indexId = Utils.GetGUID(false);
|
||||||
}
|
}
|
||||||
if (profileItem.coreType is null)
|
if (profileItem.coreType is null)
|
||||||
{
|
{
|
||||||
profileItem.coreType = ECoreType.clash_meta;
|
profileItem.coreType = CoreKind.ClashMeta;
|
||||||
}
|
}
|
||||||
if (!config.profileItems.Exists(it => it.indexId == profileItem.indexId))
|
if (!config.ProfileItems.Exists(it => it.indexId == profileItem.indexId))
|
||||||
{
|
{
|
||||||
var maxSort = config.profileItems.Any() ? config.profileItems.Max(t => t.sort) : 0;
|
var maxSort = config.ProfileItems.Any() ? config.ProfileItems.Max(t => t.sort) : 0;
|
||||||
profileItem.sort = maxSort++;
|
profileItem.sort = maxSort++;
|
||||||
|
|
||||||
config.profileItems.Add(profileItem);
|
config.ProfileItems.Add(profileItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -525,16 +513,16 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (File.Exists(Utils.GetConfigPath(config.profileItems[index].address)))
|
if (File.Exists(Utils.GetConfigPath(config.ProfileItems[index].address)))
|
||||||
{
|
{
|
||||||
File.Delete(Utils.GetConfigPath(config.profileItems[index].address));
|
File.Delete(Utils.GetConfigPath(config.ProfileItems[index].address));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Utils.SaveLog("RemoveProfileItem", ex);
|
Utils.SaveLog("RemoveProfileItem", ex);
|
||||||
}
|
}
|
||||||
config.profileItems.RemoveAt(index);
|
config.ProfileItems.RemoveAt(index);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -545,7 +533,7 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
if (Utils.IsNullOrEmpty(item.address))
|
if (string.IsNullOrEmpty(item.address))
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
@@ -556,19 +544,19 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
public static int AddBatchProfiles(ref Config config, string clipboardData, string indexId, string groupId)
|
public static int AddBatchProfiles(ref Config config, string clipboardData, string indexId, string groupId)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(clipboardData))
|
if (string.IsNullOrEmpty(clipboardData))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//maybe url
|
//maybe url
|
||||||
if (Utils.IsNullOrEmpty(indexId) && (clipboardData.StartsWith(Global.httpsProtocol) || clipboardData.StartsWith(Global.httpProtocol)))
|
if (string.IsNullOrEmpty(indexId) && (clipboardData.StartsWith(Global.httpsProtocol) || clipboardData.StartsWith(Global.httpProtocol)))
|
||||||
{
|
{
|
||||||
ProfileItem item = new ProfileItem()
|
ProfileItem item = new ProfileItem()
|
||||||
{
|
{
|
||||||
groupId = groupId,
|
groupId = groupId,
|
||||||
url = clipboardData,
|
url = clipboardData,
|
||||||
coreType = ECoreType.clash_meta,
|
coreType = CoreKind.ClashMeta,
|
||||||
address = string.Empty,
|
address = string.Empty,
|
||||||
enabled = true,
|
enabled = true,
|
||||||
remarks = "clash_subscription"
|
remarks = "clash_subscription"
|
||||||
@@ -578,19 +566,19 @@ namespace ClashN.Handler
|
|||||||
}
|
}
|
||||||
|
|
||||||
//maybe clashProtocol
|
//maybe clashProtocol
|
||||||
if (Utils.IsNullOrEmpty(indexId) && (clipboardData.StartsWith(Global.clashProtocol)))
|
if (string.IsNullOrEmpty(indexId) && (clipboardData.StartsWith(Global.clashProtocol)))
|
||||||
{
|
{
|
||||||
Uri url = new Uri(clipboardData);
|
Uri url = new Uri(clipboardData);
|
||||||
if (url.Host == "install-config")
|
if (url.Host == "install-config")
|
||||||
{
|
{
|
||||||
var query = HttpUtility.ParseQueryString(url.Query);
|
var query = HttpUtility.ParseQueryString(url.Query);
|
||||||
if (!Utils.IsNullOrEmpty(query["url"] ?? ""))
|
if (!string.IsNullOrEmpty(query["url"] ?? ""))
|
||||||
{
|
{
|
||||||
ProfileItem item = new ProfileItem()
|
ProfileItem item = new ProfileItem()
|
||||||
{
|
{
|
||||||
groupId = groupId,
|
groupId = groupId,
|
||||||
url = query["url"],
|
url = query["url"],
|
||||||
coreType = ECoreType.clash_meta,
|
coreType = CoreKind.ClashMeta,
|
||||||
address = string.Empty,
|
address = string.Empty,
|
||||||
enabled = true,
|
enabled = true,
|
||||||
remarks = "clash_subscription"
|
remarks = "clash_subscription"
|
||||||
@@ -608,7 +596,7 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
groupId = groupId,
|
groupId = groupId,
|
||||||
url = "",
|
url = "",
|
||||||
coreType = ECoreType.clash_meta,
|
coreType = CoreKind.ClashMeta,
|
||||||
address = string.Empty,
|
address = string.Empty,
|
||||||
enabled = false,
|
enabled = false,
|
||||||
remarks = "clash_local_file"
|
remarks = "clash_local_file"
|
||||||
@@ -622,10 +610,11 @@ namespace ClashN.Handler
|
|||||||
&& clipboardData.IndexOf("proxies") >= 0
|
&& clipboardData.IndexOf("proxies") >= 0
|
||||||
&& clipboardData.IndexOf("rules") >= 0)
|
&& clipboardData.IndexOf("rules") >= 0)
|
||||||
{ }
|
{ }
|
||||||
else { return -1; }
|
else
|
||||||
|
{ return -1; }
|
||||||
|
|
||||||
ProfileItem profileItem;
|
ProfileItem profileItem;
|
||||||
if (!Utils.IsNullOrEmpty(indexId))
|
if (!string.IsNullOrEmpty(indexId))
|
||||||
{
|
{
|
||||||
profileItem = config.GetProfileItem(indexId);
|
profileItem = config.GetProfileItem(indexId);
|
||||||
}
|
}
|
||||||
@@ -648,7 +637,7 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
public static void ClearAllServerStatistics(ref Config config)
|
public static void ClearAllServerStatistics(ref Config config)
|
||||||
{
|
{
|
||||||
foreach (var item in config.profileItems)
|
foreach (var item in config.ProfileItems)
|
||||||
{
|
{
|
||||||
item.uploadRemote = 0;
|
item.uploadRemote = 0;
|
||||||
item.downloadRemote = 0;
|
item.downloadRemote = 0;
|
||||||
@@ -42,7 +42,7 @@ namespace ClashN.Handler
|
|||||||
}
|
}
|
||||||
|
|
||||||
string addressFileName = node.address;
|
string addressFileName = node.address;
|
||||||
if (Utils.IsNullOrEmpty(addressFileName))
|
if (string.IsNullOrEmpty(addressFileName))
|
||||||
{
|
{
|
||||||
msg = ResUI.FailedGetDefaultConfiguration;
|
msg = ResUI.FailedGetDefaultConfiguration;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -60,7 +60,7 @@ namespace ClashN.Handler
|
|||||||
string tagYamlStr1 = "!<str>";
|
string tagYamlStr1 = "!<str>";
|
||||||
string tagYamlStr2 = "__strn__";
|
string tagYamlStr2 = "__strn__";
|
||||||
string tagYamlStr3 = "!!str";
|
string tagYamlStr3 = "!!str";
|
||||||
var config = LazyConfig.Instance.GetConfig();
|
var config = LazyConfig.Instance.Config;
|
||||||
var txtFile = File.ReadAllText(addressFileName);
|
var txtFile = File.ReadAllText(addressFileName);
|
||||||
txtFile = txtFile.Replace(tagYamlStr1, tagYamlStr2);
|
txtFile = txtFile.Replace(tagYamlStr1, tagYamlStr2);
|
||||||
|
|
||||||
@@ -71,50 +71,51 @@ namespace ClashN.Handler
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
//mixed-port
|
//mixed-port
|
||||||
ModifyContent(fileContent, "mixed-port", config.mixedPort);
|
fileContent["mixed-port"] = config.MixedPort;
|
||||||
//port
|
//port
|
||||||
ModifyContent(fileContent, "port", config.httpPort);
|
fileContent["port"] = config.HttpPort;
|
||||||
//socks-port
|
//socks-port
|
||||||
ModifyContent(fileContent, "socks-port", config.socksPort);
|
fileContent["socks-port"] = config.SocksPort;
|
||||||
//log-level
|
//log-level
|
||||||
ModifyContent(fileContent, "log-level", config.logLevel);
|
fileContent["log-level"] = config.LogLevel;
|
||||||
//external-controller
|
//external-controller
|
||||||
ModifyContent(fileContent, "external-controller", $"{Global.Loopback}:{config.APIPort}");
|
fileContent["external-controller"] = $"{Global.Loopback}:{config.ApiPort}";
|
||||||
//allow-lan
|
//allow-lan
|
||||||
if (config.allowLANConn)
|
if (config.AllowLANConn)
|
||||||
{
|
{
|
||||||
ModifyContent(fileContent, "allow-lan", "true");
|
fileContent["allow-lan"] = "true";
|
||||||
ModifyContent(fileContent, "bind-address", "*");
|
fileContent["bind-address"] = "*";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ModifyContent(fileContent, "allow-lan", "false");
|
fileContent["allow-lan"] = "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
//ipv6
|
//ipv6
|
||||||
ModifyContent(fileContent, "ipv6", config.enableIpv6);
|
fileContent["ipv6"] = config.EnableIpv6;
|
||||||
|
|
||||||
//mode
|
//mode
|
||||||
if (!fileContent.ContainsKey("mode"))
|
if (!fileContent.ContainsKey("mode"))
|
||||||
{
|
{
|
||||||
ModifyContent(fileContent, "mode", ERuleMode.Rule.ToString().ToLower());
|
fileContent["mode"] = ERuleMode.Rule.ToString().ToLower();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (config.ruleMode != ERuleMode.Unchanged)
|
if (config.ruleMode != ERuleMode.Unchanged)
|
||||||
{
|
{
|
||||||
ModifyContent(fileContent, "mode", config.ruleMode.ToString().ToLower());
|
fileContent["model"] = config.ruleMode.ToString().ToLower();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//enable tun mode
|
//enable tun mode
|
||||||
if (config.enableTun)
|
if (config.EnableTun)
|
||||||
{
|
{
|
||||||
string tun = Utils.GetEmbedText(Global.SampleTun);
|
string tun = Utils.GetEmbedText(Global.SampleTun);
|
||||||
if (!Utils.IsNullOrEmpty(tun))
|
if (!string.IsNullOrEmpty(tun))
|
||||||
{
|
{
|
||||||
var tunContent = Utils.FromYaml<Dictionary<string, object>>(tun);
|
var tunContent = Utils.FromYaml<Dictionary<string, object>>(tun);
|
||||||
ModifyContent(fileContent, "tun", tunContent["tun"]);
|
if (tunContent != null)
|
||||||
|
fileContent["tun"] = tunContent["tun"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +153,7 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
private static void MixinContent(Dictionary<string, object> fileContent, Config config, ProfileItem node)
|
private static void MixinContent(Dictionary<string, object> fileContent, Config config, ProfileItem node)
|
||||||
{
|
{
|
||||||
if (!config.enableMixinContent)
|
if (!config.EnableMixinContent)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -173,7 +174,7 @@ namespace ClashN.Handler
|
|||||||
}
|
}
|
||||||
foreach (var item in mixinContent)
|
foreach (var item in mixinContent)
|
||||||
{
|
{
|
||||||
if (!config.enableTun && item.Key == "tun")
|
if (!config.EnableTun && item.Key == "tun")
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -186,23 +187,12 @@ namespace ClashN.Handler
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ModifyContent(fileContent, item.Key, item.Value);
|
fileContent[item.Key] = item.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ModifyContent(Dictionary<string, object> fileContent, string key, object value)
|
|
||||||
{
|
|
||||||
if (fileContent.ContainsKey(key))
|
|
||||||
{
|
|
||||||
fileContent[key] = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fileContent.Add(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static void ModifyContentMerge(Dictionary<string, object> fileContent, string key, object value)
|
private static void ModifyContentMerge(Dictionary<string, object> fileContent, string key, object value)
|
||||||
{
|
{
|
||||||
bool blPrepend = false;
|
bool blPrepend = false;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
if (Global.reloadCore)
|
if (Global.reloadCore)
|
||||||
{
|
{
|
||||||
var item = ConfigHandler.GetDefaultProfile(ref config);
|
var item = ConfigProc.GetDefaultProfile(ref config);
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
CoreStop();
|
CoreStop();
|
||||||
@@ -36,12 +36,12 @@ namespace ClashN.Handler
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.enableTun && !Utils.IsAdministrator())
|
if (config.EnableTun && !Utils.IsAdministrator())
|
||||||
{
|
{
|
||||||
ShowMsg(true, ResUI.EnableTunModeFailed);
|
ShowMsg(true, ResUI.EnableTunModeFailed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (config.enableTun && item.coreType == ECoreType.clash)
|
if (config.EnableTun && item.coreType == CoreKind.Clash)
|
||||||
{
|
{
|
||||||
ShowMsg(true, ResUI.TunModeCoreTip);
|
ShowMsg(true, ResUI.TunModeCoreTip);
|
||||||
return;
|
return;
|
||||||
@@ -171,7 +171,7 @@ namespace ClashN.Handler
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Utils.IsNullOrEmpty(fileName))
|
if (string.IsNullOrEmpty(fileName))
|
||||||
{
|
{
|
||||||
string msg = string.Format(ResUI.NotFoundCore, coreInfo.coreUrl);
|
string msg = string.Format(ResUI.NotFoundCore, coreInfo.coreUrl);
|
||||||
ShowMsg(false, msg);
|
ShowMsg(false, msg);
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ namespace ClashN.Handler
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
class DownloadHandle
|
class DownloadHandle
|
||||||
{
|
{
|
||||||
public event EventHandler<ResultEventArgs> UpdateCompleted;
|
public event EventHandler<ResultEventArgs>? UpdateCompleted;
|
||||||
|
public event ErrorEventHandler? Error;
|
||||||
public event ErrorEventHandler Error;
|
|
||||||
|
|
||||||
|
|
||||||
public class ResultEventArgs : EventArgs
|
public class ResultEventArgs : EventArgs
|
||||||
@@ -34,7 +33,7 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
|
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.EnableSecurityProtocolTls13);
|
||||||
UpdateCompleted?.Invoke(this, new ResultEventArgs(false, ResUI.Downloading));
|
UpdateCompleted?.Invoke(this, new ResultEventArgs(false, ResUI.Downloading));
|
||||||
|
|
||||||
var client = new HttpClient(new SocketsHttpHandler()
|
var client = new HttpClient(new SocketsHttpHandler()
|
||||||
@@ -75,13 +74,13 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
|
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.EnableSecurityProtocolTls13);
|
||||||
var client = new HttpClient(new SocketsHttpHandler()
|
var client = new HttpClient(new SocketsHttpHandler()
|
||||||
{
|
{
|
||||||
Proxy = GetWebProxy(blProxy)
|
Proxy = GetWebProxy(blProxy)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(userAgent))
|
if (string.IsNullOrEmpty(userAgent))
|
||||||
{
|
{
|
||||||
userAgent = $"{Utils.GetVersion(false)}";
|
userAgent = $"{Utils.GetVersion(false)}";
|
||||||
}
|
}
|
||||||
@@ -89,7 +88,7 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
Uri uri = new Uri(url);
|
Uri uri = new Uri(url);
|
||||||
//Authorization Header
|
//Authorization Header
|
||||||
if (!Utils.IsNullOrEmpty(uri.UserInfo))
|
if (!string.IsNullOrEmpty(uri.UserInfo))
|
||||||
{
|
{
|
||||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Utils.Base64Encode(uri.UserInfo));
|
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Utils.Base64Encode(uri.UserInfo));
|
||||||
}
|
}
|
||||||
@@ -114,7 +113,7 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
public async Task<string> UrlRedirectAsync(string url, bool blProxy)
|
public async Task<string> UrlRedirectAsync(string url, bool blProxy)
|
||||||
{
|
{
|
||||||
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
|
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.EnableSecurityProtocolTls13);
|
||||||
SocketsHttpHandler webRequestHandler = new SocketsHttpHandler
|
SocketsHttpHandler webRequestHandler = new SocketsHttpHandler
|
||||||
{
|
{
|
||||||
AllowAutoRedirect = false,
|
AllowAutoRedirect = false,
|
||||||
@@ -140,7 +139,7 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var socksPort = LazyConfig.Instance.GetConfig().socksPort;
|
var socksPort = LazyConfig.Instance.Config.SocksPort;
|
||||||
if (!SocketCheck(Global.Loopback, socksPort))
|
if (!SocketCheck(Global.Loopback, socksPort))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -19,10 +19,7 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
}
|
}
|
||||||
public Config GetConfig()
|
public Config Config => _config;
|
||||||
{
|
|
||||||
return _config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetProxies(Dictionary<String, ProxiesItem> proxies)
|
public void SetProxies(Dictionary<String, ProxiesItem> proxies)
|
||||||
{
|
{
|
||||||
@@ -35,17 +32,17 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
public Dictionary<string, object> ProfileContent { get; set; }
|
public Dictionary<string, object> ProfileContent { get; set; }
|
||||||
|
|
||||||
public ECoreType GetCoreType(ProfileItem profileItem)
|
public CoreKind GetCoreType(ProfileItem profileItem)
|
||||||
{
|
{
|
||||||
if (profileItem != null && profileItem.coreType != null)
|
if (profileItem != null && profileItem.coreType != null)
|
||||||
{
|
{
|
||||||
return (ECoreType)profileItem.coreType;
|
return (CoreKind)profileItem.coreType;
|
||||||
}
|
}
|
||||||
return ECoreType.clash;
|
return CoreKind.Clash;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CoreInfo GetCoreInfo(ECoreType coreType)
|
public CoreInfo GetCoreInfo(CoreKind coreType)
|
||||||
{
|
{
|
||||||
if (coreInfos == null)
|
if (coreInfos == null)
|
||||||
{
|
{
|
||||||
@@ -60,7 +57,7 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
coreInfos.Add(new CoreInfo
|
coreInfos.Add(new CoreInfo
|
||||||
{
|
{
|
||||||
coreType = ECoreType.clashN,
|
coreType = CoreKind.ClashN,
|
||||||
coreUrl = Global.NUrl,
|
coreUrl = Global.NUrl,
|
||||||
coreLatestUrl = Global.NUrl + "/latest",
|
coreLatestUrl = Global.NUrl + "/latest",
|
||||||
coreDownloadUrl32 = Global.NUrl + "/download/{0}/clashN-32.zip",
|
coreDownloadUrl32 = Global.NUrl + "/download/{0}/clashN-32.zip",
|
||||||
@@ -69,7 +66,7 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
coreInfos.Add(new CoreInfo
|
coreInfos.Add(new CoreInfo
|
||||||
{
|
{
|
||||||
coreType = ECoreType.clash,
|
coreType = CoreKind.Clash,
|
||||||
coreExes = new List<string> { "clash-windows-amd64-v3", "clash-windows-amd64", "clash-windows-386", "clash" },
|
coreExes = new List<string> { "clash-windows-amd64-v3", "clash-windows-amd64", "clash-windows-386", "clash" },
|
||||||
arguments = "-f config.yaml",
|
arguments = "-f config.yaml",
|
||||||
coreUrl = Global.clashCoreUrl,
|
coreUrl = Global.clashCoreUrl,
|
||||||
@@ -81,7 +78,7 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
coreInfos.Add(new CoreInfo
|
coreInfos.Add(new CoreInfo
|
||||||
{
|
{
|
||||||
coreType = ECoreType.clash_meta,
|
coreType = CoreKind.ClashMeta,
|
||||||
coreExes = new List<string> { $"Clash.Meta-windows-amd64{(Avx2.X64.IsSupported ? "" : "-compatible")}", "Clash.Meta-windows-amd64-compatible", "Clash.Meta-windows-amd64", "Clash.Meta-windows-386", "Clash.Meta", "clash" },
|
coreExes = new List<string> { $"Clash.Meta-windows-amd64{(Avx2.X64.IsSupported ? "" : "-compatible")}", "Clash.Meta-windows-amd64-compatible", "Clash.Meta-windows-amd64", "Clash.Meta-windows-386", "Clash.Meta", "clash" },
|
||||||
arguments = "-f config.yaml",
|
arguments = "-f config.yaml",
|
||||||
coreUrl = Global.clashMetaCoreUrl,
|
coreUrl = Global.clashMetaCoreUrl,
|
||||||
@@ -93,7 +90,7 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
coreInfos.Add(new CoreInfo
|
coreInfos.Add(new CoreInfo
|
||||||
{
|
{
|
||||||
coreType = ECoreType.clash_premium,
|
coreType = CoreKind.ClashPremium,
|
||||||
coreExes = new List<string> { "clash-windows-amd64-v3", "clash-windows-amd64", "clash-windows-386", "clash" },
|
coreExes = new List<string> { "clash-windows-amd64-v3", "clash-windows-amd64", "clash-windows-386", "clash" },
|
||||||
arguments = "-f config.yaml",
|
arguments = "-f config.yaml",
|
||||||
coreUrl = Global.clashCoreUrl,
|
coreUrl = Global.clashCoreUrl,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int index = (int)config.sysProxyType;
|
int index = (int)config.SysProxyType;
|
||||||
|
|
||||||
//Load from local file
|
//Load from local file
|
||||||
var fileName = Utils.GetPath($"NotifyIcon{index + 1}.ico");
|
var fileName = Utils.GetPath($"NotifyIcon{index + 1}.ico");
|
||||||
@@ -76,7 +76,7 @@ namespace ClashN.Handler
|
|||||||
}
|
}
|
||||||
fileName = fileDialog.FileName;
|
fileName = fileDialog.FileName;
|
||||||
}
|
}
|
||||||
if (Utils.IsNullOrEmpty(fileName))
|
if (string.IsNullOrEmpty(fileName))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -112,9 +112,9 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
var dtNow = DateTime.Now;
|
var dtNow = DateTime.Now;
|
||||||
|
|
||||||
if (config.autoUpdateSubInterval > 0)
|
if (config.AutoUpdateSubInterval > 0)
|
||||||
{
|
{
|
||||||
if ((dtNow - autoUpdateSubTime).Hours % config.autoUpdateSubInterval == 0)
|
if ((dtNow - autoUpdateSubTime).Hours % config.AutoUpdateSubInterval == 0)
|
||||||
{
|
{
|
||||||
updateHandle.UpdateSubscriptionProcess(config, true, null, (bool success, string msg) =>
|
updateHandle.UpdateSubscriptionProcess(config, true, null, (bool success, string msg) =>
|
||||||
{
|
{
|
||||||
@@ -183,13 +183,13 @@ namespace ClashN.Handler
|
|||||||
var gesture = new KeyGesture(KeyInterop.KeyFromVirtualKey((int)item.KeyCode), modifiers);
|
var gesture = new KeyGesture(KeyInterop.KeyFromVirtualKey((int)item.KeyCode), modifiers);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HotkeyManager.Current.AddOrReplace(((int)item.eGlobalHotkey).ToString(), gesture, handler);
|
HotkeyManager.Current.AddOrReplace(((int)item.GlobalHotkey).ToString(), gesture, handler);
|
||||||
var msg = string.Format(ResUI.RegisterGlobalHotkeySuccessfully, $"{item.eGlobalHotkey.ToString()} = {Utils.ToJson(item)}");
|
var msg = string.Format(ResUI.RegisterGlobalHotkeySuccessfully, $"{item.GlobalHotkey.ToString()} = {Utils.ToJson(item)}");
|
||||||
update(false, msg);
|
update(false, msg);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var msg = string.Format(ResUI.RegisterGlobalHotkeyFailed, $"{item.eGlobalHotkey.ToString()} = {Utils.ToJson(item)}", ex.Message);
|
var msg = string.Format(ResUI.RegisterGlobalHotkeyFailed, $"{item.GlobalHotkey.ToString()} = {Utils.ToJson(item)}", ex.Message);
|
||||||
update(false, msg);
|
update(false, msg);
|
||||||
Utils.SaveLog(msg);
|
Utils.SaveLog(msg);
|
||||||
}
|
}
|
||||||
@@ -205,12 +205,12 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < 5; i++)
|
for (var i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
var url = $"{Global.httpProtocol}{Global.Loopback}:{config.APIPort}/proxies";
|
var url = $"{Global.httpProtocol}{Global.Loopback}:{config.ApiPort}/proxies";
|
||||||
var result = await HttpClientHelper.GetInstance().GetAsync(url);
|
var result = await HttpClientHelper.GetInstance().TryGetAsync(url);
|
||||||
var clashProxies = Utils.FromJson<ClashProxies>(result);
|
var clashProxies = Utils.FromJson<ClashProxies>(result);
|
||||||
|
|
||||||
var url2 = $"{Global.httpProtocol}{Global.Loopback}:{config.APIPort}/providers/proxies";
|
var url2 = $"{Global.httpProtocol}{Global.Loopback}:{config.ApiPort}/providers/proxies";
|
||||||
var result2 = await HttpClientHelper.GetInstance().GetAsync(url2);
|
var result2 = await HttpClientHelper.GetInstance().TryGetAsync(url2);
|
||||||
var clashProviders = Utils.FromJson<ClashProviders>(result2);
|
var clashProviders = Utils.FromJson<ClashProviders>(result2);
|
||||||
|
|
||||||
if (clashProxies != null || clashProviders != null)
|
if (clashProxies != null || clashProviders != null)
|
||||||
@@ -261,8 +261,8 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var urlBase = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.GetConfig().APIPort}/proxies";
|
var urlBase = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.Config.ApiPort}/proxies";
|
||||||
urlBase += @"/{0}/delay?timeout=10000&url=" + LazyConfig.Instance.GetConfig().constItem.speedPingTestUrl;
|
urlBase += @"/{0}/delay?timeout=10000&url=" + LazyConfig.Instance.Config.ConstItem.speedPingTestUrl;
|
||||||
|
|
||||||
List<Task> tasks = new List<Task>();
|
List<Task> tasks = new List<Task>();
|
||||||
foreach (var it in lstProxy)
|
foreach (var it in lstProxy)
|
||||||
@@ -275,7 +275,7 @@ namespace ClashN.Handler
|
|||||||
var url = string.Format(urlBase, name);
|
var url = string.Format(urlBase, name);
|
||||||
tasks.Add(Task.Run(async () =>
|
tasks.Add(Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var result = await HttpClientHelper.GetInstance().GetAsync(url);
|
var result = await HttpClientHelper.GetInstance().TryGetAsync(url);
|
||||||
update(it, result);
|
update(it, result);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -320,7 +320,7 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var url = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.GetConfig().APIPort}/proxies/{name}";
|
var url = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.Config.ApiPort}/proxies/{name}";
|
||||||
Dictionary<string, string> headers = new Dictionary<string, string>();
|
Dictionary<string, string> headers = new Dictionary<string, string>();
|
||||||
headers.Add("name", nameNode);
|
headers.Add("name", nameNode);
|
||||||
await HttpClientHelper.GetInstance().PutAsync(url, headers);
|
await HttpClientHelper.GetInstance().PutAsync(url, headers);
|
||||||
@@ -341,7 +341,7 @@ namespace ClashN.Handler
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var urlBase = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.GetConfig().APIPort}/configs";
|
var urlBase = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.Config.ApiPort}/configs";
|
||||||
|
|
||||||
await HttpClientHelper.GetInstance().PatchAsync(urlBase, headers);
|
await HttpClientHelper.GetInstance().PatchAsync(urlBase, headers);
|
||||||
});
|
});
|
||||||
@@ -352,7 +352,7 @@ namespace ClashN.Handler
|
|||||||
ClashConnectionClose("");
|
ClashConnectionClose("");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var url = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.GetConfig().APIPort}/configs?force=true";
|
var url = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.Config.ApiPort}/configs?force=true";
|
||||||
Dictionary<string, string> headers = new Dictionary<string, string>();
|
Dictionary<string, string> headers = new Dictionary<string, string>();
|
||||||
headers.Add("path", filePath);
|
headers.Add("path", filePath);
|
||||||
await HttpClientHelper.GetInstance().PutAsync(url, headers);
|
await HttpClientHelper.GetInstance().PutAsync(url, headers);
|
||||||
@@ -371,8 +371,8 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var url = $"{Global.httpProtocol}{Global.Loopback}:{config.APIPort}/connections";
|
var url = $"{Global.httpProtocol}{Global.Loopback}:{config.ApiPort}/connections";
|
||||||
var result = await HttpClientHelper.GetInstance().GetAsync(url);
|
var result = await HttpClientHelper.GetInstance().TryGetAsync(url);
|
||||||
var clashConnections = Utils.FromJson<ClashConnections>(result);
|
var clashConnections = Utils.FromJson<ClashConnections>(result);
|
||||||
|
|
||||||
update(clashConnections);
|
update(clashConnections);
|
||||||
@@ -387,7 +387,7 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var url = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.GetConfig().APIPort}/connections/{id}";
|
var url = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.Config.ApiPort}/connections/{id}";
|
||||||
await HttpClientHelper.GetInstance().DeleteAsync(url);
|
await HttpClientHelper.GetInstance().DeleteAsync(url);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace ClashN.Handler
|
|||||||
}
|
}
|
||||||
else if (type == 2 || type == 4)
|
else if (type == 2 || type == 4)
|
||||||
{
|
{
|
||||||
optionCount = Utils.IsNullOrEmpty(exceptions) ? 2 : 3;
|
optionCount = string.IsNullOrEmpty(exceptions) ? 2 : 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
int m_Int = (int)PerConnFlags.PROXY_TYPE_DIRECT;
|
int m_Int = (int)PerConnFlags.PROXY_TYPE_DIRECT;
|
||||||
@@ -37,7 +37,7 @@ namespace ClashN.Handler
|
|||||||
m_Option = PerConnOption.INTERNET_PER_CONN_AUTOCONFIG_URL;
|
m_Option = PerConnOption.INTERNET_PER_CONN_AUTOCONFIG_URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//int optionCount = Utils.IsNullOrEmpty(strProxy) ? 1 : (Utils.IsNullOrEmpty(exceptions) ? 2 : 3);
|
//int optionCount = string.IsNullOrEmpty(strProxy) ? 1 : (string.IsNullOrEmpty(exceptions) ? 2 : 3);
|
||||||
InternetConnectionOption[] options = new InternetConnectionOption[optionCount];
|
InternetConnectionOption[] options = new InternetConnectionOption[optionCount];
|
||||||
// USE a proxy server ...
|
// USE a proxy server ...
|
||||||
options[0].m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS;
|
options[0].m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS;
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
_selecteds.Add(new ServerTestItem()
|
_selecteds.Add(new ServerTestItem()
|
||||||
{
|
{
|
||||||
indexId = it.indexId,
|
IndexId = it.indexId,
|
||||||
address = it.address
|
Address = it.address
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,9 +74,9 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
RunPingSub((ServerTestItem it) =>
|
RunPingSub((ServerTestItem it) =>
|
||||||
{
|
{
|
||||||
long time = Utils.Ping(it.address);
|
long time = Utils.Ping(it.Address);
|
||||||
|
|
||||||
_updateFunc(it.indexId, FormatOut(time, "ms"));
|
_updateFunc(it.IndexId, FormatOut(time, "ms"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,9 +84,9 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
RunPingSub((ServerTestItem it) =>
|
RunPingSub((ServerTestItem it) =>
|
||||||
{
|
{
|
||||||
int time = GetTcpingTime(it.address, it.port);
|
int time = GetTcpingTime(it.Address, it.Port);
|
||||||
|
|
||||||
_updateFunc(it.indexId, FormatOut(time, "ms"));
|
_updateFunc(it.IndexId, FormatOut(time, "ms"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int httpPort = _config.httpPort;
|
int httpPort = _config.HttpPort;
|
||||||
|
|
||||||
Task<int> t = Task.Run(() =>
|
Task<int> t = Task.Run(() =>
|
||||||
{
|
{
|
||||||
@@ -103,8 +103,8 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
WebProxy webProxy = new WebProxy(Global.Loopback, httpPort);
|
WebProxy webProxy = new WebProxy(Global.Loopback, httpPort);
|
||||||
int responseTime = -1;
|
int responseTime = -1;
|
||||||
string status = GetRealPingTime(LazyConfig.Instance.GetConfig().constItem.speedPingTestUrl, webProxy, out responseTime);
|
string status = GetRealPingTime(LazyConfig.Instance.Config.ConstItem.speedPingTestUrl, webProxy, out responseTime);
|
||||||
bool noError = Utils.IsNullOrEmpty(status);
|
bool noError = string.IsNullOrEmpty(status);
|
||||||
return noError ? responseTime : -1;
|
return noError ? responseTime : -1;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace ClashN.Handler
|
|||||||
public StatisticsHandler(Config config, Action<ulong, ulong> update)
|
public StatisticsHandler(Config config, Action<ulong, ulong> update)
|
||||||
{
|
{
|
||||||
config_ = config;
|
config_ = config;
|
||||||
Enable = config.enableStatistics;
|
Enable = config.EnableStatistics;
|
||||||
updateFunc_ = update;
|
updateFunc_ = update;
|
||||||
exitFlag_ = false;
|
exitFlag_ = false;
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ namespace ClashN.Handler
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
url = $"ws://{Global.Loopback}:{config_.APIPort}/traffic";
|
url = $"ws://{Global.Loopback}:{config_.ApiPort}/traffic";
|
||||||
|
|
||||||
if (webSocket == null)
|
if (webSocket == null)
|
||||||
{
|
{
|
||||||
@@ -104,9 +104,9 @@ namespace ClashN.Handler
|
|||||||
while (!res.CloseStatus.HasValue)
|
while (!res.CloseStatus.HasValue)
|
||||||
{
|
{
|
||||||
var result = Encoding.UTF8.GetString(buffer, 0, res.Count);
|
var result = Encoding.UTF8.GetString(buffer, 0, res.Count);
|
||||||
if (!Utils.IsNullOrEmpty(result))
|
if (!string.IsNullOrEmpty(result))
|
||||||
{
|
{
|
||||||
var serverStatItem = config_.GetProfileItem(config_.indexId);
|
var serverStatItem = config_.GetProfileItem(config_.IndexId);
|
||||||
ParseOutput(result, out ulong up, out ulong down);
|
ParseOutput(result, out ulong up, out ulong down);
|
||||||
if (up + down > 0)
|
if (up + down > 0)
|
||||||
{
|
{
|
||||||
@@ -134,7 +134,7 @@ namespace ClashN.Handler
|
|||||||
// try
|
// try
|
||||||
// {
|
// {
|
||||||
// string result = Utils.LoadResource(Utils.GetConfigPath(Global.StatisticLogOverall));
|
// string result = Utils.LoadResource(Utils.GetConfigPath(Global.StatisticLogOverall));
|
||||||
// if (!Utils.IsNullOrEmpty(result))
|
// if (!string.IsNullOrEmpty(result))
|
||||||
// {
|
// {
|
||||||
// serverStatistics_ = Utils.FromJson<ServerStatistics>(result);
|
// serverStatistics_ = Utils.FromJson<ServerStatistics>(result);
|
||||||
// }
|
// }
|
||||||
@@ -239,7 +239,7 @@ namespace ClashN.Handler
|
|||||||
down = trafficItem.down;
|
down = trafficItem.down;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
//Utils.SaveLog(ex.Message, ex);
|
//Utils.SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,54 +36,54 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
public static bool UpdateSysProxy(Config config, bool forceDisable)
|
public static bool UpdateSysProxy(Config config, bool forceDisable)
|
||||||
{
|
{
|
||||||
var type = config.sysProxyType;
|
var type = config.SysProxyType;
|
||||||
|
|
||||||
if (forceDisable && (type == ESysProxyType.ForcedChange || type == ESysProxyType.Pac))
|
if (forceDisable && (type == SysProxyType.ForcedChange || type == SysProxyType.Pac))
|
||||||
{
|
{
|
||||||
type = ESysProxyType.ForcedClear;
|
type = SysProxyType.ForcedClear;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int port = config.httpPort;
|
int port = config.HttpPort;
|
||||||
int socksPort = config.socksPort;
|
int socksPort = config.SocksPort;
|
||||||
if (port <= 0)
|
if (port <= 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (type == ESysProxyType.ForcedChange)
|
if (type == SysProxyType.ForcedChange)
|
||||||
{
|
{
|
||||||
var strExceptions = $"{config.constItem.defIEProxyExceptions};{config.systemProxyExceptions}";
|
var strExceptions = $"{config.ConstItem.defIEProxyExceptions};{config.SystemProxyExceptions}";
|
||||||
|
|
||||||
var strProxy = string.Empty;
|
var strProxy = string.Empty;
|
||||||
if (Utils.IsNullOrEmpty(config.systemProxyAdvancedProtocol))
|
if (string.IsNullOrEmpty(config.SystemProxyAdvancedProtocol))
|
||||||
{
|
{
|
||||||
strProxy = $"{Global.Loopback}:{port}";
|
strProxy = $"{Global.Loopback}:{port}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strProxy = config.systemProxyAdvancedProtocol
|
strProxy = config.SystemProxyAdvancedProtocol
|
||||||
.Replace("{ip}", Global.Loopback)
|
.Replace("{ip}", Global.Loopback)
|
||||||
.Replace("{http_port}", port.ToString())
|
.Replace("{http_port}", port.ToString())
|
||||||
.Replace("{socks_port}", socksPort.ToString());
|
.Replace("{socks_port}", socksPort.ToString());
|
||||||
}
|
}
|
||||||
SetIEProxy(true, strProxy, strExceptions);
|
SetIEProxy(true, strProxy, strExceptions);
|
||||||
}
|
}
|
||||||
else if (type == ESysProxyType.ForcedClear)
|
else if (type == SysProxyType.ForcedClear)
|
||||||
{
|
{
|
||||||
ResetIEProxy();
|
ResetIEProxy();
|
||||||
}
|
}
|
||||||
else if (type == ESysProxyType.Unchanged)
|
else if (type == SysProxyType.Unchanged)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else if (type == ESysProxyType.Pac)
|
else if (type == SysProxyType.Pac)
|
||||||
{
|
{
|
||||||
PacHandler.Start(Utils.GetConfigPath(), port, config.PacPort);
|
PacHandler.Start(Utils.GetConfigPath(), port, config.PacPort);
|
||||||
var strProxy = $"{Global.httpProtocol}{Global.Loopback}:{config.PacPort}/pac?t={DateTime.Now.Ticks}";
|
var strProxy = $"{Global.httpProtocol}{Global.Loopback}:{config.PacPort}/pac?t={DateTime.Now.Ticks}";
|
||||||
SetIEProxy(false, strProxy, "");
|
SetIEProxy(false, strProxy, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != ESysProxyType.Pac)
|
if (type != SysProxyType.Pac)
|
||||||
{
|
{
|
||||||
PacHandler.Stop();
|
PacHandler.Stop();
|
||||||
}
|
}
|
||||||
@@ -196,9 +196,8 @@ namespace ClashN.Handler
|
|||||||
}
|
}
|
||||||
catch (System.ComponentModel.Win32Exception e)
|
catch (System.ComponentModel.Win32Exception e)
|
||||||
{
|
{
|
||||||
|
|
||||||
// log the arguments
|
// log the arguments
|
||||||
throw new Exception(process.StartInfo.Arguments);
|
throw new Exception(process.StartInfo.Arguments, e);
|
||||||
}
|
}
|
||||||
string stderr = error.ToString();
|
string stderr = error.ToString();
|
||||||
string stdout = output.ToString();
|
string stdout = output.ToString();
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ namespace ClashN.Handler
|
|||||||
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, "clashN"));
|
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, "clashN"));
|
||||||
|
|
||||||
url = args.Msg;
|
url = args.Msg;
|
||||||
askToDownload(downloadHandle, url, true);
|
AskToDownload(downloadHandle, url, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -97,11 +97,11 @@ namespace ClashN.Handler
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, "clashN"));
|
_updateFunc(false, string.Format(ResUI.MsgStartUpdating, "clashN"));
|
||||||
CheckUpdateAsync(ECoreType.clashN);
|
CheckUpdateAsync(CoreKind.ClashN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void CheckUpdateCore(ECoreType type, Config config, Action<bool, string> update)
|
public void CheckUpdateCore(CoreKind type, Config config, Action<bool, string> update)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
_updateFunc = update;
|
_updateFunc = update;
|
||||||
@@ -144,7 +144,7 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, "Core"));
|
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, "Core"));
|
||||||
url = args.Msg;
|
url = args.Msg;
|
||||||
askToDownload(downloadHandle, url, true);
|
AskToDownload(downloadHandle, url, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,7 +164,7 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
_updateFunc(false, ResUI.MsgUpdateSubscriptionStart);
|
_updateFunc(false, ResUI.MsgUpdateSubscriptionStart);
|
||||||
|
|
||||||
if (config.profileItems == null || config.profileItems.Count <= 0)
|
if (config.ProfileItems == null || config.ProfileItems.Count <= 0)
|
||||||
{
|
{
|
||||||
_updateFunc(false, ResUI.MsgNoValidSubscription);
|
_updateFunc(false, ResUI.MsgNoValidSubscription);
|
||||||
return;
|
return;
|
||||||
@@ -174,17 +174,17 @@ namespace ClashN.Handler
|
|||||||
{
|
{
|
||||||
//Turn off system proxy
|
//Turn off system proxy
|
||||||
bool bSysProxyType = false;
|
bool bSysProxyType = false;
|
||||||
if (!blProxy && config.sysProxyType == ESysProxyType.ForcedChange)
|
if (!blProxy && config.SysProxyType == SysProxyType.ForcedChange)
|
||||||
{
|
{
|
||||||
bSysProxyType = true;
|
bSysProxyType = true;
|
||||||
config.sysProxyType = ESysProxyType.ForcedClear;
|
config.SysProxyType = SysProxyType.ForcedClear;
|
||||||
SysProxyHandle.UpdateSysProxy(config, false);
|
SysProxyHandle.UpdateSysProxy(config, false);
|
||||||
Thread.Sleep(3000);
|
Thread.Sleep(3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profileItems == null)
|
if (profileItems == null)
|
||||||
{
|
{
|
||||||
profileItems = config.profileItems;
|
profileItems = config.ProfileItems;
|
||||||
}
|
}
|
||||||
foreach (var item in profileItems)
|
foreach (var item in profileItems)
|
||||||
{
|
{
|
||||||
@@ -193,7 +193,7 @@ namespace ClashN.Handler
|
|||||||
string userAgent = item.userAgent.TrimEx();
|
string userAgent = item.userAgent.TrimEx();
|
||||||
string groupId = item.groupId.TrimEx();
|
string groupId = item.groupId.TrimEx();
|
||||||
string hashCode = $"{item.remarks}->";
|
string hashCode = $"{item.remarks}->";
|
||||||
if (item.enabled == false || Utils.IsNullOrEmpty(indexId) || Utils.IsNullOrEmpty(url))
|
if (item.enabled == false || string.IsNullOrEmpty(indexId) || string.IsNullOrEmpty(url))
|
||||||
{
|
{
|
||||||
_updateFunc(false, $"{hashCode}{ResUI.MsgSkipSubscriptionUpdate}");
|
_updateFunc(false, $"{hashCode}{ResUI.MsgSkipSubscriptionUpdate}");
|
||||||
continue;
|
continue;
|
||||||
@@ -203,11 +203,11 @@ namespace ClashN.Handler
|
|||||||
|
|
||||||
if (item.enableConvert)
|
if (item.enableConvert)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(config.constItem.subConvertUrl))
|
if (string.IsNullOrEmpty(config.ConstItem.subConvertUrl))
|
||||||
{
|
{
|
||||||
config.constItem.subConvertUrl = Global.SubConvertUrls[0];
|
config.ConstItem.subConvertUrl = Global.SubConvertUrls[0];
|
||||||
}
|
}
|
||||||
url = String.Format(config.constItem.subConvertUrl, Utils.UrlEncode(url));
|
url = String.Format(config.ConstItem.subConvertUrl, Utils.UrlEncode(url));
|
||||||
if (!url.Contains("config="))
|
if (!url.Contains("config="))
|
||||||
{
|
{
|
||||||
url += String.Format("&config={0}", Global.SubConvertConfig[0]);
|
url += String.Format("&config={0}", Global.SubConvertConfig[0]);
|
||||||
@@ -219,12 +219,12 @@ namespace ClashN.Handler
|
|||||||
_updateFunc(false, $"{hashCode}{args.GetException().Message}");
|
_updateFunc(false, $"{hashCode}{args.GetException().Message}");
|
||||||
};
|
};
|
||||||
var result = await downloadHandle.DownloadStringAsync(url, blProxy, userAgent);
|
var result = await downloadHandle.DownloadStringAsync(url, blProxy, userAgent);
|
||||||
if (blProxy && Utils.IsNullOrEmpty(result.Item1))
|
if (blProxy && string.IsNullOrEmpty(result.Item1))
|
||||||
{
|
{
|
||||||
result = await downloadHandle.DownloadStringAsync(url, false, userAgent);
|
result = await downloadHandle.DownloadStringAsync(url, false, userAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(result.Item1))
|
if (string.IsNullOrEmpty(result.Item1))
|
||||||
{
|
{
|
||||||
_updateFunc(false, $"{hashCode}{ResUI.MsgSubscriptionDecodingFailed}");
|
_updateFunc(false, $"{hashCode}{ResUI.MsgSubscriptionDecodingFailed}");
|
||||||
}
|
}
|
||||||
@@ -236,7 +236,7 @@ namespace ClashN.Handler
|
|||||||
_updateFunc(false, $"{hashCode}{result}");
|
_updateFunc(false, $"{hashCode}{result}");
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = ConfigHandler.AddBatchProfiles(ref config, result.Item1, indexId, groupId);
|
int ret = ConfigProc.AddBatchProfiles(ref config, result.Item1, indexId, groupId);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
item.updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
|
item.updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
|
||||||
@@ -282,7 +282,7 @@ namespace ClashN.Handler
|
|||||||
//restore system proxy
|
//restore system proxy
|
||||||
if (bSysProxyType)
|
if (bSysProxyType)
|
||||||
{
|
{
|
||||||
config.sysProxyType = ESysProxyType.ForcedChange;
|
config.SysProxyType = SysProxyType.ForcedChange;
|
||||||
SysProxyHandle.UpdateSysProxy(config, false);
|
SysProxyHandle.UpdateSysProxy(config, false);
|
||||||
}
|
}
|
||||||
_updateFunc(true, $"{ResUI.MsgUpdateSubscriptionEnd}");
|
_updateFunc(true, $"{ResUI.MsgUpdateSubscriptionEnd}");
|
||||||
@@ -340,12 +340,12 @@ namespace ClashN.Handler
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
askToDownload(downloadHandle, url, false);
|
AskToDownload(downloadHandle, url, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region private
|
#region private
|
||||||
|
|
||||||
private async void CheckUpdateAsync(ECoreType type)
|
private async void CheckUpdateAsync(CoreKind type)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -353,7 +353,7 @@ namespace ClashN.Handler
|
|||||||
string url = coreInfo.coreLatestUrl;
|
string url = coreInfo.coreLatestUrl;
|
||||||
|
|
||||||
var result = await (new DownloadHandle()).UrlRedirectAsync(url, true);
|
var result = await (new DownloadHandle()).UrlRedirectAsync(url, true);
|
||||||
if (!Utils.IsNullOrEmpty(result))
|
if (!string.IsNullOrEmpty(result))
|
||||||
{
|
{
|
||||||
responseHandler(type, result);
|
responseHandler(type, result);
|
||||||
}
|
}
|
||||||
@@ -377,7 +377,7 @@ namespace ClashN.Handler
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取Core版本
|
/// 获取Core版本
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private string getCoreVersion(ECoreType type)
|
private string getCoreVersion(CoreKind type)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -393,7 +393,7 @@ namespace ClashN.Handler
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Utils.IsNullOrEmpty(filePath))
|
if (string.IsNullOrEmpty(filePath))
|
||||||
{
|
{
|
||||||
string msg = string.Format(ResUI.NotFoundCore, @"");
|
string msg = string.Format(ResUI.NotFoundCore, @"");
|
||||||
return "";
|
return "";
|
||||||
@@ -420,7 +420,7 @@ namespace ClashN.Handler
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void responseHandler(ECoreType type, string redirectUrl)
|
private void responseHandler(CoreKind type, string redirectUrl)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -430,7 +430,7 @@ namespace ClashN.Handler
|
|||||||
string curVersion;
|
string curVersion;
|
||||||
string message;
|
string message;
|
||||||
string url;
|
string url;
|
||||||
if (type == ECoreType.clash)
|
if (type == CoreKind.Clash)
|
||||||
{
|
{
|
||||||
curVersion = getCoreVersion(type);
|
curVersion = getCoreVersion(type);
|
||||||
message = string.Format(ResUI.IsLatestCore, curVersion);
|
message = string.Format(ResUI.IsLatestCore, curVersion);
|
||||||
@@ -443,7 +443,7 @@ namespace ClashN.Handler
|
|||||||
url = string.Format(coreInfo.coreDownloadUrl32, version);
|
url = string.Format(coreInfo.coreDownloadUrl32, version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == ECoreType.clash_meta)
|
else if (type == CoreKind.ClashMeta)
|
||||||
{
|
{
|
||||||
curVersion = getCoreVersion(type);
|
curVersion = getCoreVersion(type);
|
||||||
message = string.Format(ResUI.IsLatestCore, curVersion);
|
message = string.Format(ResUI.IsLatestCore, curVersion);
|
||||||
@@ -456,7 +456,7 @@ namespace ClashN.Handler
|
|||||||
url = string.Format(coreInfo.coreDownloadUrl32, version);
|
url = string.Format(coreInfo.coreDownloadUrl32, version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == ECoreType.clashN)
|
else if (type == CoreKind.ClashN)
|
||||||
{
|
{
|
||||||
curVersion = FileVersionInfo.GetVersionInfo(Utils.GetExePath()).FileVersion.ToString();
|
curVersion = FileVersionInfo.GetVersionInfo(Utils.GetExePath()).FileVersion.ToString();
|
||||||
message = string.Format(ResUI.IsLatestN, curVersion);
|
message = string.Format(ResUI.IsLatestN, curVersion);
|
||||||
@@ -482,7 +482,7 @@ namespace ClashN.Handler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void askToDownload(DownloadHandle downloadHandle, string url, bool blAsk)
|
private void AskToDownload(DownloadHandle downloadHandle, string url, bool blAsk)
|
||||||
{
|
{
|
||||||
bool blDownload = false;
|
bool blDownload = false;
|
||||||
if (blAsk)
|
if (blAsk)
|
||||||
|
|||||||
@@ -2,36 +2,36 @@
|
|||||||
{
|
{
|
||||||
public class ClashConnections
|
public class ClashConnections
|
||||||
{
|
{
|
||||||
public ulong downloadTotal { get; set; }
|
public ulong DownloadTotal { get; set; }
|
||||||
public ulong uploadTotal { get; set; }
|
public ulong UploadTotal { get; set; }
|
||||||
public List<ConnectionItem> connections { get; set; }
|
public List<ConnectionItem> Connections { get; } = new List<ConnectionItem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ConnectionItem
|
public class ConnectionItem
|
||||||
{
|
{
|
||||||
public string id { get; set; }
|
public string Id { get; set; } = string.Empty;
|
||||||
public MetadataItem metadata { get; set; }
|
public MetadataItem metadata { get; set; }
|
||||||
public ulong upload { get; set; }
|
public ulong upload { get; set; }
|
||||||
public ulong download { get; set; }
|
public ulong download { get; set; }
|
||||||
public DateTime start { get; set; }
|
public DateTime start { get; set; }
|
||||||
public List<string> chains { get; set; }
|
public List<string> Chains { get; } = new List<string>();
|
||||||
public string rule { get; set; }
|
public string rule { get; set; }
|
||||||
public string rulePayload { get; set; }
|
public string rulePayload { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MetadataItem
|
public class MetadataItem
|
||||||
{
|
{
|
||||||
public string network { get; set; }
|
public string Network { get; set; }
|
||||||
public string type { get; set; }
|
public string Type { get; set; }
|
||||||
public string sourceIP { get; set; }
|
public string SourceIP { get; set; }
|
||||||
public string destinationIP { get; set; }
|
public string DestinationIP { get; set; }
|
||||||
public string sourcePort { get; set; }
|
public string SourcePort { get; set; }
|
||||||
public string destinationPort { get; set; }
|
public string DestinationPort { get; set; }
|
||||||
public string host { get; set; }
|
public string Host { get; set; }
|
||||||
public string dnsMode { get; set; }
|
public string DnsMode { get; set; }
|
||||||
public object uid { get; set; }
|
public object Uid { get; set; }
|
||||||
public string process { get; set; }
|
public string Process { get; set; }
|
||||||
public string processPath { get; set; }
|
public string ProcessPath { get; set; }
|
||||||
public string remoteDestination { get; set; }
|
public string RemoteDestination { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,13 +2,7 @@
|
|||||||
{
|
{
|
||||||
class ComboItem
|
class ComboItem
|
||||||
{
|
{
|
||||||
public int ID
|
public int ID { get; set; }
|
||||||
{
|
public string Text { get; set; }
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
public string Text
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace ClashN.Mode
|
namespace ClashN.Mode
|
||||||
{
|
{
|
||||||
@@ -10,69 +9,57 @@ namespace ClashN.Mode
|
|||||||
public class Config
|
public class Config
|
||||||
{
|
{
|
||||||
#region property
|
#region property
|
||||||
public int mixedPort { get; set; }
|
public int MixedPort { get; set; } = 7888;
|
||||||
|
|
||||||
public int httpPort { get; set; }
|
public int HttpPort { get; set; } = 7890;
|
||||||
|
|
||||||
public int socksPort { get; set; }
|
public int SocksPort { get; set; } = 7891;
|
||||||
|
|
||||||
public int APIPort { get; set; }
|
public int ApiPort { get; set; } = 9090;
|
||||||
|
|
||||||
public string logLevel { get; set; }
|
public string LogLevel { get; set; }
|
||||||
|
|
||||||
public bool enableIpv6 { get; set; }
|
public bool EnableIpv6 { get; set; }
|
||||||
|
|
||||||
public string indexId { get; set; }
|
public string IndexId { get; set; }
|
||||||
|
|
||||||
public ESysProxyType sysProxyType { get; set; }
|
public SysProxyType SysProxyType { get; set; }
|
||||||
|
|
||||||
public ERuleMode ruleMode { get; set; }
|
public ERuleMode ruleMode { get; set; }
|
||||||
|
|
||||||
public bool allowLANConn { get; set; }
|
public bool AllowLANConn { get; set; }
|
||||||
|
|
||||||
public bool autoRun { get; set; }
|
public bool AutoRun { get; set; }
|
||||||
|
|
||||||
public bool enableStatistics { get; set; }
|
public bool EnableStatistics { get; set; }
|
||||||
|
|
||||||
public string systemProxyExceptions { get; set; }
|
public string SystemProxyExceptions { get; set; }
|
||||||
public string systemProxyAdvancedProtocol { get; set; }
|
public string SystemProxyAdvancedProtocol { get; set; }
|
||||||
|
|
||||||
public int autoUpdateSubInterval { get; set; } = 10;
|
public int AutoUpdateSubInterval { get; set; } = 10;
|
||||||
public int autoDelayTestInterval { get; set; } = 10;
|
public int AutoDelayTestInterval { get; set; } = 10;
|
||||||
|
|
||||||
public bool enableSecurityProtocolTls13 { get; set; }
|
public bool EnableSecurityProtocolTls13 { get; set; }
|
||||||
|
|
||||||
public bool enableMixinContent { get; set; }
|
public bool EnableMixinContent { get; set; }
|
||||||
|
|
||||||
public int PacPort { get; set; }
|
public int PacPort { get; set; }
|
||||||
|
|
||||||
public bool autoHideStartup { get; set; }
|
public bool AutoHideStartup { get; set; }
|
||||||
|
|
||||||
public bool enableTun { get; set; }
|
public bool EnableTun { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region other entities
|
#region other entities
|
||||||
|
|
||||||
public List<ProfileItem> profileItems
|
public List<ProfileItem> ProfileItems { get; } = new List<ProfileItem>();
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UIItem uiItem
|
public UIItem? UiItem { get; set; }
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConstItem constItem
|
public ConstItem? ConstItem { get; set; }
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<KeyEventItem> globalHotkeys
|
public List<KeyShortcut> globalHotkeys { get; } = new List<KeyShortcut>();
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -80,25 +67,25 @@ namespace ClashN.Mode
|
|||||||
|
|
||||||
public int FindIndexId(string id)
|
public int FindIndexId(string id)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(id))
|
if (string.IsNullOrEmpty(id))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return profileItems.FindIndex(it => it.indexId == id);
|
return ProfileItems.FindIndex(it => it.indexId == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileItem GetProfileItem(string id)
|
public ProfileItem GetProfileItem(string id)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(id))
|
if (string.IsNullOrEmpty(id))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return profileItems.FirstOrDefault(it => it.indexId == id);
|
return ProfileItems.FirstOrDefault(it => it.indexId == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsActiveNode(ProfileItem item)
|
public bool IsActiveNode(ProfileItem item)
|
||||||
{
|
{
|
||||||
if (!Utils.IsNullOrEmpty(item.indexId) && item.indexId == indexId)
|
if (!string.IsNullOrEmpty(item.indexId) && item.indexId == IndexId)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -135,44 +122,20 @@ namespace ClashN.Mode
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public string indexId
|
public string indexId { get; set; }
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int sort
|
public int sort { get; set; }
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string address
|
public string address { get; set; }
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string remarks
|
public string remarks { get; set; }
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string testResult
|
public string testResult { get; set; }
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string groupId
|
public string groupId { get; set; } = string.Empty;
|
||||||
{
|
public CoreKind? coreType { get; set; }
|
||||||
get; set;
|
|
||||||
} = string.Empty;
|
|
||||||
public ECoreType? coreType
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string url
|
public string url { get; set; }
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool enabled { get; set; } = true;
|
public bool enabled { get; set; } = true;
|
||||||
|
|
||||||
@@ -228,18 +191,4 @@ namespace ClashN.Mode
|
|||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class KeyEventItem
|
|
||||||
{
|
|
||||||
public EGlobalHotkey eGlobalHotkey { get; set; }
|
|
||||||
|
|
||||||
public bool Alt { get; set; }
|
|
||||||
|
|
||||||
public bool Control { get; set; }
|
|
||||||
|
|
||||||
public bool Shift { get; set; }
|
|
||||||
|
|
||||||
public Keys? KeyCode { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
[Serializable]
|
[Serializable]
|
||||||
public class CoreInfo
|
public class CoreInfo
|
||||||
{
|
{
|
||||||
public ECoreType coreType { get; set; }
|
public CoreKind coreType { get; set; }
|
||||||
|
|
||||||
public List<string> coreExes { get; set; }
|
public List<string> coreExes { get; set; }
|
||||||
|
|
||||||
|
|||||||
11
clashN/clashN/Mode/CoreKind.cs
Normal file
11
clashN/clashN/Mode/CoreKind.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
namespace ClashN.Mode
|
||||||
|
{
|
||||||
|
public enum CoreKind
|
||||||
|
{
|
||||||
|
Clash = 1,
|
||||||
|
ClashMeta = 2,
|
||||||
|
ClashPremium = 3,
|
||||||
|
ClashN = 99
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
|
|
||||||
namespace ClashN.Mode
|
|
||||||
{
|
|
||||||
public enum ECoreType
|
|
||||||
{
|
|
||||||
clash = 1,
|
|
||||||
clash_meta = 2,
|
|
||||||
clash_premium = 3,
|
|
||||||
clashN = 99
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
namespace ClashN.Mode
|
namespace ClashN.Mode
|
||||||
{
|
{
|
||||||
public enum EGlobalHotkey
|
public enum GlobalHotkeyAction
|
||||||
{
|
{
|
||||||
ShowForm = 0,
|
ShowForm = 0,
|
||||||
SystemProxyClear = 1,
|
SystemProxyClear = 1,
|
||||||
18
clashN/clashN/Mode/KeyShortcut.cs
Normal file
18
clashN/clashN/Mode/KeyShortcut.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace ClashN.Mode
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public struct KeyShortcut
|
||||||
|
{
|
||||||
|
public GlobalHotkeyAction GlobalHotkey { get; set; }
|
||||||
|
|
||||||
|
public bool Alt { get; set; }
|
||||||
|
|
||||||
|
public bool Control { get; set; }
|
||||||
|
|
||||||
|
public bool Shift { get; set; }
|
||||||
|
|
||||||
|
public Keys? KeyCode { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
namespace ClashN.Mode
|
namespace ClashN.Mode
|
||||||
{
|
{
|
||||||
public enum EMove
|
public enum MovementTarget
|
||||||
{
|
{
|
||||||
Top = 1,
|
Top = 1,
|
||||||
Up = 2,
|
Up = 2,
|
||||||
@@ -4,15 +4,9 @@ namespace ClashN.Mode
|
|||||||
{
|
{
|
||||||
public class ProfileItemModel : ProfileItem
|
public class ProfileItemModel : ProfileItem
|
||||||
{
|
{
|
||||||
public bool isActive { get; set; }
|
public bool IsActive { get; set; }
|
||||||
public bool HasUrl
|
public bool HasUrl => string.IsNullOrEmpty(url);
|
||||||
{
|
public bool HasAddress => string.IsNullOrEmpty(address);
|
||||||
get { return !url.IsNullOrEmpty(); }
|
|
||||||
}
|
|
||||||
public bool HasAddress
|
|
||||||
{
|
|
||||||
get { return !address.IsNullOrEmpty(); }
|
|
||||||
}
|
|
||||||
public string StrUpdateTime
|
public string StrUpdateTime
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -25,14 +19,8 @@ namespace ClashN.Mode
|
|||||||
return dateTime.AddSeconds(updateTime).ToLocalTime().ToString("MM-dd HH:mm");
|
return dateTime.AddSeconds(updateTime).ToLocalTime().ToString("MM-dd HH:mm");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public string TrafficUsed
|
public string TrafficUsed => Utils.HumanFy(uploadRemote + downloadRemote);
|
||||||
{
|
public string TrafficTotal => totalRemote <= 0 ? "∞" : Utils.HumanFy(totalRemote);
|
||||||
get { return Utils.HumanFy(uploadRemote + downloadRemote); }
|
|
||||||
}
|
|
||||||
public string TrafficTotal
|
|
||||||
{
|
|
||||||
get { return totalRemote <= 0 ? "∞" : Utils.HumanFy(totalRemote); }
|
|
||||||
}
|
|
||||||
public string StrExpireTime
|
public string StrExpireTime
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|||||||
@@ -3,21 +3,9 @@
|
|||||||
[Serializable]
|
[Serializable]
|
||||||
class ServerTestItem
|
class ServerTestItem
|
||||||
{
|
{
|
||||||
public string indexId
|
public string IndexId { get; set; }
|
||||||
{
|
public string Address { get; set; }
|
||||||
get; set;
|
public int Port { get; set; }
|
||||||
}
|
public bool AllowTest { get; set; }
|
||||||
public string address
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
public int port
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
public bool allowTest
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
namespace ClashN.Mode
|
namespace ClashN.Mode
|
||||||
{
|
{
|
||||||
public enum ESysProxyType
|
public enum SysProxyType
|
||||||
{
|
{
|
||||||
ForcedClear = 0,
|
ForcedClear = 0,
|
||||||
ForcedChange = 1,
|
ForcedChange = 1,
|
||||||
@@ -81,7 +81,7 @@ namespace ClashN.Tool
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!Utils.IsNullOrEmpty(ignoredName) && entry.Name.Contains(ignoredName))
|
if (!string.IsNullOrEmpty(ignoredName) && entry.Name.Contains(ignoredName))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,16 @@ namespace ClashN.Tool
|
|||||||
{
|
{
|
||||||
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName)
|
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName)
|
||||||
{
|
{
|
||||||
return _OrderBy<T>(query, propertyName, false);
|
return OrderBy<T>(query, propertyName, false);
|
||||||
}
|
|
||||||
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName)
|
|
||||||
{
|
|
||||||
return _OrderBy<T>(query, propertyName, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static IOrderedQueryable<T> _OrderBy<T>(IQueryable<T> query, string propertyName, bool isDesc)
|
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName)
|
||||||
|
{
|
||||||
|
return OrderBy<T>(query, propertyName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static IOrderedQueryable<T> OrderBy<T>(IQueryable<T> query, string propertyName, bool isDesc)
|
||||||
{
|
{
|
||||||
string methodname = (isDesc) ? "OrderByDescendingInternal" : "OrderByInternal";
|
string methodname = (isDesc) ? "OrderByDescendingInternal" : "OrderByInternal";
|
||||||
|
|
||||||
@@ -25,17 +27,21 @@ namespace ClashN.Tool
|
|||||||
|
|
||||||
return (IOrderedQueryable<T>)method.Invoke(null, new object[] { query, memberProp });
|
return (IOrderedQueryable<T>)method.Invoke(null, new object[] { query, memberProp });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IOrderedQueryable<T> OrderByInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
|
public static IOrderedQueryable<T> OrderByInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
|
||||||
{//public
|
|
||||||
return query.OrderBy(_GetLamba<T, TProp>(memberProperty));
|
|
||||||
}
|
|
||||||
public static IOrderedQueryable<T> OrderByDescendingInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
|
|
||||||
{//public
|
|
||||||
return query.OrderByDescending(_GetLamba<T, TProp>(memberProperty));
|
|
||||||
}
|
|
||||||
static Expression<Func<T, TProp>> _GetLamba<T, TProp>(PropertyInfo memberProperty)
|
|
||||||
{
|
{
|
||||||
if (memberProperty.PropertyType != typeof(TProp)) throw new Exception();
|
return query.OrderBy(GetLambda<T, TProp>(memberProperty));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IOrderedQueryable<T> OrderByDescendingInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)
|
||||||
|
{
|
||||||
|
return query.OrderByDescending(GetLambda<T, TProp>(memberProperty));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Expression<Func<T, TProp>> GetLambda<T, TProp>(PropertyInfo memberProperty)
|
||||||
|
{
|
||||||
|
if (memberProperty.PropertyType != typeof(TProp))
|
||||||
|
throw new Exception();
|
||||||
|
|
||||||
var thisArg = Expression.Parameter(typeof(T));
|
var thisArg = Expression.Parameter(typeof(T));
|
||||||
var lamba = Expression.Lambda<Func<T, TProp>>(Expression.Property(thisArg, memberProperty), thisArg);
|
var lamba = Expression.Lambda<Func<T, TProp>>(Expression.Property(thisArg, memberProperty), thisArg);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ using System.Text.RegularExpressions;
|
|||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using YamlDotNet.Serialization;
|
using YamlDotNet.Serialization;
|
||||||
|
using YamlDotNet.Serialization.NamingConventions;
|
||||||
using ZXing;
|
using ZXing;
|
||||||
using ZXing.Common;
|
using ZXing.Common;
|
||||||
using ZXing.QrCode;
|
using ZXing.QrCode;
|
||||||
@@ -407,7 +408,7 @@ namespace ClashN
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text"></param>
|
/// <param name="text"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool IsNullOrEmpty(string text)
|
public static bool IsNullOrEmpty(string? text)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(text))
|
if (string.IsNullOrEmpty(text))
|
||||||
{
|
{
|
||||||
@@ -846,13 +847,13 @@ namespace ClashN
|
|||||||
string location = GetExePath();
|
string location = GetExePath();
|
||||||
if (blFull)
|
if (blFull)
|
||||||
{
|
{
|
||||||
return string.Format("clashN - V{0} - {1}",
|
return string.Format("ClashN - V{0} - {1}",
|
||||||
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString(),
|
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString(),
|
||||||
File.GetLastWriteTime(location).ToString("yyyy/MM/dd"));
|
File.GetLastWriteTime(location).ToString("yyyy/MM/dd"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return string.Format("clashN/{0}",
|
return string.Format("ClashN/{0}",
|
||||||
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString());
|
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -889,9 +890,9 @@ namespace ClashN
|
|||||||
/// 获取剪贴板数
|
/// 获取剪贴板数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string GetClipboardData()
|
public static string? GetClipboardData()
|
||||||
{
|
{
|
||||||
string strData = string.Empty;
|
string? strData = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -900,7 +901,8 @@ namespace ClashN
|
|||||||
{
|
{
|
||||||
strData = data.GetData(DataFormats.UnicodeText).ToString();
|
strData = data.GetData(DataFormats.UnicodeText).ToString();
|
||||||
}
|
}
|
||||||
if (Utils.IsNullOrEmpty(strData))
|
|
||||||
|
if (string.IsNullOrEmpty(strData))
|
||||||
{
|
{
|
||||||
var file = Clipboard.GetFileDropList();
|
var file = Clipboard.GetFileDropList();
|
||||||
if (file.Count > 0)
|
if (file.Count > 0)
|
||||||
@@ -915,6 +917,7 @@ namespace ClashN
|
|||||||
{
|
{
|
||||||
SaveLog(ex.Message, ex);
|
SaveLog(ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return strData;
|
return strData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1099,7 +1102,7 @@ namespace ClashN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetBinPath(string filename, ECoreType? coreType = null)
|
public static string GetBinPath(string filename, CoreKind? coreType = null)
|
||||||
{
|
{
|
||||||
string _tempPath = Path.Combine(StartupPath(), "bin");
|
string _tempPath = Path.Combine(StartupPath(), "bin");
|
||||||
if (!Directory.Exists(_tempPath))
|
if (!Directory.Exists(_tempPath))
|
||||||
@@ -1223,7 +1226,7 @@ namespace ClashN
|
|||||||
public static T FromYaml<T>(string str)
|
public static T FromYaml<T>(string str)
|
||||||
{
|
{
|
||||||
var deserializer = new DeserializerBuilder()
|
var deserializer = new DeserializerBuilder()
|
||||||
//.WithNamingConvention(UnderscoredNamingConvention.Instance)
|
.WithNamingConvention(PascalCaseNamingConvention.Instance)
|
||||||
.Build();
|
.Build();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1245,7 +1248,7 @@ namespace ClashN
|
|||||||
public static string ToYaml(Object obj)
|
public static string ToYaml(Object obj)
|
||||||
{
|
{
|
||||||
var serializer = new SerializerBuilder()
|
var serializer = new SerializerBuilder()
|
||||||
//.WithNamingConvention(CamelCaseNamingConvention.Instance)
|
.WithNamingConvention(HyphenatedNamingConvention.Instance)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
string result = string.Empty;
|
string result = string.Empty;
|
||||||
|
|||||||
@@ -15,6 +15,14 @@ namespace ClashN.ViewModels
|
|||||||
public class ConnectionsViewModel : ReactiveObject
|
public class ConnectionsViewModel : ReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
private static Config _config;
|
||||||
|
|
||||||
|
static ConnectionsViewModel()
|
||||||
|
{
|
||||||
|
_config = LazyConfig.Instance.Config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private NoticeHandler? _noticeHandler;
|
private NoticeHandler? _noticeHandler;
|
||||||
private IObservableCollection<ConnectionModel> _connectionItems = new ObservableCollectionExtended<ConnectionModel>();
|
private IObservableCollection<ConnectionModel> _connectionItems = new ObservableCollectionExtended<ConnectionModel>();
|
||||||
|
|
||||||
@@ -35,11 +43,10 @@ namespace ClashN.ViewModels
|
|||||||
public ConnectionsViewModel()
|
public ConnectionsViewModel()
|
||||||
{
|
{
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
|
||||||
|
|
||||||
AutoRefreshInterval = 10;
|
AutoRefreshInterval = 10;
|
||||||
SortingSelected = _config.uiItem.connectionsSorting;
|
SortingSelected = _config.UiItem.connectionsSorting;
|
||||||
AutoRefresh = _config.uiItem.connectionsAutoRefresh;
|
AutoRefresh = _config.UiItem.connectionsAutoRefresh;
|
||||||
|
|
||||||
var canEditRemove = this.WhenAnyValue(
|
var canEditRemove = this.WhenAnyValue(
|
||||||
x => x.SelectedSource,
|
x => x.SelectedSource,
|
||||||
@@ -47,13 +54,13 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.SortingSelected,
|
x => x.SortingSelected,
|
||||||
y => y != null && y >= 0)
|
y => y >= 0)
|
||||||
.Subscribe(c => DoSortingSelected(c));
|
.Subscribe(c => DoSortingSelected(c));
|
||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.AutoRefresh,
|
x => x.AutoRefresh,
|
||||||
y => y == true)
|
y => y == true)
|
||||||
.Subscribe(c => { _config.uiItem.connectionsAutoRefresh = AutoRefresh; });
|
.Subscribe(c => { _config.UiItem.connectionsAutoRefresh = AutoRefresh; });
|
||||||
|
|
||||||
ConnectionCloseCmd = ReactiveCommand.Create(() =>
|
ConnectionCloseCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
@@ -74,9 +81,9 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (SortingSelected != _config.uiItem.connectionsSorting)
|
if (SortingSelected != _config.UiItem.connectionsSorting)
|
||||||
{
|
{
|
||||||
_config.uiItem.connectionsSorting = SortingSelected;
|
_config.UiItem.connectionsSorting = SortingSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetClashConnections();
|
GetClashConnections();
|
||||||
@@ -119,7 +126,7 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
Application.Current.Dispatcher.Invoke((Action)(() =>
|
Application.Current.Dispatcher.Invoke((Action)(() =>
|
||||||
{
|
{
|
||||||
RefreshConnections(it?.connections!);
|
RefreshConnections(it?.Connections!);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -134,10 +141,10 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
ConnectionModel model = new();
|
ConnectionModel model = new();
|
||||||
|
|
||||||
model.id = item.id;
|
model.id = item.Id;
|
||||||
model.network = item.metadata.network;
|
model.network = item.metadata.Network;
|
||||||
model.type = item.metadata.type;
|
model.type = item.metadata.Type;
|
||||||
model.host = $"{(item.metadata.host.IsNullOrEmpty() ? item.metadata.destinationIP : item.metadata.host)}:{item.metadata.destinationPort}";
|
model.host = $"{(item.metadata.Host.IsNullOrEmpty() ? item.metadata.DestinationIP : item.metadata.Host)}:{item.metadata.DestinationPort}";
|
||||||
var sp = (dtNow - item.start);
|
var sp = (dtNow - item.start);
|
||||||
model.time = sp.TotalSeconds < 0 ? 1 : sp.TotalSeconds;
|
model.time = sp.TotalSeconds < 0 ? 1 : sp.TotalSeconds;
|
||||||
model.upload = item.upload;
|
model.upload = item.upload;
|
||||||
@@ -145,7 +152,7 @@ namespace ClashN.ViewModels
|
|||||||
model.uploadTraffic = $"{Utils.HumanFy(item.upload)}";
|
model.uploadTraffic = $"{Utils.HumanFy(item.upload)}";
|
||||||
model.downloadTraffic = $"{Utils.HumanFy(item.download)}";
|
model.downloadTraffic = $"{Utils.HumanFy(item.download)}";
|
||||||
model.elapsed = sp.ToString(@"hh\:mm\:ss");
|
model.elapsed = sp.ToString(@"hh\:mm\:ss");
|
||||||
model.chain = item.chains.Count > 0 ? item.chains[0] : String.Empty;
|
model.chain = item.Chains.Count > 0 ? item.Chains[0] : String.Empty;
|
||||||
|
|
||||||
lstModel.Add(model);
|
lstModel.Add(model);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
public HelpViewModel()
|
public HelpViewModel()
|
||||||
{
|
{
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.Config;
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
|
|
||||||
CheckUpdateCmd = ReactiveCommand.Create(() =>
|
CheckUpdateCmd = ReactiveCommand.Create(() =>
|
||||||
@@ -28,11 +28,11 @@ namespace ClashN.ViewModels
|
|||||||
});
|
});
|
||||||
CheckUpdateClashCoreCmd = ReactiveCommand.Create(() =>
|
CheckUpdateClashCoreCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
CheckUpdateCore(ECoreType.clash);
|
CheckUpdateCore(CoreKind.Clash);
|
||||||
});
|
});
|
||||||
CheckUpdateClashMetaCoreCmd = ReactiveCommand.Create(() =>
|
CheckUpdateClashMetaCoreCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
CheckUpdateCore(ECoreType.clash_meta);
|
CheckUpdateCore(CoreKind.ClashMeta);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ namespace ClashN.ViewModels
|
|||||||
};
|
};
|
||||||
(new UpdateHandle()).CheckUpdateGuiN(_config, _updateUI);
|
(new UpdateHandle()).CheckUpdateGuiN(_config, _updateUI);
|
||||||
}
|
}
|
||||||
private void CheckUpdateCore(ECoreType type)
|
private void CheckUpdateCore(CoreKind type)
|
||||||
{
|
{
|
||||||
void _updateUI(bool success, string msg)
|
void _updateUI(bool success, string msg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue)
|
public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue)
|
||||||
{
|
{
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.Config;
|
||||||
|
|
||||||
Locator.CurrentMutable.RegisterLazySingleton(() => new NoticeHandler(snackbarMessageQueue), typeof(NoticeHandler));
|
Locator.CurrentMutable.RegisterLazySingleton(() => new NoticeHandler(snackbarMessageQueue), typeof(NoticeHandler));
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
@@ -112,7 +112,7 @@ namespace ClashN.ViewModels
|
|||||||
GetPromotionView = new();
|
GetPromotionView = new();
|
||||||
|
|
||||||
RestoreUI();
|
RestoreUI();
|
||||||
if (_config.autoHideStartup)
|
if (_config.AutoHideStartup)
|
||||||
{
|
{
|
||||||
Observable.Range(1, 1)
|
Observable.Range(1, 1)
|
||||||
.Delay(TimeSpan.FromSeconds(1))
|
.Delay(TimeSpan.FromSeconds(1))
|
||||||
@@ -129,19 +129,19 @@ namespace ClashN.ViewModels
|
|||||||
//System proxy
|
//System proxy
|
||||||
SystemProxyClearCmd = ReactiveCommand.Create(() =>
|
SystemProxyClearCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
SetListenerType(ESysProxyType.ForcedClear);
|
SetListenerType(SysProxyType.ForcedClear);
|
||||||
});//, this.WhenAnyValue(x => x.BlSystemProxyClear, y => !y));
|
});//, this.WhenAnyValue(x => x.BlSystemProxyClear, y => !y));
|
||||||
SystemProxySetCmd = ReactiveCommand.Create(() =>
|
SystemProxySetCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
SetListenerType(ESysProxyType.ForcedChange);
|
SetListenerType(SysProxyType.ForcedChange);
|
||||||
});//, this.WhenAnyValue(x => x.BlSystemProxySet, y => !y));
|
});//, this.WhenAnyValue(x => x.BlSystemProxySet, y => !y));
|
||||||
SystemProxyNothingCmd = ReactiveCommand.Create(() =>
|
SystemProxyNothingCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
SetListenerType(ESysProxyType.Unchanged);
|
SetListenerType(SysProxyType.Unchanged);
|
||||||
});//, this.WhenAnyValue(x => x.BlSystemProxyNothing, y => !y));
|
});//, this.WhenAnyValue(x => x.BlSystemProxyNothing, y => !y));
|
||||||
SystemProxyPacCmd = ReactiveCommand.Create(() =>
|
SystemProxyPacCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
SetListenerType(ESysProxyType.Pac);
|
SetListenerType(SysProxyType.Pac);
|
||||||
});//, this.WhenAnyValue(x => x.BlSystemProxyNothing, y => !y));
|
});//, this.WhenAnyValue(x => x.BlSystemProxyNothing, y => !y));
|
||||||
|
|
||||||
//Rule mode
|
//Rule mode
|
||||||
@@ -195,18 +195,17 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
Application.Current.Dispatcher.Invoke((Action)(() =>
|
Application.Current.Dispatcher.Invoke((Action)(() =>
|
||||||
{
|
{
|
||||||
string clipboardData = Utils.GetClipboardData();
|
string? clipboardData = Utils.GetClipboardData();
|
||||||
if (state != null)
|
if (state != null && clipboardData != null)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(clipboardData) || !clipboardData.StartsWith(Global.clashProtocol))
|
if (string.IsNullOrEmpty(clipboardData) || !clipboardData.StartsWith(Global.clashProtocol))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!blFirst)
|
if (!blFirst)
|
||||||
{
|
|
||||||
ShowHideWindow(true);
|
ShowHideWindow(true);
|
||||||
}
|
|
||||||
|
|
||||||
Locator.Current.GetService<ProfilesViewModel>()?.AddProfilesViaClipboard(true);
|
Locator.Current.GetService<ProfilesViewModel>()?.AddProfilesViaClipboard(true);
|
||||||
}));
|
}));
|
||||||
@@ -229,7 +228,7 @@ namespace ClashN.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
StorageUI();
|
StorageUI();
|
||||||
ConfigHandler.SaveConfig(ref _config);
|
ConfigProc.SaveConfig(_config);
|
||||||
//statistics?.SaveToFile();
|
//statistics?.SaveToFile();
|
||||||
statistics?.Close();
|
statistics?.Close();
|
||||||
}
|
}
|
||||||
@@ -245,20 +244,20 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
switch (Utils.ToInt(e.Name))
|
switch (Utils.ToInt(e.Name))
|
||||||
{
|
{
|
||||||
case (int)EGlobalHotkey.ShowForm:
|
case (int)GlobalHotkeyAction.ShowForm:
|
||||||
ShowHideWindow(null);
|
ShowHideWindow(null);
|
||||||
break;
|
break;
|
||||||
case (int)EGlobalHotkey.SystemProxyClear:
|
case (int)GlobalHotkeyAction.SystemProxyClear:
|
||||||
SetListenerType(ESysProxyType.ForcedClear);
|
SetListenerType(SysProxyType.ForcedClear);
|
||||||
break;
|
break;
|
||||||
case (int)EGlobalHotkey.SystemProxySet:
|
case (int)GlobalHotkeyAction.SystemProxySet:
|
||||||
SetListenerType(ESysProxyType.ForcedChange);
|
SetListenerType(SysProxyType.ForcedChange);
|
||||||
break;
|
break;
|
||||||
case (int)EGlobalHotkey.SystemProxyUnchanged:
|
case (int)GlobalHotkeyAction.SystemProxyUnchanged:
|
||||||
SetListenerType(ESysProxyType.Unchanged);
|
SetListenerType(SysProxyType.Unchanged);
|
||||||
break;
|
break;
|
||||||
case (int)EGlobalHotkey.SystemProxyPac:
|
case (int)GlobalHotkeyAction.SystemProxyPac:
|
||||||
SetListenerType(ESysProxyType.Pac);
|
SetListenerType(SysProxyType.Pac);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
@@ -273,7 +272,7 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
coreHandler = new CoreHandler(UpdateHandler);
|
coreHandler = new CoreHandler(UpdateHandler);
|
||||||
|
|
||||||
if (_config.enableStatistics)
|
if (_config.EnableStatistics)
|
||||||
{
|
{
|
||||||
statistics = new StatisticsHandler(_config, UpdateStatisticsHandler);
|
statistics = new StatisticsHandler(_config, UpdateStatisticsHandler);
|
||||||
}
|
}
|
||||||
@@ -346,10 +345,10 @@ namespace ClashN.ViewModels
|
|||||||
});
|
});
|
||||||
|
|
||||||
Global.reloadCore = false;
|
Global.reloadCore = false;
|
||||||
ConfigHandler.SaveConfig(ref _config, false);
|
ConfigProc.SaveConfig(_config, false);
|
||||||
//statistics?.SaveToFile();
|
//statistics?.SaveToFile();
|
||||||
|
|
||||||
ChangePACButtonStatus(_config.sysProxyType);
|
ChangePACButtonStatus(_config.SysProxyType);
|
||||||
SetRuleMode(_config.ruleMode);
|
SetRuleMode(_config.ruleMode);
|
||||||
|
|
||||||
Locator.Current.GetService<ProxiesViewModel>()?.ProxiesReload();
|
Locator.Current.GetService<ProxiesViewModel>()?.ProxiesReload();
|
||||||
@@ -359,10 +358,10 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
public void CloseCore()
|
public void CloseCore()
|
||||||
{
|
{
|
||||||
ConfigHandler.SaveConfig(ref _config, false);
|
ConfigProc.SaveConfig(_config, false);
|
||||||
//statistics?.SaveToFile();
|
//statistics?.SaveToFile();
|
||||||
|
|
||||||
ChangePACButtonStatus(ESysProxyType.ForcedClear);
|
ChangePACButtonStatus(SysProxyType.ForcedClear);
|
||||||
|
|
||||||
coreHandler.CoreStop();
|
coreHandler.CoreStop();
|
||||||
}
|
}
|
||||||
@@ -370,30 +369,30 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
#region System proxy and Rule mode
|
#region System proxy and Rule mode
|
||||||
|
|
||||||
public void SetListenerType(ESysProxyType type)
|
public void SetListenerType(SysProxyType type)
|
||||||
{
|
{
|
||||||
if (_config.sysProxyType == type)
|
if (_config.SysProxyType == type)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_config.sysProxyType = type;
|
_config.SysProxyType = type;
|
||||||
ChangePACButtonStatus(type);
|
ChangePACButtonStatus(type);
|
||||||
|
|
||||||
Locator.Current.GetService<ProxiesViewModel>()?.ReloadSystemProxySelected();
|
Locator.Current.GetService<ProxiesViewModel>()?.ReloadSystemProxySelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ChangePACButtonStatus(ESysProxyType type)
|
private void ChangePACButtonStatus(SysProxyType type)
|
||||||
{
|
{
|
||||||
SysProxyHandle.UpdateSysProxy(_config, false);
|
SysProxyHandle.UpdateSysProxy(_config, false);
|
||||||
|
|
||||||
BlSystemProxyClear = (type == ESysProxyType.ForcedClear);
|
BlSystemProxyClear = (type == SysProxyType.ForcedClear);
|
||||||
BlSystemProxySet = (type == ESysProxyType.ForcedChange);
|
BlSystemProxySet = (type == SysProxyType.ForcedChange);
|
||||||
BlSystemProxyNothing = (type == ESysProxyType.Unchanged);
|
BlSystemProxyNothing = (type == SysProxyType.Unchanged);
|
||||||
BlSystemProxyPac = (type == ESysProxyType.Pac);
|
BlSystemProxyPac = (type == SysProxyType.Pac);
|
||||||
|
|
||||||
_noticeHandler?.SendMessage($"Change system proxy", true);
|
_noticeHandler?.SendMessage($"Change system proxy", true);
|
||||||
|
|
||||||
ConfigHandler.SaveConfig(ref _config, false);
|
ConfigProc.SaveConfig(_config, false);
|
||||||
|
|
||||||
//mainMsgControl.DisplayToolStatus(config);
|
//mainMsgControl.DisplayToolStatus(config);
|
||||||
|
|
||||||
@@ -422,7 +421,7 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
_noticeHandler?.SendMessage($"Set rule mode {_config.ruleMode.ToString()}->{mode.ToString()}", true);
|
_noticeHandler?.SendMessage($"Set rule mode {_config.ruleMode.ToString()}->{mode.ToString()}", true);
|
||||||
_config.ruleMode = mode;
|
_config.ruleMode = mode;
|
||||||
ConfigHandler.SaveConfig(ref _config, false);
|
ConfigProc.SaveConfig(_config, false);
|
||||||
|
|
||||||
if (mode != ERuleMode.Unchanged)
|
if (mode != ERuleMode.Unchanged)
|
||||||
{
|
{
|
||||||
@@ -459,11 +458,11 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
private void RestoreUI()
|
private void RestoreUI()
|
||||||
{
|
{
|
||||||
ModifyTheme(_config.uiItem.colorModeDark);
|
ModifyTheme(_config.UiItem.colorModeDark);
|
||||||
|
|
||||||
if (!_config.uiItem.colorPrimaryName.IsNullOrEmpty())
|
if (!_config.UiItem.colorPrimaryName.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
var swatch = new SwatchesProvider().Swatches.FirstOrDefault(t => t.Name == _config.uiItem.colorPrimaryName);
|
var swatch = new SwatchesProvider().Swatches.FirstOrDefault(t => t.Name == _config.UiItem.colorPrimaryName);
|
||||||
if (swatch != null
|
if (swatch != null
|
||||||
&& swatch.ExemplarHue != null
|
&& swatch.ExemplarHue != null
|
||||||
&& swatch.ExemplarHue?.Color != null)
|
&& swatch.ExemplarHue?.Color != null)
|
||||||
@@ -477,10 +476,10 @@ namespace ClashN.ViewModels
|
|||||||
// this.Location = config.uiItem.mainLocation;
|
// this.Location = config.uiItem.mainLocation;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (_config.uiItem.mainWidth > 0 && _config.uiItem.mainHeight > 0)
|
if (_config.UiItem.mainWidth > 0 && _config.UiItem.mainHeight > 0)
|
||||||
{
|
{
|
||||||
Application.Current.MainWindow.Width = _config.uiItem.mainWidth;
|
Application.Current.MainWindow.Width = _config.UiItem.mainWidth;
|
||||||
Application.Current.MainWindow.Height = _config.uiItem.mainHeight;
|
Application.Current.MainWindow.Height = _config.UiItem.mainHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntPtr hWnd = new WindowInteropHelper(Application.Current.MainWindow).EnsureHandle();
|
IntPtr hWnd = new WindowInteropHelper(Application.Current.MainWindow).EnsureHandle();
|
||||||
@@ -496,8 +495,8 @@ namespace ClashN.ViewModels
|
|||||||
}
|
}
|
||||||
private void StorageUI()
|
private void StorageUI()
|
||||||
{
|
{
|
||||||
_config.uiItem.mainWidth = Application.Current.MainWindow.Width;
|
_config.UiItem.mainWidth = Application.Current.MainWindow.Width;
|
||||||
_config.uiItem.mainHeight = Application.Current.MainWindow.Height;
|
_config.UiItem.mainHeight = Application.Current.MainWindow.Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyTheme(bool isDarkTheme)
|
public void ModifyTheme(bool isDarkTheme)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace ClashN.ViewModels
|
|||||||
public ProfileEditViewModel(ProfileItem profileItem, PorfileEditWindow view)
|
public ProfileEditViewModel(ProfileItem profileItem, PorfileEditWindow view)
|
||||||
{
|
{
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.Config;
|
||||||
|
|
||||||
if (profileItem.indexId.IsNullOrEmpty())
|
if (profileItem.indexId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
@@ -44,7 +44,7 @@ namespace ClashN.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
_view = view;
|
_view = view;
|
||||||
CoreType = (SelectedSource.coreType ?? ECoreType.clash).ToString();
|
CoreType = (SelectedSource.coreType ?? CoreKind.Clash).ToString();
|
||||||
|
|
||||||
BrowseProfileCmd = ReactiveCommand.Create(() =>
|
BrowseProfileCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
@@ -61,25 +61,25 @@ namespace ClashN.ViewModels
|
|||||||
SaveProfile();
|
SaveProfile();
|
||||||
});
|
});
|
||||||
|
|
||||||
Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);
|
Utils.SetDarkBorder(view, _config.UiItem.colorModeDark);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveProfile()
|
private void SaveProfile()
|
||||||
{
|
{
|
||||||
string remarks = SelectedSource.remarks;
|
string remarks = SelectedSource.remarks;
|
||||||
if (Utils.IsNullOrEmpty(remarks))
|
if (string.IsNullOrEmpty(remarks))
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.PleaseFillRemarks);
|
_noticeHandler?.Enqueue(ResUI.PleaseFillRemarks);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(CoreType))
|
if (string.IsNullOrEmpty(CoreType))
|
||||||
{
|
{
|
||||||
SelectedSource.coreType = null;
|
SelectedSource.coreType = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SelectedSource.coreType = (ECoreType)Enum.Parse(typeof(ECoreType), CoreType);
|
SelectedSource.coreType = (CoreKind)Enum.Parse(typeof(CoreKind), CoreType);
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = _config.GetProfileItem(SelectedSource.indexId);
|
var item = _config.GetProfileItem(SelectedSource.indexId);
|
||||||
@@ -98,7 +98,7 @@ namespace ClashN.ViewModels
|
|||||||
item.enableConvert = SelectedSource.enableConvert;
|
item.enableConvert = SelectedSource.enableConvert;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConfigHandler.EditProfile(ref _config, item) == 0)
|
if (ConfigProc.EditProfile(ref _config, item) == 0)
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<ProfilesViewModel>()?.RefreshProfiles();
|
Locator.Current.GetService<ProfilesViewModel>()?.RefreshProfiles();
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
@@ -128,7 +128,7 @@ namespace ClashN.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
string fileName = fileDialog.FileName;
|
string fileName = fileDialog.FileName;
|
||||||
if (Utils.IsNullOrEmpty(fileName))
|
if (string.IsNullOrEmpty(fileName))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
item = SelectedSource;
|
item = SelectedSource;
|
||||||
}
|
}
|
||||||
if (ConfigHandler.AddProfileViaPath(ref _config, item, fileName) == 0)
|
if (ConfigProc.AddProfileViaPath(ref _config, item, fileName) == 0)
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.SuccessfullyImportedCustomProfile);
|
_noticeHandler?.Enqueue(ResUI.SuccessfullyImportedCustomProfile);
|
||||||
Locator.Current.GetService<ProfilesViewModel>()?.RefreshProfiles();
|
Locator.Current.GetService<ProfilesViewModel>()?.RefreshProfiles();
|
||||||
@@ -152,7 +152,7 @@ namespace ClashN.ViewModels
|
|||||||
private void EditProfile()
|
private void EditProfile()
|
||||||
{
|
{
|
||||||
var address = SelectedSource.address;
|
var address = SelectedSource.address;
|
||||||
if (Utils.IsNullOrEmpty(address))
|
if (string.IsNullOrEmpty(address))
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.FillProfileAddressCustom);
|
_noticeHandler?.Enqueue(ResUI.FillProfileAddressCustom);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace ClashN.ViewModels
|
|||||||
public ProfilesViewModel()
|
public ProfilesViewModel()
|
||||||
{
|
{
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.Config;
|
||||||
|
|
||||||
SelectedSource = new();
|
SelectedSource = new();
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
ClearStatisticCmd = ReactiveCommand.Create(() =>
|
ClearStatisticCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
ConfigHandler.ClearAllServerStatistics(ref _config);
|
ConfigProc.ClearAllServerStatistics(ref _config);
|
||||||
RefreshProfiles();
|
RefreshProfiles();
|
||||||
});
|
});
|
||||||
ProfileReloadCmd = ReactiveCommand.Create(() =>
|
ProfileReloadCmd = ReactiveCommand.Create(() =>
|
||||||
@@ -144,7 +144,7 @@ namespace ClashN.ViewModels
|
|||||||
private void EditLocalFile()
|
private void EditLocalFile()
|
||||||
{
|
{
|
||||||
var address = SelectedSource.address;
|
var address = SelectedSource.address;
|
||||||
if (Utils.IsNullOrEmpty(address))
|
if (string.IsNullOrEmpty(address))
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.FillProfileAddressCustom);
|
_noticeHandler?.Enqueue(ResUI.FillProfileAddressCustom);
|
||||||
return;
|
return;
|
||||||
@@ -168,7 +168,7 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
item = new()
|
item = new()
|
||||||
{
|
{
|
||||||
coreType = ECoreType.clash_meta
|
coreType = CoreKind.ClashMeta
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -202,13 +202,13 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(true);
|
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(true);
|
||||||
|
|
||||||
if (Utils.IsNullOrEmpty(result))
|
if (string.IsNullOrEmpty(result))
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.NoValidQRcodeFound);
|
_noticeHandler?.Enqueue(ResUI.NoValidQRcodeFound);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int ret = ConfigHandler.AddBatchProfiles(ref _config, result, "", "");
|
int ret = ConfigProc.AddBatchProfiles(ref _config, result, "", "");
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
RefreshProfiles();
|
RefreshProfiles();
|
||||||
@@ -218,12 +218,12 @@ namespace ClashN.ViewModels
|
|||||||
}
|
}
|
||||||
public void AddProfilesViaClipboard(bool bClear)
|
public void AddProfilesViaClipboard(bool bClear)
|
||||||
{
|
{
|
||||||
string clipboardData = Utils.GetClipboardData();
|
string? clipboardData = Utils.GetClipboardData();
|
||||||
if (Utils.IsNullOrEmpty(clipboardData))
|
if (string.IsNullOrEmpty(clipboardData))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int ret = ConfigHandler.AddBatchProfiles(ref _config, clipboardData, "", "");
|
int ret = ConfigProc.AddBatchProfiles(ref _config, clipboardData, "", "");
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
if (bClear)
|
if (bClear)
|
||||||
@@ -242,8 +242,8 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var content = ConfigHandler.GetProfileContent(item);
|
var content = ConfigProc.GetProfileContent(item);
|
||||||
if (Utils.IsNullOrEmpty(content))
|
if (string.IsNullOrEmpty(content))
|
||||||
{
|
{
|
||||||
content = item.url;
|
content = item.url;
|
||||||
}
|
}
|
||||||
@@ -286,7 +286,7 @@ namespace ClashN.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigHandler.RemoveProfile(_config, new List<ProfileItem>() { item });
|
ConfigProc.RemoveProfile(_config, new List<ProfileItem>() { item });
|
||||||
|
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
|
|
||||||
@@ -301,7 +301,7 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ConfigHandler.CopyProfile(ref _config, new List<ProfileItem>() { item }) == 0)
|
if (ConfigProc.CopyProfile(ref _config, new List<ProfileItem>() { item }) == 0)
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
RefreshProfiles();
|
RefreshProfiles();
|
||||||
@@ -309,7 +309,7 @@ namespace ClashN.ViewModels
|
|||||||
}
|
}
|
||||||
public void SetDefaultProfile()
|
public void SetDefaultProfile()
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(SelectedSource?.indexId))
|
if (string.IsNullOrEmpty(SelectedSource?.indexId))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -320,7 +320,7 @@ namespace ClashN.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConfigHandler.SetDefaultProfile(ref _config, item) == 0)
|
if (ConfigProc.SetDefaultProfile(ref _config, item) == 0)
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
RefreshProfiles();
|
RefreshProfiles();
|
||||||
@@ -331,13 +331,13 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
public void RefreshProfiles()
|
public void RefreshProfiles()
|
||||||
{
|
{
|
||||||
ConfigHandler.SetDefaultProfile(_config, _config.profileItems);
|
ConfigProc.SetDefaultProfile(_config, _config.ProfileItems);
|
||||||
|
|
||||||
var lstModel = new List<ProfileItemModel>();
|
var lstModel = new List<ProfileItemModel>();
|
||||||
foreach (var item in _config.profileItems.OrderBy(it => it.sort))
|
foreach (var item in _config.ProfileItems.OrderBy(it => it.sort))
|
||||||
{
|
{
|
||||||
var model = Utils.FromJson<ProfileItemModel>(Utils.ToJson(item));
|
var model = Utils.FromJson<ProfileItemModel>(Utils.ToJson(item));
|
||||||
model.isActive = _config.IsActiveNode(item);
|
model.IsActive = _config.IsActiveNode(item);
|
||||||
lstModel.Add(model);
|
lstModel.Add(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +354,7 @@ namespace ClashN.ViewModels
|
|||||||
var targetIndex = _profileItems.IndexOf(targetItem);
|
var targetIndex = _profileItems.IndexOf(targetItem);
|
||||||
if (startIndex >= 0 && targetIndex >= 0 && startIndex != targetIndex)
|
if (startIndex >= 0 && targetIndex >= 0 && startIndex != targetIndex)
|
||||||
{
|
{
|
||||||
if (ConfigHandler.MoveProfile(ref _config, startIndex, EMove.Position, targetIndex) == 0)
|
if (ConfigProc.MoveProfile(ref _config, startIndex, MovementTarget.Position, targetIndex) == 0)
|
||||||
{
|
{
|
||||||
RefreshProfiles();
|
RefreshProfiles();
|
||||||
}
|
}
|
||||||
@@ -368,7 +368,7 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Utils.IsNullOrEmpty(item.url))
|
if (string.IsNullOrEmpty(item.url))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,13 +54,13 @@ namespace ClashN.ViewModels
|
|||||||
public ProxiesViewModel()
|
public ProxiesViewModel()
|
||||||
{
|
{
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.Config;
|
||||||
|
|
||||||
SelectedGroup = new();
|
SelectedGroup = new();
|
||||||
SelectedDetail = new();
|
SelectedDetail = new();
|
||||||
AutoRefresh = _config.uiItem.proxiesAutoRefresh;
|
AutoRefresh = _config.UiItem.proxiesAutoRefresh;
|
||||||
EnableTun = _config.enableTun;
|
EnableTun = _config.EnableTun;
|
||||||
SortingSelected = _config.uiItem.proxiesSorting;
|
SortingSelected = _config.UiItem.proxiesSorting;
|
||||||
|
|
||||||
//GetClashProxies(true);
|
//GetClashProxies(true);
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
@@ -70,17 +70,17 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.SystemProxySelected,
|
x => x.SystemProxySelected,
|
||||||
y => y != null && y >= 0)
|
y => y >= 0)
|
||||||
.Subscribe(c => DoSystemProxySelected(c));
|
.Subscribe(c => DoSystemProxySelected(c));
|
||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.RuleModeSelected,
|
x => x.RuleModeSelected,
|
||||||
y => y != null && y >= 0)
|
y => y >= 0)
|
||||||
.Subscribe(c => DoRulemodeSelected(c));
|
.Subscribe(c => DoRulemodeSelected(c));
|
||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.SortingSelected,
|
x => x.SortingSelected,
|
||||||
y => y != null && y >= 0)
|
y => y >= 0)
|
||||||
.Subscribe(c => DoSortingSelected(c));
|
.Subscribe(c => DoSortingSelected(c));
|
||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
@@ -91,7 +91,7 @@ namespace ClashN.ViewModels
|
|||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.AutoRefresh,
|
x => x.AutoRefresh,
|
||||||
y => y == true)
|
y => y == true)
|
||||||
.Subscribe(c => { _config.uiItem.proxiesAutoRefresh = AutoRefresh; });
|
.Subscribe(c => { _config.UiItem.proxiesAutoRefresh = AutoRefresh; });
|
||||||
|
|
||||||
ProxiesReloadCmd = ReactiveCommand.Create(() =>
|
ProxiesReloadCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
@@ -123,11 +123,11 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_config.sysProxyType == (ESysProxyType)SystemProxySelected)
|
if (_config.SysProxyType == (SysProxyType)SystemProxySelected)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.SetListenerType((ESysProxyType)SystemProxySelected);
|
Locator.Current.GetService<MainWindowViewModel>()?.SetListenerType((SysProxyType)SystemProxySelected);
|
||||||
}
|
}
|
||||||
void DoRulemodeSelected(bool c)
|
void DoRulemodeSelected(bool c)
|
||||||
{
|
{
|
||||||
@@ -148,9 +148,9 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (SortingSelected != _config.uiItem.proxiesSorting)
|
if (SortingSelected != _config.UiItem.proxiesSorting)
|
||||||
{
|
{
|
||||||
_config.uiItem.proxiesSorting = SortingSelected;
|
_config.UiItem.proxiesSorting = SortingSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefreshProxyDetails(c);
|
RefreshProxyDetails(c);
|
||||||
@@ -186,7 +186,7 @@ namespace ClashN.ViewModels
|
|||||||
}
|
}
|
||||||
public void ReloadSystemProxySelected()
|
public void ReloadSystemProxySelected()
|
||||||
{
|
{
|
||||||
SystemProxySelected = (int)_config.sysProxyType;
|
SystemProxySelected = (int)_config.SysProxyType;
|
||||||
}
|
}
|
||||||
public void ReloadRulemodeSelected()
|
public void ReloadRulemodeSelected()
|
||||||
{
|
{
|
||||||
@@ -195,9 +195,9 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
void DoEnableTun(bool c)
|
void DoEnableTun(bool c)
|
||||||
{
|
{
|
||||||
if (_config.enableTun != EnableTun)
|
if (_config.EnableTun != EnableTun)
|
||||||
{
|
{
|
||||||
_config.enableTun = EnableTun;
|
_config.EnableTun = EnableTun;
|
||||||
TunModeSwitch();
|
TunModeSwitch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,7 +242,7 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
foreach (var it in proxyGroups)
|
foreach (var it in proxyGroups)
|
||||||
{
|
{
|
||||||
if (Utils.IsNullOrEmpty(it.name) || !proxies.ContainsKey(it.name))
|
if (string.IsNullOrEmpty(it.name) || !proxies.ContainsKey(it.name))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -298,7 +298,7 @@ namespace ClashN.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var name = SelectedGroup?.name;
|
var name = SelectedGroup?.name;
|
||||||
if (Utils.IsNullOrEmpty(name))
|
if (string.IsNullOrEmpty(name))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -388,12 +388,12 @@ namespace ClashN.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var name = SelectedGroup.name;
|
var name = SelectedGroup.name;
|
||||||
if (Utils.IsNullOrEmpty(name))
|
if (string.IsNullOrEmpty(name))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var nameNode = SelectedDetail.name;
|
var nameNode = SelectedDetail.name;
|
||||||
if (Utils.IsNullOrEmpty(nameNode))
|
if (string.IsNullOrEmpty(nameNode))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -437,7 +437,7 @@ namespace ClashN.ViewModels
|
|||||||
GetClashProxies(true);
|
GetClashProxies(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Utils.IsNullOrEmpty(result))
|
if (string.IsNullOrEmpty(result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -485,9 +485,9 @@ namespace ClashN.ViewModels
|
|||||||
}
|
}
|
||||||
var dtNow = DateTime.Now;
|
var dtNow = DateTime.Now;
|
||||||
|
|
||||||
if (_config.autoDelayTestInterval > 0)
|
if (_config.AutoDelayTestInterval > 0)
|
||||||
{
|
{
|
||||||
if ((dtNow - autoDelayTestTime).Minutes % _config.autoDelayTestInterval == 0)
|
if ((dtNow - autoDelayTestTime).Minutes % _config.AutoDelayTestInterval == 0)
|
||||||
{
|
{
|
||||||
ProxiesDelayTest();
|
ProxiesDelayTest();
|
||||||
autoDelayTestTime = dtNow;
|
autoDelayTestTime = dtNow;
|
||||||
|
|||||||
@@ -93,31 +93,31 @@ namespace ClashN.ViewModels
|
|||||||
|
|
||||||
public SettingsViewModel()
|
public SettingsViewModel()
|
||||||
{
|
{
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.Config;
|
||||||
|
|
||||||
//Core
|
//Core
|
||||||
MixedPort = _config.mixedPort;
|
MixedPort = _config.MixedPort;
|
||||||
SocksPort = _config.socksPort;
|
SocksPort = _config.SocksPort;
|
||||||
HttpPort = _config.httpPort;
|
HttpPort = _config.HttpPort;
|
||||||
APIPort = _config.APIPort;
|
APIPort = _config.ApiPort;
|
||||||
AllowLANConn = _config.allowLANConn;
|
AllowLANConn = _config.AllowLANConn;
|
||||||
EnableIpv6 = _config.enableIpv6;
|
EnableIpv6 = _config.EnableIpv6;
|
||||||
LogLevel = _config.logLevel;
|
LogLevel = _config.LogLevel;
|
||||||
EnableMixinContent = _config.enableMixinContent;
|
EnableMixinContent = _config.EnableMixinContent;
|
||||||
EditMixinContentCmd = ReactiveCommand.Create(() =>
|
EditMixinContentCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
EditMixinContent();
|
EditMixinContent();
|
||||||
}, this.IsValid());
|
}, this.IsValid());
|
||||||
|
|
||||||
//clashN
|
//clashN
|
||||||
AutoRun = _config.autoRun;
|
AutoRun = _config.AutoRun;
|
||||||
EnableStatistics = _config.enableStatistics;
|
EnableStatistics = _config.EnableStatistics;
|
||||||
EnableSecurityProtocolTls13 = _config.enableSecurityProtocolTls13;
|
EnableSecurityProtocolTls13 = _config.EnableSecurityProtocolTls13;
|
||||||
autoUpdateSubInterval = _config.autoUpdateSubInterval;
|
autoUpdateSubInterval = _config.AutoUpdateSubInterval;
|
||||||
autoDelayTestInterval = _config.autoDelayTestInterval;
|
autoDelayTestInterval = _config.AutoDelayTestInterval;
|
||||||
SubConvertUrl = _config.constItem.subConvertUrl;
|
SubConvertUrl = _config.ConstItem.subConvertUrl;
|
||||||
currentFontFamily = _config.uiItem.currentFontFamily;
|
currentFontFamily = _config.UiItem.currentFontFamily;
|
||||||
AutoHideStartup = _config.autoHideStartup;
|
AutoHideStartup = _config.AutoHideStartup;
|
||||||
|
|
||||||
SetLoopbackCmd = ReactiveCommand.Create(() =>
|
SetLoopbackCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
@@ -134,30 +134,30 @@ namespace ClashN.ViewModels
|
|||||||
}, this.IsValid());
|
}, this.IsValid());
|
||||||
|
|
||||||
//System proxy
|
//System proxy
|
||||||
systemProxyExceptions = _config.systemProxyExceptions;
|
systemProxyExceptions = _config.SystemProxyExceptions;
|
||||||
systemProxyAdvancedProtocol = _config.systemProxyAdvancedProtocol;
|
systemProxyAdvancedProtocol = _config.SystemProxyAdvancedProtocol;
|
||||||
PacPort = _config.PacPort;
|
PacPort = _config.PacPort;
|
||||||
|
|
||||||
//UI
|
//UI
|
||||||
ColorModeDark = _config.uiItem.colorModeDark;
|
ColorModeDark = _config.UiItem.colorModeDark;
|
||||||
_swatches.AddRange(new SwatchesProvider().Swatches);
|
_swatches.AddRange(new SwatchesProvider().Swatches);
|
||||||
if (!_config.uiItem.colorPrimaryName.IsNullOrEmpty())
|
if (!_config.UiItem.colorPrimaryName.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
SelectedSwatch = _swatches.FirstOrDefault(t => t.Name == _config.uiItem.colorPrimaryName);
|
SelectedSwatch = _swatches.FirstOrDefault(t => t.Name == _config.UiItem.colorPrimaryName);
|
||||||
}
|
}
|
||||||
CurrentLanguage = Utils.RegReadValue(Global.MyRegPath, Global.MyRegKeyLanguage, Global.Languages[0]);
|
CurrentLanguage = Utils.RegReadValue(Global.MyRegPath, Global.MyRegKeyLanguage, Global.Languages[0]);
|
||||||
CurrentFontSize = _config.uiItem.currentFontSize;
|
CurrentFontSize = _config.UiItem.currentFontSize;
|
||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.ColorModeDark,
|
x => x.ColorModeDark,
|
||||||
y => y == true)
|
y => y == true)
|
||||||
.Subscribe(c =>
|
.Subscribe(c =>
|
||||||
{
|
{
|
||||||
if (_config.uiItem.colorModeDark != ColorModeDark)
|
if (_config.UiItem.colorModeDark != ColorModeDark)
|
||||||
{
|
{
|
||||||
_config.uiItem.colorModeDark = ColorModeDark;
|
_config.UiItem.colorModeDark = ColorModeDark;
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.ModifyTheme(ColorModeDark);
|
Locator.Current.GetService<MainWindowViewModel>()?.ModifyTheme(ColorModeDark);
|
||||||
ConfigHandler.SaveConfig(ref _config);
|
ConfigProc.SaveConfig(_config);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -173,11 +173,11 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_config.uiItem.colorPrimaryName != SelectedSwatch?.Name)
|
if (_config.UiItem.colorPrimaryName != SelectedSwatch?.Name)
|
||||||
{
|
{
|
||||||
_config.uiItem.colorPrimaryName = SelectedSwatch?.Name;
|
_config.UiItem.colorPrimaryName = SelectedSwatch?.Name;
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.ChangePrimaryColor(SelectedSwatch.ExemplarHue.Color);
|
Locator.Current.GetService<MainWindowViewModel>()?.ChangePrimaryColor(SelectedSwatch.ExemplarHue.Color);
|
||||||
ConfigHandler.SaveConfig(ref _config);
|
ConfigProc.SaveConfig(_config);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ namespace ClashN.ViewModels
|
|||||||
y => y != null && !y.IsNullOrEmpty())
|
y => y != null && !y.IsNullOrEmpty())
|
||||||
.Subscribe(c =>
|
.Subscribe(c =>
|
||||||
{
|
{
|
||||||
if (!Utils.IsNullOrEmpty(CurrentLanguage))
|
if (!string.IsNullOrEmpty(CurrentLanguage))
|
||||||
{
|
{
|
||||||
Utils.RegWriteValue(Global.MyRegPath, Global.MyRegKeyLanguage, CurrentLanguage);
|
Utils.RegWriteValue(Global.MyRegPath, Global.MyRegKeyLanguage, CurrentLanguage);
|
||||||
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(CurrentLanguage);
|
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(CurrentLanguage);
|
||||||
@@ -198,11 +198,11 @@ namespace ClashN.ViewModels
|
|||||||
y => y > 0)
|
y => y > 0)
|
||||||
.Subscribe(c =>
|
.Subscribe(c =>
|
||||||
{
|
{
|
||||||
if (_config.uiItem.colorModeDark != ColorModeDark)
|
if (_config.UiItem.colorModeDark != ColorModeDark)
|
||||||
{
|
{
|
||||||
_config.uiItem.colorModeDark = ColorModeDark;
|
_config.UiItem.colorModeDark = ColorModeDark;
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.ModifyTheme(ColorModeDark);
|
Locator.Current.GetService<MainWindowViewModel>()?.ModifyTheme(ColorModeDark);
|
||||||
ConfigHandler.SaveConfig(ref _config);
|
ConfigProc.SaveConfig(_config);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -213,14 +213,14 @@ namespace ClashN.ViewModels
|
|||||||
{
|
{
|
||||||
if (CurrentFontSize >= Global.MinFontSize)
|
if (CurrentFontSize >= Global.MinFontSize)
|
||||||
{
|
{
|
||||||
_config.uiItem.currentFontSize = CurrentFontSize;
|
_config.UiItem.currentFontSize = CurrentFontSize;
|
||||||
double size = (long)CurrentFontSize;
|
double size = (long)CurrentFontSize;
|
||||||
Application.Current.Resources["StdFontSize1"] = size;
|
Application.Current.Resources["StdFontSize1"] = size;
|
||||||
Application.Current.Resources["StdFontSize2"] = size + 1;
|
Application.Current.Resources["StdFontSize2"] = size + 1;
|
||||||
Application.Current.Resources["StdFontSize3"] = size + 2;
|
Application.Current.Resources["StdFontSize3"] = size + 2;
|
||||||
Application.Current.Resources["StdFontSize4"] = size + 3;
|
Application.Current.Resources["StdFontSize4"] = size + 3;
|
||||||
|
|
||||||
ConfigHandler.SaveConfig(ref _config);
|
ConfigProc.SaveConfig(_config);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -235,32 +235,32 @@ namespace ClashN.ViewModels
|
|||||||
void SaveConfig()
|
void SaveConfig()
|
||||||
{
|
{
|
||||||
//Core
|
//Core
|
||||||
_config.mixedPort = MixedPort;
|
_config.MixedPort = MixedPort;
|
||||||
_config.socksPort = SocksPort;
|
_config.SocksPort = SocksPort;
|
||||||
_config.httpPort = HttpPort;
|
_config.HttpPort = HttpPort;
|
||||||
_config.APIPort = APIPort;
|
_config.ApiPort = APIPort;
|
||||||
_config.allowLANConn = AllowLANConn;
|
_config.AllowLANConn = AllowLANConn;
|
||||||
_config.enableIpv6 = EnableIpv6;
|
_config.EnableIpv6 = EnableIpv6;
|
||||||
_config.logLevel = LogLevel;
|
_config.LogLevel = LogLevel;
|
||||||
_config.enableMixinContent = EnableMixinContent;
|
_config.EnableMixinContent = EnableMixinContent;
|
||||||
|
|
||||||
//clashN
|
//clashN
|
||||||
Utils.SetAutoRun(AutoRun);
|
Utils.SetAutoRun(AutoRun);
|
||||||
_config.autoRun = AutoRun;
|
_config.AutoRun = AutoRun;
|
||||||
_config.enableStatistics = EnableStatistics;
|
_config.EnableStatistics = EnableStatistics;
|
||||||
_config.enableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
|
_config.EnableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
|
||||||
_config.autoUpdateSubInterval = autoUpdateSubInterval;
|
_config.AutoUpdateSubInterval = autoUpdateSubInterval;
|
||||||
_config.autoDelayTestInterval = autoDelayTestInterval;
|
_config.AutoDelayTestInterval = autoDelayTestInterval;
|
||||||
_config.constItem.subConvertUrl = SubConvertUrl;
|
_config.ConstItem.subConvertUrl = SubConvertUrl;
|
||||||
_config.uiItem.currentFontFamily = currentFontFamily;
|
_config.UiItem.currentFontFamily = currentFontFamily;
|
||||||
_config.autoHideStartup = AutoHideStartup;
|
_config.AutoHideStartup = AutoHideStartup;
|
||||||
|
|
||||||
//System proxy
|
//System proxy
|
||||||
_config.systemProxyExceptions = systemProxyExceptions;
|
_config.SystemProxyExceptions = systemProxyExceptions;
|
||||||
_config.systemProxyAdvancedProtocol = systemProxyAdvancedProtocol;
|
_config.SystemProxyAdvancedProtocol = systemProxyAdvancedProtocol;
|
||||||
_config.PacPort = PacPort;
|
_config.PacPort = PacPort;
|
||||||
|
|
||||||
if (ConfigHandler.SaveConfig(ref _config) == 0)
|
if (ConfigProc.SaveConfig(_config) == 0)
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<NoticeHandler>()?.Enqueue(ResUI.OperationSuccess);
|
Locator.Current.GetService<NoticeHandler>()?.Enqueue(ResUI.OperationSuccess);
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.LoadCore();
|
Locator.Current.GetService<MainWindowViewModel>()?.LoadCore();
|
||||||
@@ -278,7 +278,7 @@ namespace ClashN.ViewModels
|
|||||||
if (!File.Exists(address))
|
if (!File.Exists(address))
|
||||||
{
|
{
|
||||||
string contents = Utils.GetEmbedText(Global.SampleMixin);
|
string contents = Utils.GetEmbedText(Global.SampleMixin);
|
||||||
if (!Utils.IsNullOrEmpty(contents))
|
if (!string.IsNullOrEmpty(contents))
|
||||||
{
|
{
|
||||||
File.WriteAllText(address, contents);
|
File.WriteAllText(address, contents);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,28 +14,23 @@ namespace ClashN.Views
|
|||||||
public partial class GlobalHotkeySettingWindow
|
public partial class GlobalHotkeySettingWindow
|
||||||
{
|
{
|
||||||
private static Config _config;
|
private static Config _config;
|
||||||
List<KeyEventItem> lstKey;
|
List<KeyShortcut> lstKey;
|
||||||
|
|
||||||
public GlobalHotkeySettingWindow()
|
public GlobalHotkeySettingWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.Config;
|
||||||
|
|
||||||
if (_config.globalHotkeys == null)
|
foreach (GlobalHotkeyAction it in Enum.GetValues(typeof(GlobalHotkeyAction)))
|
||||||
{
|
{
|
||||||
_config.globalHotkeys = new List<KeyEventItem>();
|
if (_config.globalHotkeys.FindIndex(t => t.GlobalHotkey == it) >= 0)
|
||||||
}
|
|
||||||
|
|
||||||
foreach (EGlobalHotkey it in Enum.GetValues(typeof(EGlobalHotkey)))
|
|
||||||
{
|
|
||||||
if (_config.globalHotkeys.FindIndex(t => t.eGlobalHotkey == it) >= 0)
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_config.globalHotkeys.Add(new KeyEventItem()
|
_config.globalHotkeys.Add(new KeyShortcut()
|
||||||
{
|
{
|
||||||
eGlobalHotkey = it,
|
GlobalHotkey = it,
|
||||||
Alt = false,
|
Alt = false,
|
||||||
Control = false,
|
Control = false,
|
||||||
Shift = false,
|
Shift = false,
|
||||||
@@ -53,7 +48,7 @@ namespace ClashN.Views
|
|||||||
|
|
||||||
BindingData(-1);
|
BindingData(-1);
|
||||||
|
|
||||||
Utils.SetDarkBorder(this, _config.uiItem.colorModeDark);
|
Utils.SetDarkBorder(this, _config.UiItem.colorModeDark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -66,10 +61,13 @@ namespace ClashN.Views
|
|||||||
return;
|
return;
|
||||||
var formsKey = (Forms.Keys)KeyInterop.VirtualKeyFromKey(e.Key);
|
var formsKey = (Forms.Keys)KeyInterop.VirtualKeyFromKey(e.Key);
|
||||||
|
|
||||||
lstKey[index].KeyCode = formsKey;
|
lstKey[index] = new KeyShortcut()
|
||||||
lstKey[index].Alt = Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt);
|
{
|
||||||
lstKey[index].Control = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);
|
KeyCode = formsKey,
|
||||||
lstKey[index].Shift = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
|
Alt = Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt),
|
||||||
|
Control = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl),
|
||||||
|
Shift = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift),
|
||||||
|
};
|
||||||
|
|
||||||
BindingData(index);
|
BindingData(index);
|
||||||
}
|
}
|
||||||
@@ -108,9 +106,10 @@ namespace ClashN.Views
|
|||||||
|
|
||||||
private void btnSave_Click(object sender, RoutedEventArgs e)
|
private void btnSave_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_config.globalHotkeys = lstKey;
|
_config.globalHotkeys.Clear();
|
||||||
|
_config.globalHotkeys.AddRange(lstKey);
|
||||||
|
|
||||||
if (ConfigHandler.SaveConfig(ref _config, false) == 0)
|
if (ConfigProc.SaveConfig(_config, false) == 0)
|
||||||
{
|
{
|
||||||
this.Close();
|
this.Close();
|
||||||
}
|
}
|
||||||
@@ -128,16 +127,16 @@ namespace ClashN.Views
|
|||||||
private void btnReset_Click(object sender, RoutedEventArgs e)
|
private void btnReset_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
lstKey.Clear();
|
lstKey.Clear();
|
||||||
foreach (EGlobalHotkey it in Enum.GetValues(typeof(EGlobalHotkey)))
|
foreach (GlobalHotkeyAction it in Enum.GetValues(typeof(GlobalHotkeyAction)))
|
||||||
{
|
{
|
||||||
if (lstKey.FindIndex(t => t.eGlobalHotkey == it) >= 0)
|
if (lstKey.FindIndex(t => t.GlobalHotkey == it) >= 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
lstKey.Add(new KeyEventItem()
|
lstKey.Add(new KeyShortcut()
|
||||||
{
|
{
|
||||||
eGlobalHotkey = it,
|
GlobalHotkey = it,
|
||||||
Alt = false,
|
Alt = false,
|
||||||
Control = false,
|
Control = false,
|
||||||
Shift = false,
|
Shift = false,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace ClashN.Views
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
string? msgFilter = ViewModel?.MsgFilter;
|
string? msgFilter = ViewModel?.MsgFilter;
|
||||||
if (!Utils.IsNullOrEmpty(msgFilter))
|
if (!string.IsNullOrEmpty(msgFilter))
|
||||||
{
|
{
|
||||||
if (!Regex.IsMatch(msg, msgFilter))
|
if (!Regex.IsMatch(msg, msgFilter))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace ClashN.Views
|
|||||||
|
|
||||||
public void AppendText(string msg)
|
public void AppendText(string msg)
|
||||||
{
|
{
|
||||||
//if (!Utils.IsNullOrEmpty(MsgFilter))
|
//if (!string.IsNullOrEmpty(MsgFilter))
|
||||||
//{
|
//{
|
||||||
// if (!Regex.IsMatch(text, MsgFilter))
|
// if (!Regex.IsMatch(text, MsgFilter))
|
||||||
// {
|
// {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace ClashN.Views
|
|||||||
public SettingsView()
|
public SettingsView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.Config;
|
||||||
ViewModel = new SettingsViewModel();
|
ViewModel = new SettingsViewModel();
|
||||||
|
|
||||||
Global.SubConvertUrls.ForEach(it =>
|
Global.SubConvertUrls.ForEach(it =>
|
||||||
@@ -66,10 +66,10 @@ namespace ClashN.Views
|
|||||||
// continue;
|
// continue;
|
||||||
//}
|
//}
|
||||||
var fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture)];
|
var fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture)];
|
||||||
if (Utils.IsNullOrEmpty(fontFamily))
|
if (string.IsNullOrEmpty(fontFamily))
|
||||||
{
|
{
|
||||||
fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture2)];
|
fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture2)];
|
||||||
if (Utils.IsNullOrEmpty(fontFamily))
|
if (string.IsNullOrEmpty(fontFamily))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user