改了一堆屎山代码

This commit is contained in:
SlimeNull
2023-02-17 20:21:29 +08:00
parent 4409a891df
commit 95d90d6fd4
41 changed files with 648 additions and 710 deletions

View File

@@ -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)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/2dust/clashn)](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
- Please download clashN.zip from [releases](https://github.com/2dust/clashN/releases)
- Unzip to folder
- Run clashN.exe
1. Download `clashN.zip` from [releases](https://github.com/2dust/clashN/releases)
2. Unzip to any folder you want
3. Run ClashN.exe
### Tips
- You can also add `v2ray` subscription to `ClashN`, just enable `Subcription conversion` when you add a profile.
### 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))
- 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)
### Telegram Channel
[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

View File

@@ -11,8 +11,21 @@ namespace ClashN
/// </summary>
public partial class App : Application
{
public static EventWaitHandle ProgramStarted;
private static Config _config;
public static EventWaitHandle? ProgramStarted;
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()
{
// Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetCallingAssembly());
@@ -34,14 +47,6 @@ namespace ClashN
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();
Logging.Setup();
@@ -58,7 +63,7 @@ namespace ClashN
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配置文件异常,请重启应用");
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);
}

View File

@@ -14,7 +14,13 @@ namespace ClashN.Base
/// <summary>
/// </summary>
private HttpClientHelper() { }
private HttpClientHelper()
{
httpClient = new HttpClient(new HttpClientHandler()
{
UseCookies = false
});
}
/// <summary>
/// </summary>
@@ -34,26 +40,26 @@ namespace ClashN.Base
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;
}
try
{
HttpResponseMessage response = await httpClient.GetAsync(url);
return await response.Content.ReadAsStringAsync();
}
catch
{
return null;
}
return null;
}
public async Task<(string, HttpResponseHeaders)> GetAsync(HttpClient client, string url, CancellationToken token)
{
if (Utils.IsNullOrEmpty(url))
if (string.IsNullOrEmpty(url))
{
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)
{
if (Utils.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (Utils.IsNullOrEmpty(fileName))
{
throw new ArgumentNullException("fileName");
}
if (File.Exists(fileName))
{
File.Delete(fileName);
}
if (string.IsNullOrEmpty(url))
throw new ArgumentNullException(nameof(url));
if (string.IsNullOrEmpty(fileName))
throw new ArgumentNullException(nameof(fileName));
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
HttpResponseMessage response =
await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
if (!response.IsSuccessStatusCode)
{
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 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;
var buffer = new byte[1024 * 1024];
var isMoreToRead = true;
progressPercentage = -1;
isMoreToRead = false;
}
else
{
var data = new byte[read];
buffer.ToList().CopyTo(0, data, 0, read);
do
{
token.ThrowIfCancellationRequested();
// TODO: put here the code to write the file to disk
file.Write(data, 0, read);
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)
{
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);
}
}
}

View File

@@ -11,7 +11,7 @@ namespace ClashN.Converters
{
try
{
var fontFamily = LazyConfig.Instance.GetConfig().uiItem.currentFontFamily;
var fontFamily = LazyConfig.Instance.Config.UiItem.currentFontFamily;
if (!string.IsNullOrEmpty(fontFamily))
{
var fontPath = Utils.GetFontsPath();

View File

@@ -8,7 +8,7 @@ namespace ClashN.Handler
/// <summary>
/// 本软件配置文件处理类
/// </summary>
class ConfigHandler
class ConfigProc
{
private static string configRes = Global.ConfigFileName;
private static readonly object objLock = new object();
@@ -20,11 +20,11 @@ namespace ClashN.Handler
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static int LoadConfig(ref Config config)
public static int LoadConfig(ref Config? config)
{
//载入配置文件
string result = Utils.LoadResource(Utils.GetConfigPath(configRes));
if (!Utils.IsNullOrEmpty(result))
if (!string.IsNullOrEmpty(result))
{
//转成Json
config = Utils.FromJson<Config>(result);
@@ -42,71 +42,59 @@ namespace ClashN.Handler
{
config = new Config
{
logLevel = "warning",
profileItems = new List<ProfileItem>(),
enableStatistics = true,
LogLevel = "warning",
EnableStatistics = true,
};
}
//本地监听
if (config.mixedPort == 0)
{
config.mixedPort = 7888;
}
if (config.httpPort == 0)
{
config.httpPort = 7890;
}
if (config.socksPort == 0)
{
config.socksPort = 7891;
}
if (config.APIPort == 0)
{
config.APIPort = 9090;
}
if (config.MixedPort == 0)
config.MixedPort = 7888;
if (config.HttpPort == 0)
config.HttpPort = 7890;
if (config.SocksPort == 0)
config.SocksPort = 7891;
if (config.ApiPort == 0)
config.ApiPort = 9090;
if (config.PacPort == 0)
{
config.PacPort = 7990;
}
if (config.profileItems == null)
if (config.UiItem == null)
{
config.profileItems = new List<ProfileItem>();
}
if (config.uiItem == null)
{
config.uiItem = new UIItem()
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;
//}
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
|| config.profileItems.Count <= 0
|| config.ProfileItems.Count <= 0
)
{
Global.reloadCore = false;
@@ -115,11 +103,11 @@ namespace ClashN.Handler
{
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);
}
@@ -134,7 +122,7 @@ namespace ClashN.Handler
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static int SaveConfig(ref Config config, bool reload = true)
public static int SaveConfig(Config config, bool reload = true)
{
Global.reloadCore = reload;
@@ -215,7 +203,7 @@ namespace ClashN.Handler
profileItem.indexId = string.Empty;
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;
AddProfileCommon(ref config, profileItem);
@@ -246,7 +234,7 @@ namespace ClashN.Handler
return -1;
}
config.indexId = item.indexId;
config.IndexId = item.indexId;
Global.reloadCore = true;
ToJsonFile(config);
@@ -256,11 +244,11 @@ namespace ClashN.Handler
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;
}
if (config.profileItems.Exists(t => t.indexId == config.indexId))
if (config.ProfileItems.Exists(t => t.indexId == config.IndexId))
{
return 0;
}
@@ -268,26 +256,26 @@ namespace ClashN.Handler
{
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;
}
public static ProfileItem GetDefaultProfile(ref Config config)
{
if (config.profileItems.Count <= 0)
if (config.ProfileItems.Count <= 0)
{
return null;
}
var index = config.FindIndexId(config.indexId);
var index = config.FindIndexId(config.IndexId);
if (index < 0)
{
SetDefaultProfile(ref config, config.profileItems[0]);
return config.profileItems[0];
SetDefaultProfile(ref config, config.ProfileItems[0]);
return config.ProfileItems[0];
}
return config.profileItems[index];
return config.ProfileItems[index];
}
/// <summary>
@@ -297,9 +285,9 @@ namespace ClashN.Handler
/// <param name="index"></param>
/// <param name="eMove"></param>
/// <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;
if (index < 0 || index > lstProfile.Count - 1)
{
@@ -313,48 +301,48 @@ namespace ClashN.Handler
switch (eMove)
{
case EMove.Top:
case MovementTarget.Top:
{
if (index == 0)
{
if (index == 0)
{
return 0;
}
lstProfile[index].sort = lstProfile[0].sort - 1;
break;
return 0;
}
case EMove.Up:
lstProfile[index].sort = lstProfile[0].sort - 1;
break;
}
case MovementTarget.Up:
{
if (index == 0)
{
if (index == 0)
{
return 0;
}
lstProfile[index].sort = lstProfile[index - 1].sort - 1;
break;
return 0;
}
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;
}
lstProfile[index].sort = lstProfile[index + 1].sort + 1;
break;
return 0;
}
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;
}
lstProfile[index].sort = lstProfile[lstProfile.Count - 1].sort + 1;
break;
return 0;
}
case EMove.Position:
lstProfile[index].sort = lstProfile[lstProfile.Count - 1].sort + 1;
break;
}
case MovementTarget.Position:
lstProfile[index].sort = pos * 10 + 1;
break;
}
@@ -366,19 +354,19 @@ namespace ClashN.Handler
public static int AddProfileViaContent(ref Config config, ProfileItem profileItem, string content)
{
if (Utils.IsNullOrEmpty(content))
if (string.IsNullOrEmpty(content))
{
return -1;
}
string newFileName = profileItem.address;
if (Utils.IsNullOrEmpty(newFileName))
if (string.IsNullOrEmpty(newFileName))
{
var ext = ".yaml";
newFileName = string.Format("{0}{1}", Utils.GetGUID(), ext);
profileItem.address = newFileName;
}
if (Utils.IsNullOrEmpty(profileItem.remarks))
if (string.IsNullOrEmpty(profileItem.remarks))
{
profileItem.remarks = "clash_local_file";
}
@@ -392,7 +380,7 @@ namespace ClashN.Handler
return -1;
}
if (Utils.IsNullOrEmpty(profileItem.remarks))
if (string.IsNullOrEmpty(profileItem.remarks))
{
profileItem.remarks = string.Format("import custom@{0}", DateTime.Now.ToShortDateString());
}
@@ -416,7 +404,7 @@ namespace ClashN.Handler
try
{
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));
}
@@ -427,7 +415,7 @@ namespace ClashN.Handler
}
profileItem.address = newFileName;
if (Utils.IsNullOrEmpty(profileItem.remarks))
if (string.IsNullOrEmpty(profileItem.remarks))
{
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)
{
if (!Utils.IsNullOrEmpty(profileItem.indexId) && config.indexId == profileItem.indexId)
if (!string.IsNullOrEmpty(profileItem.indexId) && config.IndexId == profileItem.indexId)
{
Global.reloadCore = true;
}
@@ -449,7 +437,7 @@ namespace ClashN.Handler
AddProfileCommon(ref config, profileItem);
//TODO auto update via url
//if (!Utils.IsNullOrEmpty(profileItem.url))
//if (!string.IsNullOrEmpty(profileItem.url))
//{
// var httpClient = new HttpClient();
// string result = httpClient.GetStringAsync(profileItem.url).Result;
@@ -502,20 +490,20 @@ namespace ClashN.Handler
public static int AddProfileCommon(ref Config config, ProfileItem profileItem)
{
if (Utils.IsNullOrEmpty(profileItem.indexId))
if (string.IsNullOrEmpty(profileItem.indexId))
{
profileItem.indexId = Utils.GetGUID(false);
}
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++;
config.profileItems.Add(profileItem);
config.ProfileItems.Add(profileItem);
}
return 0;
@@ -525,16 +513,16 @@ namespace ClashN.Handler
{
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)
{
Utils.SaveLog("RemoveProfileItem", ex);
}
config.profileItems.RemoveAt(index);
config.ProfileItems.RemoveAt(index);
return 0;
}
@@ -545,7 +533,7 @@ namespace ClashN.Handler
{
return string.Empty;
}
if (Utils.IsNullOrEmpty(item.address))
if (string.IsNullOrEmpty(item.address))
{
return string.Empty;
}
@@ -556,19 +544,19 @@ namespace ClashN.Handler
public static int AddBatchProfiles(ref Config config, string clipboardData, string indexId, string groupId)
{
if (Utils.IsNullOrEmpty(clipboardData))
if (string.IsNullOrEmpty(clipboardData))
{
return -1;
}
//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()
{
groupId = groupId,
url = clipboardData,
coreType = ECoreType.clash_meta,
coreType = CoreKind.ClashMeta,
address = string.Empty,
enabled = true,
remarks = "clash_subscription"
@@ -578,19 +566,19 @@ namespace ClashN.Handler
}
//maybe clashProtocol
if (Utils.IsNullOrEmpty(indexId) && (clipboardData.StartsWith(Global.clashProtocol)))
if (string.IsNullOrEmpty(indexId) && (clipboardData.StartsWith(Global.clashProtocol)))
{
Uri url = new Uri(clipboardData);
if (url.Host == "install-config")
{
var query = HttpUtility.ParseQueryString(url.Query);
if (!Utils.IsNullOrEmpty(query["url"] ?? ""))
if (!string.IsNullOrEmpty(query["url"] ?? ""))
{
ProfileItem item = new ProfileItem()
{
groupId = groupId,
url = query["url"],
coreType = ECoreType.clash_meta,
coreType = CoreKind.ClashMeta,
address = string.Empty,
enabled = true,
remarks = "clash_subscription"
@@ -608,7 +596,7 @@ namespace ClashN.Handler
{
groupId = groupId,
url = "",
coreType = ECoreType.clash_meta,
coreType = CoreKind.ClashMeta,
address = string.Empty,
enabled = false,
remarks = "clash_local_file"
@@ -622,10 +610,11 @@ namespace ClashN.Handler
&& clipboardData.IndexOf("proxies") >= 0
&& clipboardData.IndexOf("rules") >= 0)
{ }
else { return -1; }
else
{ return -1; }
ProfileItem profileItem;
if (!Utils.IsNullOrEmpty(indexId))
if (!string.IsNullOrEmpty(indexId))
{
profileItem = config.GetProfileItem(indexId);
}
@@ -648,7 +637,7 @@ namespace ClashN.Handler
public static void ClearAllServerStatistics(ref Config config)
{
foreach (var item in config.profileItems)
foreach (var item in config.ProfileItems)
{
item.uploadRemote = 0;
item.downloadRemote = 0;

View File

@@ -42,7 +42,7 @@ namespace ClashN.Handler
}
string addressFileName = node.address;
if (Utils.IsNullOrEmpty(addressFileName))
if (string.IsNullOrEmpty(addressFileName))
{
msg = ResUI.FailedGetDefaultConfiguration;
return -1;
@@ -60,7 +60,7 @@ namespace ClashN.Handler
string tagYamlStr1 = "!<str>";
string tagYamlStr2 = "__strn__";
string tagYamlStr3 = "!!str";
var config = LazyConfig.Instance.GetConfig();
var config = LazyConfig.Instance.Config;
var txtFile = File.ReadAllText(addressFileName);
txtFile = txtFile.Replace(tagYamlStr1, tagYamlStr2);
@@ -71,50 +71,51 @@ namespace ClashN.Handler
return -1;
}
//mixed-port
ModifyContent(fileContent, "mixed-port", config.mixedPort);
fileContent["mixed-port"] = config.MixedPort;
//port
ModifyContent(fileContent, "port", config.httpPort);
fileContent["port"] = config.HttpPort;
//socks-port
ModifyContent(fileContent, "socks-port", config.socksPort);
fileContent["socks-port"] = config.SocksPort;
//log-level
ModifyContent(fileContent, "log-level", config.logLevel);
fileContent["log-level"] = config.LogLevel;
//external-controller
ModifyContent(fileContent, "external-controller", $"{Global.Loopback}:{config.APIPort}");
fileContent["external-controller"] = $"{Global.Loopback}:{config.ApiPort}";
//allow-lan
if (config.allowLANConn)
if (config.AllowLANConn)
{
ModifyContent(fileContent, "allow-lan", "true");
ModifyContent(fileContent, "bind-address", "*");
fileContent["allow-lan"] = "true";
fileContent["bind-address"] = "*";
}
else
{
ModifyContent(fileContent, "allow-lan", "false");
fileContent["allow-lan"] = "false";
}
//ipv6
ModifyContent(fileContent, "ipv6", config.enableIpv6);
fileContent["ipv6"] = config.EnableIpv6;
//mode
if (!fileContent.ContainsKey("mode"))
{
ModifyContent(fileContent, "mode", ERuleMode.Rule.ToString().ToLower());
fileContent["mode"] = ERuleMode.Rule.ToString().ToLower();
}
else
{
if (config.ruleMode != ERuleMode.Unchanged)
{
ModifyContent(fileContent, "mode", config.ruleMode.ToString().ToLower());
fileContent["model"] = config.ruleMode.ToString().ToLower();
}
}
//enable tun mode
if (config.enableTun)
if (config.EnableTun)
{
string tun = Utils.GetEmbedText(Global.SampleTun);
if (!Utils.IsNullOrEmpty(tun))
if (!string.IsNullOrEmpty(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)
{
if (!config.enableMixinContent)
if (!config.EnableMixinContent)
{
return;
}
@@ -173,7 +174,7 @@ namespace ClashN.Handler
}
foreach (var item in mixinContent)
{
if (!config.enableTun && item.Key == "tun")
if (!config.EnableTun && item.Key == "tun")
{
continue;
}
@@ -186,23 +187,12 @@ namespace ClashN.Handler
}
else
{
ModifyContent(fileContent, item.Key, item.Value);
fileContent[item.Key] = item.Value;
}
}
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)
{
bool blPrepend = false;

View File

@@ -28,7 +28,7 @@ namespace ClashN.Handler
{
if (Global.reloadCore)
{
var item = ConfigHandler.GetDefaultProfile(ref config);
var item = ConfigProc.GetDefaultProfile(ref config);
if (item == null)
{
CoreStop();
@@ -36,12 +36,12 @@ namespace ClashN.Handler
return;
}
if (config.enableTun && !Utils.IsAdministrator())
if (config.EnableTun && !Utils.IsAdministrator())
{
ShowMsg(true, ResUI.EnableTunModeFailed);
return;
}
if (config.enableTun && item.coreType == ECoreType.clash)
if (config.EnableTun && item.coreType == CoreKind.Clash)
{
ShowMsg(true, ResUI.TunModeCoreTip);
return;
@@ -171,7 +171,7 @@ namespace ClashN.Handler
break;
}
}
if (Utils.IsNullOrEmpty(fileName))
if (string.IsNullOrEmpty(fileName))
{
string msg = string.Format(ResUI.NotFoundCore, coreInfo.coreUrl);
ShowMsg(false, msg);

View File

@@ -13,9 +13,8 @@ namespace ClashN.Handler
/// </summary>
class DownloadHandle
{
public event EventHandler<ResultEventArgs> UpdateCompleted;
public event ErrorEventHandler Error;
public event EventHandler<ResultEventArgs>? UpdateCompleted;
public event ErrorEventHandler? Error;
public class ResultEventArgs : EventArgs
@@ -34,7 +33,7 @@ namespace ClashN.Handler
{
try
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.EnableSecurityProtocolTls13);
UpdateCompleted?.Invoke(this, new ResultEventArgs(false, ResUI.Downloading));
var client = new HttpClient(new SocketsHttpHandler()
@@ -75,13 +74,13 @@ namespace ClashN.Handler
{
try
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.EnableSecurityProtocolTls13);
var client = new HttpClient(new SocketsHttpHandler()
{
Proxy = GetWebProxy(blProxy)
});
if (Utils.IsNullOrEmpty(userAgent))
if (string.IsNullOrEmpty(userAgent))
{
userAgent = $"{Utils.GetVersion(false)}";
}
@@ -89,7 +88,7 @@ namespace ClashN.Handler
Uri uri = new Uri(url);
//Authorization Header
if (!Utils.IsNullOrEmpty(uri.UserInfo))
if (!string.IsNullOrEmpty(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)
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.EnableSecurityProtocolTls13);
SocketsHttpHandler webRequestHandler = new SocketsHttpHandler
{
AllowAutoRedirect = false,
@@ -140,7 +139,7 @@ namespace ClashN.Handler
{
return null;
}
var socksPort = LazyConfig.Instance.GetConfig().socksPort;
var socksPort = LazyConfig.Instance.Config.SocksPort;
if (!SocketCheck(Global.Loopback, socksPort))
{
return null;

View File

@@ -19,10 +19,7 @@ namespace ClashN.Handler
{
_config = config;
}
public Config GetConfig()
{
return _config;
}
public Config Config => _config;
public void SetProxies(Dictionary<String, ProxiesItem> proxies)
{
@@ -35,17 +32,17 @@ namespace ClashN.Handler
public Dictionary<string, object> ProfileContent { get; set; }
public ECoreType GetCoreType(ProfileItem profileItem)
public CoreKind GetCoreType(ProfileItem profileItem)
{
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)
{
@@ -60,7 +57,7 @@ namespace ClashN.Handler
coreInfos.Add(new CoreInfo
{
coreType = ECoreType.clashN,
coreType = CoreKind.ClashN,
coreUrl = Global.NUrl,
coreLatestUrl = Global.NUrl + "/latest",
coreDownloadUrl32 = Global.NUrl + "/download/{0}/clashN-32.zip",
@@ -69,7 +66,7 @@ namespace ClashN.Handler
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" },
arguments = "-f config.yaml",
coreUrl = Global.clashCoreUrl,
@@ -81,7 +78,7 @@ namespace ClashN.Handler
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" },
arguments = "-f config.yaml",
coreUrl = Global.clashMetaCoreUrl,
@@ -93,7 +90,7 @@ namespace ClashN.Handler
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" },
arguments = "-f config.yaml",
coreUrl = Global.clashCoreUrl,

View File

@@ -23,7 +23,7 @@ namespace ClashN.Handler
{
try
{
int index = (int)config.sysProxyType;
int index = (int)config.SysProxyType;
//Load from local file
var fileName = Utils.GetPath($"NotifyIcon{index + 1}.ico");
@@ -76,7 +76,7 @@ namespace ClashN.Handler
}
fileName = fileDialog.FileName;
}
if (Utils.IsNullOrEmpty(fileName))
if (string.IsNullOrEmpty(fileName))
{
return;
}
@@ -112,9 +112,9 @@ namespace ClashN.Handler
{
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) =>
{
@@ -183,13 +183,13 @@ namespace ClashN.Handler
var gesture = new KeyGesture(KeyInterop.KeyFromVirtualKey((int)item.KeyCode), modifiers);
try
{
HotkeyManager.Current.AddOrReplace(((int)item.eGlobalHotkey).ToString(), gesture, handler);
var msg = string.Format(ResUI.RegisterGlobalHotkeySuccessfully, $"{item.eGlobalHotkey.ToString()} = {Utils.ToJson(item)}");
HotkeyManager.Current.AddOrReplace(((int)item.GlobalHotkey).ToString(), gesture, handler);
var msg = string.Format(ResUI.RegisterGlobalHotkeySuccessfully, $"{item.GlobalHotkey.ToString()} = {Utils.ToJson(item)}");
update(false, msg);
}
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);
Utils.SaveLog(msg);
}
@@ -205,12 +205,12 @@ namespace ClashN.Handler
{
for (var i = 0; i < 5; i++)
{
var url = $"{Global.httpProtocol}{Global.Loopback}:{config.APIPort}/proxies";
var result = await HttpClientHelper.GetInstance().GetAsync(url);
var url = $"{Global.httpProtocol}{Global.Loopback}:{config.ApiPort}/proxies";
var result = await HttpClientHelper.GetInstance().TryGetAsync(url);
var clashProxies = Utils.FromJson<ClashProxies>(result);
var url2 = $"{Global.httpProtocol}{Global.Loopback}:{config.APIPort}/providers/proxies";
var result2 = await HttpClientHelper.GetInstance().GetAsync(url2);
var url2 = $"{Global.httpProtocol}{Global.Loopback}:{config.ApiPort}/providers/proxies";
var result2 = await HttpClientHelper.GetInstance().TryGetAsync(url2);
var clashProviders = Utils.FromJson<ClashProviders>(result2);
if (clashProxies != null || clashProviders != null)
@@ -261,8 +261,8 @@ namespace ClashN.Handler
{
return;
}
var urlBase = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.GetConfig().APIPort}/proxies";
urlBase += @"/{0}/delay?timeout=10000&url=" + LazyConfig.Instance.GetConfig().constItem.speedPingTestUrl;
var urlBase = $"{Global.httpProtocol}{Global.Loopback}:{LazyConfig.Instance.Config.ApiPort}/proxies";
urlBase += @"/{0}/delay?timeout=10000&url=" + LazyConfig.Instance.Config.ConstItem.speedPingTestUrl;
List<Task> tasks = new List<Task>();
foreach (var it in lstProxy)
@@ -275,7 +275,7 @@ namespace ClashN.Handler
var url = string.Format(urlBase, name);
tasks.Add(Task.Run(async () =>
{
var result = await HttpClientHelper.GetInstance().GetAsync(url);
var result = await HttpClientHelper.GetInstance().TryGetAsync(url);
update(it, result);
}));
}
@@ -320,7 +320,7 @@ namespace ClashN.Handler
{
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>();
headers.Add("name", nameNode);
await HttpClientHelper.GetInstance().PutAsync(url, headers);
@@ -341,7 +341,7 @@ namespace ClashN.Handler
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);
});
@@ -352,7 +352,7 @@ namespace ClashN.Handler
ClashConnectionClose("");
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>();
headers.Add("path", filePath);
await HttpClientHelper.GetInstance().PutAsync(url, headers);
@@ -371,8 +371,8 @@ namespace ClashN.Handler
{
try
{
var url = $"{Global.httpProtocol}{Global.Loopback}:{config.APIPort}/connections";
var result = await HttpClientHelper.GetInstance().GetAsync(url);
var url = $"{Global.httpProtocol}{Global.Loopback}:{config.ApiPort}/connections";
var result = await HttpClientHelper.GetInstance().TryGetAsync(url);
var clashConnections = Utils.FromJson<ClashConnections>(result);
update(clashConnections);
@@ -387,7 +387,7 @@ namespace ClashN.Handler
{
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);
}
catch (Exception ex)

View File

@@ -21,7 +21,7 @@ namespace ClashN.Handler
}
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;
@@ -37,7 +37,7 @@ namespace ClashN.Handler
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];
// USE a proxy server ...
options[0].m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS;

View File

@@ -29,8 +29,8 @@ namespace ClashN.Handler
{
_selecteds.Add(new ServerTestItem()
{
indexId = it.indexId,
address = it.address
IndexId = it.indexId,
Address = it.address
});
}
@@ -74,9 +74,9 @@ namespace ClashN.Handler
{
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) =>
{
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
{
int httpPort = _config.httpPort;
int httpPort = _config.HttpPort;
Task<int> t = Task.Run(() =>
{
@@ -103,8 +103,8 @@ namespace ClashN.Handler
{
WebProxy webProxy = new WebProxy(Global.Loopback, httpPort);
int responseTime = -1;
string status = GetRealPingTime(LazyConfig.Instance.GetConfig().constItem.speedPingTestUrl, webProxy, out responseTime);
bool noError = Utils.IsNullOrEmpty(status);
string status = GetRealPingTime(LazyConfig.Instance.Config.ConstItem.speedPingTestUrl, webProxy, out responseTime);
bool noError = string.IsNullOrEmpty(status);
return noError ? responseTime : -1;
}
catch (Exception ex)

View File

@@ -30,7 +30,7 @@ namespace ClashN.Handler
public StatisticsHandler(Config config, Action<ulong, ulong> update)
{
config_ = config;
Enable = config.enableStatistics;
Enable = config.EnableStatistics;
updateFunc_ = update;
exitFlag_ = false;
@@ -46,7 +46,7 @@ namespace ClashN.Handler
try
{
url = $"ws://{Global.Loopback}:{config_.APIPort}/traffic";
url = $"ws://{Global.Loopback}:{config_.ApiPort}/traffic";
if (webSocket == null)
{
@@ -104,9 +104,9 @@ namespace ClashN.Handler
while (!res.CloseStatus.HasValue)
{
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);
if (up + down > 0)
{
@@ -134,7 +134,7 @@ namespace ClashN.Handler
// try
// {
// string result = Utils.LoadResource(Utils.GetConfigPath(Global.StatisticLogOverall));
// if (!Utils.IsNullOrEmpty(result))
// if (!string.IsNullOrEmpty(result))
// {
// serverStatistics_ = Utils.FromJson<ServerStatistics>(result);
// }
@@ -239,7 +239,7 @@ namespace ClashN.Handler
down = trafficItem.down;
}
}
catch (Exception ex)
catch (Exception)
{
//Utils.SaveLog(ex.Message, ex);
}

View File

@@ -36,54 +36,54 @@ namespace ClashN.Handler
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
{
int port = config.httpPort;
int socksPort = config.socksPort;
int port = config.HttpPort;
int socksPort = config.SocksPort;
if (port <= 0)
{
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;
if (Utils.IsNullOrEmpty(config.systemProxyAdvancedProtocol))
if (string.IsNullOrEmpty(config.SystemProxyAdvancedProtocol))
{
strProxy = $"{Global.Loopback}:{port}";
}
else
{
strProxy = config.systemProxyAdvancedProtocol
strProxy = config.SystemProxyAdvancedProtocol
.Replace("{ip}", Global.Loopback)
.Replace("{http_port}", port.ToString())
.Replace("{socks_port}", socksPort.ToString());
}
SetIEProxy(true, strProxy, strExceptions);
}
else if (type == ESysProxyType.ForcedClear)
else if (type == SysProxyType.ForcedClear)
{
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);
var strProxy = $"{Global.httpProtocol}{Global.Loopback}:{config.PacPort}/pac?t={DateTime.Now.Ticks}";
SetIEProxy(false, strProxy, "");
}
if (type != ESysProxyType.Pac)
if (type != SysProxyType.Pac)
{
PacHandler.Stop();
}
@@ -196,9 +196,8 @@ namespace ClashN.Handler
}
catch (System.ComponentModel.Win32Exception e)
{
// log the arguments
throw new Exception(process.StartInfo.Arguments);
throw new Exception(process.StartInfo.Arguments, e);
}
string stderr = error.ToString();
string stdout = output.ToString();

View File

@@ -88,7 +88,7 @@ namespace ClashN.Handler
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, "clashN"));
url = args.Msg;
askToDownload(downloadHandle, url, true);
AskToDownload(downloadHandle, url, true);
}
else
{
@@ -97,11 +97,11 @@ namespace ClashN.Handler
}
};
_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;
_updateFunc = update;
@@ -144,7 +144,7 @@ namespace ClashN.Handler
{
_updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, "Core"));
url = args.Msg;
askToDownload(downloadHandle, url, true);
AskToDownload(downloadHandle, url, true);
}
else
{
@@ -164,7 +164,7 @@ namespace ClashN.Handler
_updateFunc(false, ResUI.MsgUpdateSubscriptionStart);
if (config.profileItems == null || config.profileItems.Count <= 0)
if (config.ProfileItems == null || config.ProfileItems.Count <= 0)
{
_updateFunc(false, ResUI.MsgNoValidSubscription);
return;
@@ -174,17 +174,17 @@ namespace ClashN.Handler
{
//Turn off system proxy
bool bSysProxyType = false;
if (!blProxy && config.sysProxyType == ESysProxyType.ForcedChange)
if (!blProxy && config.SysProxyType == SysProxyType.ForcedChange)
{
bSysProxyType = true;
config.sysProxyType = ESysProxyType.ForcedClear;
config.SysProxyType = SysProxyType.ForcedClear;
SysProxyHandle.UpdateSysProxy(config, false);
Thread.Sleep(3000);
}
if (profileItems == null)
{
profileItems = config.profileItems;
profileItems = config.ProfileItems;
}
foreach (var item in profileItems)
{
@@ -193,7 +193,7 @@ namespace ClashN.Handler
string userAgent = item.userAgent.TrimEx();
string groupId = item.groupId.TrimEx();
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}");
continue;
@@ -203,11 +203,11 @@ namespace ClashN.Handler
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="))
{
url += String.Format("&config={0}", Global.SubConvertConfig[0]);
@@ -219,12 +219,12 @@ namespace ClashN.Handler
_updateFunc(false, $"{hashCode}{args.GetException().Message}");
};
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);
}
if (Utils.IsNullOrEmpty(result.Item1))
if (string.IsNullOrEmpty(result.Item1))
{
_updateFunc(false, $"{hashCode}{ResUI.MsgSubscriptionDecodingFailed}");
}
@@ -236,7 +236,7 @@ namespace ClashN.Handler
_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)
{
item.updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
@@ -282,7 +282,7 @@ namespace ClashN.Handler
//restore system proxy
if (bSysProxyType)
{
config.sysProxyType = ESysProxyType.ForcedChange;
config.SysProxyType = SysProxyType.ForcedChange;
SysProxyHandle.UpdateSysProxy(config, false);
}
_updateFunc(true, $"{ResUI.MsgUpdateSubscriptionEnd}");
@@ -340,12 +340,12 @@ namespace ClashN.Handler
};
}
askToDownload(downloadHandle, url, false);
AskToDownload(downloadHandle, url, false);
}
#region private
private async void CheckUpdateAsync(ECoreType type)
private async void CheckUpdateAsync(CoreKind type)
{
try
{
@@ -353,7 +353,7 @@ namespace ClashN.Handler
string url = coreInfo.coreLatestUrl;
var result = await (new DownloadHandle()).UrlRedirectAsync(url, true);
if (!Utils.IsNullOrEmpty(result))
if (!string.IsNullOrEmpty(result))
{
responseHandler(type, result);
}
@@ -377,7 +377,7 @@ namespace ClashN.Handler
/// <summary>
/// 获取Core版本
/// </summary>
private string getCoreVersion(ECoreType type)
private string getCoreVersion(CoreKind type)
{
try
{
@@ -393,7 +393,7 @@ namespace ClashN.Handler
break;
}
}
if (Utils.IsNullOrEmpty(filePath))
if (string.IsNullOrEmpty(filePath))
{
string msg = string.Format(ResUI.NotFoundCore, @"");
return "";
@@ -420,7 +420,7 @@ namespace ClashN.Handler
return "";
}
}
private void responseHandler(ECoreType type, string redirectUrl)
private void responseHandler(CoreKind type, string redirectUrl)
{
try
{
@@ -430,7 +430,7 @@ namespace ClashN.Handler
string curVersion;
string message;
string url;
if (type == ECoreType.clash)
if (type == CoreKind.Clash)
{
curVersion = getCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, curVersion);
@@ -443,7 +443,7 @@ namespace ClashN.Handler
url = string.Format(coreInfo.coreDownloadUrl32, version);
}
}
else if (type == ECoreType.clash_meta)
else if (type == CoreKind.ClashMeta)
{
curVersion = getCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, curVersion);
@@ -456,7 +456,7 @@ namespace ClashN.Handler
url = string.Format(coreInfo.coreDownloadUrl32, version);
}
}
else if (type == ECoreType.clashN)
else if (type == CoreKind.ClashN)
{
curVersion = FileVersionInfo.GetVersionInfo(Utils.GetExePath()).FileVersion.ToString();
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;
if (blAsk)

View File

@@ -2,36 +2,36 @@
{
public class ClashConnections
{
public ulong downloadTotal { get; set; }
public ulong uploadTotal { get; set; }
public List<ConnectionItem> connections { get; set; }
public ulong DownloadTotal { get; set; }
public ulong UploadTotal { get; set; }
public List<ConnectionItem> Connections { get; } = new List<ConnectionItem>();
}
public class ConnectionItem
{
public string id { get; set; }
public string Id { get; set; } = string.Empty;
public MetadataItem metadata { get; set; }
public ulong upload { get; set; }
public ulong download { 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 rulePayload { get; set; }
}
public class MetadataItem
{
public string network { get; set; }
public string type { get; set; }
public string sourceIP { get; set; }
public string destinationIP { get; set; }
public string sourcePort { get; set; }
public string destinationPort { get; set; }
public string host { get; set; }
public string dnsMode { get; set; }
public object uid { get; set; }
public string process { get; set; }
public string processPath { get; set; }
public string remoteDestination { get; set; }
public string Network { get; set; }
public string Type { get; set; }
public string SourceIP { get; set; }
public string DestinationIP { get; set; }
public string SourcePort { get; set; }
public string DestinationPort { get; set; }
public string Host { get; set; }
public string DnsMode { get; set; }
public object Uid { get; set; }
public string Process { get; set; }
public string ProcessPath { get; set; }
public string RemoteDestination { get; set; }
}
}

View File

@@ -2,13 +2,7 @@
{
class ComboItem
{
public int ID
{
get; set;
}
public string Text
{
get; set;
}
public int ID { get; set; }
public string Text { get; set; }
}
}

View File

@@ -1,5 +1,4 @@
using System.Drawing;
using System.Windows.Forms;
namespace ClashN.Mode
{
@@ -10,69 +9,57 @@ namespace ClashN.Mode
public class Config
{
#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 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 systemProxyAdvancedProtocol { get; set; }
public string SystemProxyExceptions { get; set; }
public string SystemProxyAdvancedProtocol { get; set; }
public int autoUpdateSubInterval { get; set; } = 10;
public int autoDelayTestInterval { get; set; } = 10;
public int AutoUpdateSubInterval { 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 bool autoHideStartup { get; set; }
public bool AutoHideStartup { get; set; }
public bool enableTun { get; set; }
public bool EnableTun { get; set; }
#endregion
#region other entities
public List<ProfileItem> profileItems
{
get; set;
}
public List<ProfileItem> ProfileItems { get; } = new List<ProfileItem>();
public UIItem uiItem
{
get; set;
}
public UIItem? UiItem { get; set; }
public ConstItem constItem
{
get; set;
}
public ConstItem? ConstItem { get; set; }
public List<KeyEventItem> globalHotkeys
{
get; set;
}
public List<KeyShortcut> globalHotkeys { get; } = new List<KeyShortcut>();
#endregion
@@ -80,25 +67,25 @@ namespace ClashN.Mode
public int FindIndexId(string id)
{
if (Utils.IsNullOrEmpty(id))
if (string.IsNullOrEmpty(id))
{
return -1;
}
return profileItems.FindIndex(it => it.indexId == id);
return ProfileItems.FindIndex(it => it.indexId == id);
}
public ProfileItem GetProfileItem(string id)
{
if (Utils.IsNullOrEmpty(id))
if (string.IsNullOrEmpty(id))
{
return null;
}
return profileItems.FirstOrDefault(it => it.indexId == id);
return ProfileItems.FirstOrDefault(it => it.indexId == id);
}
public bool IsActiveNode(ProfileItem item)
{
if (!Utils.IsNullOrEmpty(item.indexId) && item.indexId == indexId)
if (!string.IsNullOrEmpty(item.indexId) && item.indexId == IndexId)
{
return true;
}
@@ -135,44 +122,20 @@ namespace ClashN.Mode
#endregion
public string indexId
{
get; set;
}
public string indexId { get; set; }
public int sort
{
get; set;
}
public int sort { get; set; }
public string address
{
get; set;
}
public string address { get; set; }
public string remarks
{
get; set;
}
public string remarks { get; set; }
public string testResult
{
get; set;
}
public string testResult { get; set; }
public string groupId
{
get; set;
} = string.Empty;
public ECoreType? coreType
{
get; set;
}
public string groupId { get; set; } = string.Empty;
public CoreKind? coreType { get; set; }
public string url
{
get; set;
}
public string url { get; set; }
public bool enabled { get; set; } = true;
@@ -228,18 +191,4 @@ namespace ClashN.Mode
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; }
}
}

View File

@@ -3,7 +3,7 @@
[Serializable]
public class CoreInfo
{
public ECoreType coreType { get; set; }
public CoreKind coreType { get; set; }
public List<string> coreExes { get; set; }

View File

@@ -0,0 +1,11 @@

namespace ClashN.Mode
{
public enum CoreKind
{
Clash = 1,
ClashMeta = 2,
ClashPremium = 3,
ClashN = 99
}
}

View File

@@ -1,11 +0,0 @@

namespace ClashN.Mode
{
public enum ECoreType
{
clash = 1,
clash_meta = 2,
clash_premium = 3,
clashN = 99
}
}

View File

@@ -1,7 +1,7 @@

namespace ClashN.Mode
{
public enum EGlobalHotkey
public enum GlobalHotkeyAction
{
ShowForm = 0,
SystemProxyClear = 1,

View 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; }
}
}

View File

@@ -1,7 +1,7 @@

namespace ClashN.Mode
{
public enum EMove
public enum MovementTarget
{
Top = 1,
Up = 2,

View File

@@ -4,15 +4,9 @@ namespace ClashN.Mode
{
public class ProfileItemModel : ProfileItem
{
public bool isActive { get; set; }
public bool HasUrl
{
get { return !url.IsNullOrEmpty(); }
}
public bool HasAddress
{
get { return !address.IsNullOrEmpty(); }
}
public bool IsActive { get; set; }
public bool HasUrl => string.IsNullOrEmpty(url);
public bool HasAddress => string.IsNullOrEmpty(address);
public string StrUpdateTime
{
get
@@ -25,14 +19,8 @@ namespace ClashN.Mode
return dateTime.AddSeconds(updateTime).ToLocalTime().ToString("MM-dd HH:mm");
}
}
public string TrafficUsed
{
get { return Utils.HumanFy(uploadRemote + downloadRemote); }
}
public string TrafficTotal
{
get { return totalRemote <= 0 ? "∞" : Utils.HumanFy(totalRemote); }
}
public string TrafficUsed => Utils.HumanFy(uploadRemote + downloadRemote);
public string TrafficTotal => totalRemote <= 0 ? "∞" : Utils.HumanFy(totalRemote);
public string StrExpireTime
{
get

View File

@@ -3,21 +3,9 @@
[Serializable]
class ServerTestItem
{
public string indexId
{
get; set;
}
public string address
{
get; set;
}
public int port
{
get; set;
}
public bool allowTest
{
get; set;
}
public string IndexId { get; set; }
public string Address { get; set; }
public int Port { get; set; }
public bool AllowTest { get; set; }
}
}

View File

@@ -1,7 +1,7 @@

namespace ClashN.Mode
{
public enum ESysProxyType
public enum SysProxyType
{
ForcedClear = 0,
ForcedChange = 1,

View File

@@ -81,7 +81,7 @@ namespace ClashN.Tool
}
try
{
if (!Utils.IsNullOrEmpty(ignoredName) && entry.Name.Contains(ignoredName))
if (!string.IsNullOrEmpty(ignoredName) && entry.Name.Contains(ignoredName))
{
continue;
}

View File

@@ -7,14 +7,16 @@ namespace ClashN.Tool
{
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName)
{
return _OrderBy<T>(query, propertyName, false);
}
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName)
{
return _OrderBy<T>(query, propertyName, true);
return OrderBy<T>(query, propertyName, false);
}
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";
@@ -25,17 +27,21 @@ namespace ClashN.Tool
return (IOrderedQueryable<T>)method.Invoke(null, new object[] { query, memberProp });
}
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 lamba = Expression.Lambda<Func<T, TProp>>(Expression.Property(thisArg, memberProperty), thisArg);

View File

@@ -21,6 +21,7 @@ using System.Text.RegularExpressions;
using System.Web;
using System.Windows.Forms;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using ZXing;
using ZXing.Common;
using ZXing.QrCode;
@@ -407,7 +408,7 @@ namespace ClashN
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public static bool IsNullOrEmpty(string text)
public static bool IsNullOrEmpty(string? text)
{
if (string.IsNullOrEmpty(text))
{
@@ -846,13 +847,13 @@ namespace ClashN
string location = GetExePath();
if (blFull)
{
return string.Format("clashN - V{0} - {1}",
return string.Format("ClashN - V{0} - {1}",
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString(),
File.GetLastWriteTime(location).ToString("yyyy/MM/dd"));
}
else
{
return string.Format("clashN/{0}",
return string.Format("ClashN/{0}",
FileVersionInfo.GetVersionInfo(location).FileVersion?.ToString());
}
}
@@ -889,9 +890,9 @@ namespace ClashN
/// 获取剪贴板数
/// </summary>
/// <returns></returns>
public static string GetClipboardData()
public static string? GetClipboardData()
{
string strData = string.Empty;
string? strData = null;
try
{
@@ -900,7 +901,8 @@ namespace ClashN
{
strData = data.GetData(DataFormats.UnicodeText).ToString();
}
if (Utils.IsNullOrEmpty(strData))
if (string.IsNullOrEmpty(strData))
{
var file = Clipboard.GetFileDropList();
if (file.Count > 0)
@@ -915,6 +917,7 @@ namespace ClashN
{
SaveLog(ex.Message, ex);
}
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");
if (!Directory.Exists(_tempPath))
@@ -1223,7 +1226,7 @@ namespace ClashN
public static T FromYaml<T>(string str)
{
var deserializer = new DeserializerBuilder()
//.WithNamingConvention(UnderscoredNamingConvention.Instance)
.WithNamingConvention(PascalCaseNamingConvention.Instance)
.Build();
try
{
@@ -1245,7 +1248,7 @@ namespace ClashN
public static string ToYaml(Object obj)
{
var serializer = new SerializerBuilder()
//.WithNamingConvention(CamelCaseNamingConvention.Instance)
.WithNamingConvention(HyphenatedNamingConvention.Instance)
.Build();
string result = string.Empty;

View File

@@ -15,6 +15,14 @@ namespace ClashN.ViewModels
public class ConnectionsViewModel : ReactiveObject
{
private static Config _config;
static ConnectionsViewModel()
{
_config = LazyConfig.Instance.Config;
}
private NoticeHandler? _noticeHandler;
private IObservableCollection<ConnectionModel> _connectionItems = new ObservableCollectionExtended<ConnectionModel>();
@@ -35,11 +43,10 @@ namespace ClashN.ViewModels
public ConnectionsViewModel()
{
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_config = LazyConfig.Instance.GetConfig();
AutoRefreshInterval = 10;
SortingSelected = _config.uiItem.connectionsSorting;
AutoRefresh = _config.uiItem.connectionsAutoRefresh;
SortingSelected = _config.UiItem.connectionsSorting;
AutoRefresh = _config.UiItem.connectionsAutoRefresh;
var canEditRemove = this.WhenAnyValue(
x => x.SelectedSource,
@@ -47,13 +54,13 @@ namespace ClashN.ViewModels
this.WhenAnyValue(
x => x.SortingSelected,
y => y != null && y >= 0)
y => y >= 0)
.Subscribe(c => DoSortingSelected(c));
this.WhenAnyValue(
x => x.AutoRefresh,
y => y == true)
.Subscribe(c => { _config.uiItem.connectionsAutoRefresh = AutoRefresh; });
.Subscribe(c => { _config.UiItem.connectionsAutoRefresh = AutoRefresh; });
ConnectionCloseCmd = ReactiveCommand.Create(() =>
{
@@ -74,9 +81,9 @@ namespace ClashN.ViewModels
{
return;
}
if (SortingSelected != _config.uiItem.connectionsSorting)
if (SortingSelected != _config.UiItem.connectionsSorting)
{
_config.uiItem.connectionsSorting = SortingSelected;
_config.UiItem.connectionsSorting = SortingSelected;
}
GetClashConnections();
@@ -119,7 +126,7 @@ namespace ClashN.ViewModels
Application.Current.Dispatcher.Invoke((Action)(() =>
{
RefreshConnections(it?.connections!);
RefreshConnections(it?.Connections!);
}));
});
}
@@ -134,10 +141,10 @@ namespace ClashN.ViewModels
{
ConnectionModel model = new();
model.id = item.id;
model.network = item.metadata.network;
model.type = item.metadata.type;
model.host = $"{(item.metadata.host.IsNullOrEmpty() ? item.metadata.destinationIP : item.metadata.host)}:{item.metadata.destinationPort}";
model.id = item.Id;
model.network = item.metadata.Network;
model.type = item.metadata.Type;
model.host = $"{(item.metadata.Host.IsNullOrEmpty() ? item.metadata.DestinationIP : item.metadata.Host)}:{item.metadata.DestinationPort}";
var sp = (dtNow - item.start);
model.time = sp.TotalSeconds < 0 ? 1 : sp.TotalSeconds;
model.upload = item.upload;
@@ -145,7 +152,7 @@ namespace ClashN.ViewModels
model.uploadTraffic = $"{Utils.HumanFy(item.upload)}";
model.downloadTraffic = $"{Utils.HumanFy(item.download)}";
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);
}

View File

@@ -19,7 +19,7 @@ namespace ClashN.ViewModels
public HelpViewModel()
{
_config = LazyConfig.Instance.GetConfig();
_config = LazyConfig.Instance.Config;
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
CheckUpdateCmd = ReactiveCommand.Create(() =>
@@ -28,11 +28,11 @@ namespace ClashN.ViewModels
});
CheckUpdateClashCoreCmd = ReactiveCommand.Create(() =>
{
CheckUpdateCore(ECoreType.clash);
CheckUpdateCore(CoreKind.Clash);
});
CheckUpdateClashMetaCoreCmd = ReactiveCommand.Create(() =>
{
CheckUpdateCore(ECoreType.clash_meta);
CheckUpdateCore(CoreKind.ClashMeta);
});
}
@@ -48,7 +48,7 @@ namespace ClashN.ViewModels
};
(new UpdateHandle()).CheckUpdateGuiN(_config, _updateUI);
}
private void CheckUpdateCore(ECoreType type)
private void CheckUpdateCore(CoreKind type)
{
void _updateUI(bool success, string msg)
{

View File

@@ -92,7 +92,7 @@ namespace ClashN.ViewModels
public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue)
{
_config = LazyConfig.Instance.GetConfig();
_config = LazyConfig.Instance.Config;
Locator.CurrentMutable.RegisterLazySingleton(() => new NoticeHandler(snackbarMessageQueue), typeof(NoticeHandler));
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
@@ -112,7 +112,7 @@ namespace ClashN.ViewModels
GetPromotionView = new();
RestoreUI();
if (_config.autoHideStartup)
if (_config.AutoHideStartup)
{
Observable.Range(1, 1)
.Delay(TimeSpan.FromSeconds(1))
@@ -129,19 +129,19 @@ namespace ClashN.ViewModels
//System proxy
SystemProxyClearCmd = ReactiveCommand.Create(() =>
{
SetListenerType(ESysProxyType.ForcedClear);
SetListenerType(SysProxyType.ForcedClear);
});//, this.WhenAnyValue(x => x.BlSystemProxyClear, y => !y));
SystemProxySetCmd = ReactiveCommand.Create(() =>
{
SetListenerType(ESysProxyType.ForcedChange);
SetListenerType(SysProxyType.ForcedChange);
});//, this.WhenAnyValue(x => x.BlSystemProxySet, y => !y));
SystemProxyNothingCmd = ReactiveCommand.Create(() =>
{
SetListenerType(ESysProxyType.Unchanged);
SetListenerType(SysProxyType.Unchanged);
});//, this.WhenAnyValue(x => x.BlSystemProxyNothing, y => !y));
SystemProxyPacCmd = ReactiveCommand.Create(() =>
{
SetListenerType(ESysProxyType.Pac);
SetListenerType(SysProxyType.Pac);
});//, this.WhenAnyValue(x => x.BlSystemProxyNothing, y => !y));
//Rule mode
@@ -195,18 +195,17 @@ namespace ClashN.ViewModels
{
Application.Current.Dispatcher.Invoke((Action)(() =>
{
string clipboardData = Utils.GetClipboardData();
if (state != null)
string? clipboardData = Utils.GetClipboardData();
if (state != null && clipboardData != null)
{
if (Utils.IsNullOrEmpty(clipboardData) || !clipboardData.StartsWith(Global.clashProtocol))
if (string.IsNullOrEmpty(clipboardData) || !clipboardData.StartsWith(Global.clashProtocol))
{
return;
}
}
if (!blFirst)
{
ShowHideWindow(true);
}
Locator.Current.GetService<ProfilesViewModel>()?.AddProfilesViaClipboard(true);
}));
@@ -229,7 +228,7 @@ namespace ClashN.ViewModels
}
StorageUI();
ConfigHandler.SaveConfig(ref _config);
ConfigProc.SaveConfig(_config);
//statistics?.SaveToFile();
statistics?.Close();
}
@@ -245,20 +244,20 @@ namespace ClashN.ViewModels
{
switch (Utils.ToInt(e.Name))
{
case (int)EGlobalHotkey.ShowForm:
case (int)GlobalHotkeyAction.ShowForm:
ShowHideWindow(null);
break;
case (int)EGlobalHotkey.SystemProxyClear:
SetListenerType(ESysProxyType.ForcedClear);
case (int)GlobalHotkeyAction.SystemProxyClear:
SetListenerType(SysProxyType.ForcedClear);
break;
case (int)EGlobalHotkey.SystemProxySet:
SetListenerType(ESysProxyType.ForcedChange);
case (int)GlobalHotkeyAction.SystemProxySet:
SetListenerType(SysProxyType.ForcedChange);
break;
case (int)EGlobalHotkey.SystemProxyUnchanged:
SetListenerType(ESysProxyType.Unchanged);
case (int)GlobalHotkeyAction.SystemProxyUnchanged:
SetListenerType(SysProxyType.Unchanged);
break;
case (int)EGlobalHotkey.SystemProxyPac:
SetListenerType(ESysProxyType.Pac);
case (int)GlobalHotkeyAction.SystemProxyPac:
SetListenerType(SysProxyType.Pac);
break;
}
e.Handled = true;
@@ -273,7 +272,7 @@ namespace ClashN.ViewModels
coreHandler = new CoreHandler(UpdateHandler);
if (_config.enableStatistics)
if (_config.EnableStatistics)
{
statistics = new StatisticsHandler(_config, UpdateStatisticsHandler);
}
@@ -346,10 +345,10 @@ namespace ClashN.ViewModels
});
Global.reloadCore = false;
ConfigHandler.SaveConfig(ref _config, false);
ConfigProc.SaveConfig(_config, false);
//statistics?.SaveToFile();
ChangePACButtonStatus(_config.sysProxyType);
ChangePACButtonStatus(_config.SysProxyType);
SetRuleMode(_config.ruleMode);
Locator.Current.GetService<ProxiesViewModel>()?.ProxiesReload();
@@ -359,10 +358,10 @@ namespace ClashN.ViewModels
public void CloseCore()
{
ConfigHandler.SaveConfig(ref _config, false);
ConfigProc.SaveConfig(_config, false);
//statistics?.SaveToFile();
ChangePACButtonStatus(ESysProxyType.ForcedClear);
ChangePACButtonStatus(SysProxyType.ForcedClear);
coreHandler.CoreStop();
}
@@ -370,30 +369,30 @@ namespace ClashN.ViewModels
#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;
}
_config.sysProxyType = type;
_config.SysProxyType = type;
ChangePACButtonStatus(type);
Locator.Current.GetService<ProxiesViewModel>()?.ReloadSystemProxySelected();
}
private void ChangePACButtonStatus(ESysProxyType type)
private void ChangePACButtonStatus(SysProxyType type)
{
SysProxyHandle.UpdateSysProxy(_config, false);
BlSystemProxyClear = (type == ESysProxyType.ForcedClear);
BlSystemProxySet = (type == ESysProxyType.ForcedChange);
BlSystemProxyNothing = (type == ESysProxyType.Unchanged);
BlSystemProxyPac = (type == ESysProxyType.Pac);
BlSystemProxyClear = (type == SysProxyType.ForcedClear);
BlSystemProxySet = (type == SysProxyType.ForcedChange);
BlSystemProxyNothing = (type == SysProxyType.Unchanged);
BlSystemProxyPac = (type == SysProxyType.Pac);
_noticeHandler?.SendMessage($"Change system proxy", true);
ConfigHandler.SaveConfig(ref _config, false);
ConfigProc.SaveConfig(_config, false);
//mainMsgControl.DisplayToolStatus(config);
@@ -422,7 +421,7 @@ namespace ClashN.ViewModels
_noticeHandler?.SendMessage($"Set rule mode {_config.ruleMode.ToString()}->{mode.ToString()}", true);
_config.ruleMode = mode;
ConfigHandler.SaveConfig(ref _config, false);
ConfigProc.SaveConfig(_config, false);
if (mode != ERuleMode.Unchanged)
{
@@ -459,11 +458,11 @@ namespace ClashN.ViewModels
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
&& swatch.ExemplarHue != null
&& swatch.ExemplarHue?.Color != null)
@@ -477,10 +476,10 @@ namespace ClashN.ViewModels
// 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.Height = _config.uiItem.mainHeight;
Application.Current.MainWindow.Width = _config.UiItem.mainWidth;
Application.Current.MainWindow.Height = _config.UiItem.mainHeight;
}
IntPtr hWnd = new WindowInteropHelper(Application.Current.MainWindow).EnsureHandle();
@@ -496,8 +495,8 @@ namespace ClashN.ViewModels
}
private void StorageUI()
{
_config.uiItem.mainWidth = Application.Current.MainWindow.Width;
_config.uiItem.mainHeight = Application.Current.MainWindow.Height;
_config.UiItem.mainWidth = Application.Current.MainWindow.Width;
_config.UiItem.mainHeight = Application.Current.MainWindow.Height;
}
public void ModifyTheme(bool isDarkTheme)

View File

@@ -32,7 +32,7 @@ namespace ClashN.ViewModels
public ProfileEditViewModel(ProfileItem profileItem, PorfileEditWindow view)
{
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_config = LazyConfig.Instance.GetConfig();
_config = LazyConfig.Instance.Config;
if (profileItem.indexId.IsNullOrEmpty())
{
@@ -44,7 +44,7 @@ namespace ClashN.ViewModels
}
_view = view;
CoreType = (SelectedSource.coreType ?? ECoreType.clash).ToString();
CoreType = (SelectedSource.coreType ?? CoreKind.Clash).ToString();
BrowseProfileCmd = ReactiveCommand.Create(() =>
{
@@ -61,25 +61,25 @@ namespace ClashN.ViewModels
SaveProfile();
});
Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);
Utils.SetDarkBorder(view, _config.UiItem.colorModeDark);
}
private void SaveProfile()
{
string remarks = SelectedSource.remarks;
if (Utils.IsNullOrEmpty(remarks))
if (string.IsNullOrEmpty(remarks))
{
_noticeHandler?.Enqueue(ResUI.PleaseFillRemarks);
return;
}
if (Utils.IsNullOrEmpty(CoreType))
if (string.IsNullOrEmpty(CoreType))
{
SelectedSource.coreType = null;
}
else
{
SelectedSource.coreType = (ECoreType)Enum.Parse(typeof(ECoreType), CoreType);
SelectedSource.coreType = (CoreKind)Enum.Parse(typeof(CoreKind), CoreType);
}
var item = _config.GetProfileItem(SelectedSource.indexId);
@@ -98,7 +98,7 @@ namespace ClashN.ViewModels
item.enableConvert = SelectedSource.enableConvert;
}
if (ConfigHandler.EditProfile(ref _config, item) == 0)
if (ConfigProc.EditProfile(ref _config, item) == 0)
{
Locator.Current.GetService<ProfilesViewModel>()?.RefreshProfiles();
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
@@ -128,7 +128,7 @@ namespace ClashN.ViewModels
return;
}
string fileName = fileDialog.FileName;
if (Utils.IsNullOrEmpty(fileName))
if (string.IsNullOrEmpty(fileName))
{
return;
}
@@ -137,7 +137,7 @@ namespace ClashN.ViewModels
{
item = SelectedSource;
}
if (ConfigHandler.AddProfileViaPath(ref _config, item, fileName) == 0)
if (ConfigProc.AddProfileViaPath(ref _config, item, fileName) == 0)
{
_noticeHandler?.Enqueue(ResUI.SuccessfullyImportedCustomProfile);
Locator.Current.GetService<ProfilesViewModel>()?.RefreshProfiles();
@@ -152,7 +152,7 @@ namespace ClashN.ViewModels
private void EditProfile()
{
var address = SelectedSource.address;
if (Utils.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(address))
{
_noticeHandler?.Enqueue(ResUI.FillProfileAddressCustom);
return;

View File

@@ -51,7 +51,7 @@ namespace ClashN.ViewModels
public ProfilesViewModel()
{
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_config = LazyConfig.Instance.GetConfig();
_config = LazyConfig.Instance.Config;
SelectedSource = new();
@@ -128,7 +128,7 @@ namespace ClashN.ViewModels
ClearStatisticCmd = ReactiveCommand.Create(() =>
{
ConfigHandler.ClearAllServerStatistics(ref _config);
ConfigProc.ClearAllServerStatistics(ref _config);
RefreshProfiles();
});
ProfileReloadCmd = ReactiveCommand.Create(() =>
@@ -144,7 +144,7 @@ namespace ClashN.ViewModels
private void EditLocalFile()
{
var address = SelectedSource.address;
if (Utils.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(address))
{
_noticeHandler?.Enqueue(ResUI.FillProfileAddressCustom);
return;
@@ -168,7 +168,7 @@ namespace ClashN.ViewModels
{
item = new()
{
coreType = ECoreType.clash_meta
coreType = CoreKind.ClashMeta
};
}
else
@@ -202,13 +202,13 @@ namespace ClashN.ViewModels
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(true);
if (Utils.IsNullOrEmpty(result))
if (string.IsNullOrEmpty(result))
{
_noticeHandler?.Enqueue(ResUI.NoValidQRcodeFound);
}
else
{
int ret = ConfigHandler.AddBatchProfiles(ref _config, result, "", "");
int ret = ConfigProc.AddBatchProfiles(ref _config, result, "", "");
if (ret == 0)
{
RefreshProfiles();
@@ -218,12 +218,12 @@ namespace ClashN.ViewModels
}
public void AddProfilesViaClipboard(bool bClear)
{
string clipboardData = Utils.GetClipboardData();
if (Utils.IsNullOrEmpty(clipboardData))
string? clipboardData = Utils.GetClipboardData();
if (string.IsNullOrEmpty(clipboardData))
{
return;
}
int ret = ConfigHandler.AddBatchProfiles(ref _config, clipboardData, "", "");
int ret = ConfigProc.AddBatchProfiles(ref _config, clipboardData, "", "");
if (ret == 0)
{
if (bClear)
@@ -242,8 +242,8 @@ namespace ClashN.ViewModels
{
return;
}
var content = ConfigHandler.GetProfileContent(item);
if (Utils.IsNullOrEmpty(content))
var content = ConfigProc.GetProfileContent(item);
if (string.IsNullOrEmpty(content))
{
content = item.url;
}
@@ -286,7 +286,7 @@ namespace ClashN.ViewModels
return;
}
ConfigHandler.RemoveProfile(_config, new List<ProfileItem>() { item });
ConfigProc.RemoveProfile(_config, new List<ProfileItem>() { item });
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
@@ -301,7 +301,7 @@ namespace ClashN.ViewModels
{
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);
RefreshProfiles();
@@ -309,7 +309,7 @@ namespace ClashN.ViewModels
}
public void SetDefaultProfile()
{
if (Utils.IsNullOrEmpty(SelectedSource?.indexId))
if (string.IsNullOrEmpty(SelectedSource?.indexId))
{
return;
}
@@ -320,7 +320,7 @@ namespace ClashN.ViewModels
return;
}
if (ConfigHandler.SetDefaultProfile(ref _config, item) == 0)
if (ConfigProc.SetDefaultProfile(ref _config, item) == 0)
{
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
RefreshProfiles();
@@ -331,13 +331,13 @@ namespace ClashN.ViewModels
public void RefreshProfiles()
{
ConfigHandler.SetDefaultProfile(_config, _config.profileItems);
ConfigProc.SetDefaultProfile(_config, _config.ProfileItems);
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));
model.isActive = _config.IsActiveNode(item);
model.IsActive = _config.IsActiveNode(item);
lstModel.Add(model);
}
@@ -354,7 +354,7 @@ namespace ClashN.ViewModels
var targetIndex = _profileItems.IndexOf(targetItem);
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();
}
@@ -368,7 +368,7 @@ namespace ClashN.ViewModels
{
return;
}
if (Utils.IsNullOrEmpty(item.url))
if (string.IsNullOrEmpty(item.url))
{
return;
}

View File

@@ -54,13 +54,13 @@ namespace ClashN.ViewModels
public ProxiesViewModel()
{
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_config = LazyConfig.Instance.GetConfig();
_config = LazyConfig.Instance.Config;
SelectedGroup = new();
SelectedDetail = new();
AutoRefresh = _config.uiItem.proxiesAutoRefresh;
EnableTun = _config.enableTun;
SortingSelected = _config.uiItem.proxiesSorting;
AutoRefresh = _config.UiItem.proxiesAutoRefresh;
EnableTun = _config.EnableTun;
SortingSelected = _config.UiItem.proxiesSorting;
//GetClashProxies(true);
this.WhenAnyValue(
@@ -70,17 +70,17 @@ namespace ClashN.ViewModels
this.WhenAnyValue(
x => x.SystemProxySelected,
y => y != null && y >= 0)
y => y >= 0)
.Subscribe(c => DoSystemProxySelected(c));
this.WhenAnyValue(
x => x.RuleModeSelected,
y => y != null && y >= 0)
y => y >= 0)
.Subscribe(c => DoRulemodeSelected(c));
this.WhenAnyValue(
x => x.SortingSelected,
y => y != null && y >= 0)
y => y >= 0)
.Subscribe(c => DoSortingSelected(c));
this.WhenAnyValue(
@@ -91,7 +91,7 @@ namespace ClashN.ViewModels
this.WhenAnyValue(
x => x.AutoRefresh,
y => y == true)
.Subscribe(c => { _config.uiItem.proxiesAutoRefresh = AutoRefresh; });
.Subscribe(c => { _config.UiItem.proxiesAutoRefresh = AutoRefresh; });
ProxiesReloadCmd = ReactiveCommand.Create(() =>
{
@@ -123,11 +123,11 @@ namespace ClashN.ViewModels
{
return;
}
if (_config.sysProxyType == (ESysProxyType)SystemProxySelected)
if (_config.SysProxyType == (SysProxyType)SystemProxySelected)
{
return;
}
Locator.Current.GetService<MainWindowViewModel>()?.SetListenerType((ESysProxyType)SystemProxySelected);
Locator.Current.GetService<MainWindowViewModel>()?.SetListenerType((SysProxyType)SystemProxySelected);
}
void DoRulemodeSelected(bool c)
{
@@ -148,9 +148,9 @@ namespace ClashN.ViewModels
{
return;
}
if (SortingSelected != _config.uiItem.proxiesSorting)
if (SortingSelected != _config.UiItem.proxiesSorting)
{
_config.uiItem.proxiesSorting = SortingSelected;
_config.UiItem.proxiesSorting = SortingSelected;
}
RefreshProxyDetails(c);
@@ -186,7 +186,7 @@ namespace ClashN.ViewModels
}
public void ReloadSystemProxySelected()
{
SystemProxySelected = (int)_config.sysProxyType;
SystemProxySelected = (int)_config.SysProxyType;
}
public void ReloadRulemodeSelected()
{
@@ -195,9 +195,9 @@ namespace ClashN.ViewModels
void DoEnableTun(bool c)
{
if (_config.enableTun != EnableTun)
if (_config.EnableTun != EnableTun)
{
_config.enableTun = EnableTun;
_config.EnableTun = EnableTun;
TunModeSwitch();
}
}
@@ -242,7 +242,7 @@ namespace ClashN.ViewModels
{
foreach (var it in proxyGroups)
{
if (Utils.IsNullOrEmpty(it.name) || !proxies.ContainsKey(it.name))
if (string.IsNullOrEmpty(it.name) || !proxies.ContainsKey(it.name))
{
continue;
}
@@ -298,7 +298,7 @@ namespace ClashN.ViewModels
return;
}
var name = SelectedGroup?.name;
if (Utils.IsNullOrEmpty(name))
if (string.IsNullOrEmpty(name))
{
return;
}
@@ -388,12 +388,12 @@ namespace ClashN.ViewModels
return;
}
var name = SelectedGroup.name;
if (Utils.IsNullOrEmpty(name))
if (string.IsNullOrEmpty(name))
{
return;
}
var nameNode = SelectedDetail.name;
if (Utils.IsNullOrEmpty(nameNode))
if (string.IsNullOrEmpty(nameNode))
{
return;
}
@@ -437,7 +437,7 @@ namespace ClashN.ViewModels
GetClashProxies(true);
return;
}
if (Utils.IsNullOrEmpty(result))
if (string.IsNullOrEmpty(result))
{
return;
}
@@ -485,9 +485,9 @@ namespace ClashN.ViewModels
}
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();
autoDelayTestTime = dtNow;

View File

@@ -93,31 +93,31 @@ namespace ClashN.ViewModels
public SettingsViewModel()
{
_config = LazyConfig.Instance.GetConfig();
_config = LazyConfig.Instance.Config;
//Core
MixedPort = _config.mixedPort;
SocksPort = _config.socksPort;
HttpPort = _config.httpPort;
APIPort = _config.APIPort;
AllowLANConn = _config.allowLANConn;
EnableIpv6 = _config.enableIpv6;
LogLevel = _config.logLevel;
EnableMixinContent = _config.enableMixinContent;
MixedPort = _config.MixedPort;
SocksPort = _config.SocksPort;
HttpPort = _config.HttpPort;
APIPort = _config.ApiPort;
AllowLANConn = _config.AllowLANConn;
EnableIpv6 = _config.EnableIpv6;
LogLevel = _config.LogLevel;
EnableMixinContent = _config.EnableMixinContent;
EditMixinContentCmd = ReactiveCommand.Create(() =>
{
EditMixinContent();
}, this.IsValid());
//clashN
AutoRun = _config.autoRun;
EnableStatistics = _config.enableStatistics;
EnableSecurityProtocolTls13 = _config.enableSecurityProtocolTls13;
autoUpdateSubInterval = _config.autoUpdateSubInterval;
autoDelayTestInterval = _config.autoDelayTestInterval;
SubConvertUrl = _config.constItem.subConvertUrl;
currentFontFamily = _config.uiItem.currentFontFamily;
AutoHideStartup = _config.autoHideStartup;
AutoRun = _config.AutoRun;
EnableStatistics = _config.EnableStatistics;
EnableSecurityProtocolTls13 = _config.EnableSecurityProtocolTls13;
autoUpdateSubInterval = _config.AutoUpdateSubInterval;
autoDelayTestInterval = _config.AutoDelayTestInterval;
SubConvertUrl = _config.ConstItem.subConvertUrl;
currentFontFamily = _config.UiItem.currentFontFamily;
AutoHideStartup = _config.AutoHideStartup;
SetLoopbackCmd = ReactiveCommand.Create(() =>
{
@@ -134,30 +134,30 @@ namespace ClashN.ViewModels
}, this.IsValid());
//System proxy
systemProxyExceptions = _config.systemProxyExceptions;
systemProxyAdvancedProtocol = _config.systemProxyAdvancedProtocol;
systemProxyExceptions = _config.SystemProxyExceptions;
systemProxyAdvancedProtocol = _config.SystemProxyAdvancedProtocol;
PacPort = _config.PacPort;
//UI
ColorModeDark = _config.uiItem.colorModeDark;
ColorModeDark = _config.UiItem.colorModeDark;
_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]);
CurrentFontSize = _config.uiItem.currentFontSize;
CurrentFontSize = _config.UiItem.currentFontSize;
this.WhenAnyValue(
x => x.ColorModeDark,
y => y == true)
.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);
ConfigHandler.SaveConfig(ref _config);
ConfigProc.SaveConfig(_config);
}
});
@@ -173,11 +173,11 @@ namespace ClashN.ViewModels
{
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);
ConfigHandler.SaveConfig(ref _config);
ConfigProc.SaveConfig(_config);
}
});
@@ -186,7 +186,7 @@ namespace ClashN.ViewModels
y => y != null && !y.IsNullOrEmpty())
.Subscribe(c =>
{
if (!Utils.IsNullOrEmpty(CurrentLanguage))
if (!string.IsNullOrEmpty(CurrentLanguage))
{
Utils.RegWriteValue(Global.MyRegPath, Global.MyRegKeyLanguage, CurrentLanguage);
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(CurrentLanguage);
@@ -198,11 +198,11 @@ namespace ClashN.ViewModels
y => y > 0)
.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);
ConfigHandler.SaveConfig(ref _config);
ConfigProc.SaveConfig(_config);
}
});
@@ -213,14 +213,14 @@ namespace ClashN.ViewModels
{
if (CurrentFontSize >= Global.MinFontSize)
{
_config.uiItem.currentFontSize = CurrentFontSize;
_config.UiItem.currentFontSize = CurrentFontSize;
double size = (long)CurrentFontSize;
Application.Current.Resources["StdFontSize1"] = size;
Application.Current.Resources["StdFontSize2"] = size + 1;
Application.Current.Resources["StdFontSize3"] = size + 2;
Application.Current.Resources["StdFontSize4"] = size + 3;
ConfigHandler.SaveConfig(ref _config);
ConfigProc.SaveConfig(_config);
}
});
@@ -235,32 +235,32 @@ namespace ClashN.ViewModels
void SaveConfig()
{
//Core
_config.mixedPort = MixedPort;
_config.socksPort = SocksPort;
_config.httpPort = HttpPort;
_config.APIPort = APIPort;
_config.allowLANConn = AllowLANConn;
_config.enableIpv6 = EnableIpv6;
_config.logLevel = LogLevel;
_config.enableMixinContent = EnableMixinContent;
_config.MixedPort = MixedPort;
_config.SocksPort = SocksPort;
_config.HttpPort = HttpPort;
_config.ApiPort = APIPort;
_config.AllowLANConn = AllowLANConn;
_config.EnableIpv6 = EnableIpv6;
_config.LogLevel = LogLevel;
_config.EnableMixinContent = EnableMixinContent;
//clashN
Utils.SetAutoRun(AutoRun);
_config.autoRun = AutoRun;
_config.enableStatistics = EnableStatistics;
_config.enableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
_config.autoUpdateSubInterval = autoUpdateSubInterval;
_config.autoDelayTestInterval = autoDelayTestInterval;
_config.constItem.subConvertUrl = SubConvertUrl;
_config.uiItem.currentFontFamily = currentFontFamily;
_config.autoHideStartup = AutoHideStartup;
_config.AutoRun = AutoRun;
_config.EnableStatistics = EnableStatistics;
_config.EnableSecurityProtocolTls13 = EnableSecurityProtocolTls13;
_config.AutoUpdateSubInterval = autoUpdateSubInterval;
_config.AutoDelayTestInterval = autoDelayTestInterval;
_config.ConstItem.subConvertUrl = SubConvertUrl;
_config.UiItem.currentFontFamily = currentFontFamily;
_config.AutoHideStartup = AutoHideStartup;
//System proxy
_config.systemProxyExceptions = systemProxyExceptions;
_config.systemProxyAdvancedProtocol = systemProxyAdvancedProtocol;
_config.SystemProxyExceptions = systemProxyExceptions;
_config.SystemProxyAdvancedProtocol = systemProxyAdvancedProtocol;
_config.PacPort = PacPort;
if (ConfigHandler.SaveConfig(ref _config) == 0)
if (ConfigProc.SaveConfig(_config) == 0)
{
Locator.Current.GetService<NoticeHandler>()?.Enqueue(ResUI.OperationSuccess);
Locator.Current.GetService<MainWindowViewModel>()?.LoadCore();
@@ -278,7 +278,7 @@ namespace ClashN.ViewModels
if (!File.Exists(address))
{
string contents = Utils.GetEmbedText(Global.SampleMixin);
if (!Utils.IsNullOrEmpty(contents))
if (!string.IsNullOrEmpty(contents))
{
File.WriteAllText(address, contents);
}

View File

@@ -14,28 +14,23 @@ namespace ClashN.Views
public partial class GlobalHotkeySettingWindow
{
private static Config _config;
List<KeyEventItem> lstKey;
List<KeyShortcut> lstKey;
public GlobalHotkeySettingWindow()
{
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>();
}
foreach (EGlobalHotkey it in Enum.GetValues(typeof(EGlobalHotkey)))
{
if (_config.globalHotkeys.FindIndex(t => t.eGlobalHotkey == it) >= 0)
if (_config.globalHotkeys.FindIndex(t => t.GlobalHotkey == it) >= 0)
{
continue;
}
_config.globalHotkeys.Add(new KeyEventItem()
_config.globalHotkeys.Add(new KeyShortcut()
{
eGlobalHotkey = it,
GlobalHotkey = it,
Alt = false,
Control = false,
Shift = false,
@@ -53,7 +48,7 @@ namespace ClashN.Views
BindingData(-1);
Utils.SetDarkBorder(this, _config.uiItem.colorModeDark);
Utils.SetDarkBorder(this, _config.UiItem.colorModeDark);
}
@@ -66,10 +61,13 @@ namespace ClashN.Views
return;
var formsKey = (Forms.Keys)KeyInterop.VirtualKeyFromKey(e.Key);
lstKey[index].KeyCode = formsKey;
lstKey[index].Alt = Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt);
lstKey[index].Control = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);
lstKey[index].Shift = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
lstKey[index] = new KeyShortcut()
{
KeyCode = formsKey,
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);
}
@@ -108,9 +106,10 @@ namespace ClashN.Views
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();
}
@@ -128,16 +127,16 @@ namespace ClashN.Views
private void btnReset_Click(object sender, RoutedEventArgs e)
{
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;
}
lstKey.Add(new KeyEventItem()
lstKey.Add(new KeyShortcut()
{
eGlobalHotkey = it,
GlobalHotkey = it,
Alt = false,
Control = false,
Shift = false,

View File

@@ -41,7 +41,7 @@ namespace ClashN.Views
return;
}
string? msgFilter = ViewModel?.MsgFilter;
if (!Utils.IsNullOrEmpty(msgFilter))
if (!string.IsNullOrEmpty(msgFilter))
{
if (!Regex.IsMatch(msg, msgFilter))
{

View File

@@ -22,7 +22,7 @@ namespace ClashN.Views
public void AppendText(string msg)
{
//if (!Utils.IsNullOrEmpty(MsgFilter))
//if (!string.IsNullOrEmpty(MsgFilter))
//{
// if (!Regex.IsMatch(text, MsgFilter))
// {

View File

@@ -19,7 +19,7 @@ namespace ClashN.Views
public SettingsView()
{
InitializeComponent();
_config = LazyConfig.Instance.GetConfig();
_config = LazyConfig.Instance.Config;
ViewModel = new SettingsViewModel();
Global.SubConvertUrls.ForEach(it =>
@@ -66,10 +66,10 @@ namespace ClashN.Views
// continue;
//}
var fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture)];
if (Utils.IsNullOrEmpty(fontFamily))
if (string.IsNullOrEmpty(fontFamily))
{
fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture2)];
if (Utils.IsNullOrEmpty(fontFamily))
if (string.IsNullOrEmpty(fontFamily))
{
continue;
}