C# language usage improvements

This commit is contained in:
Edi Wang 2022-12-04 13:39:19 +08:00
parent cdf35740d9
commit 140fab948d
35 changed files with 457 additions and 732 deletions

View file

@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Threading; using System.Threading;
@ -58,7 +57,7 @@ namespace v2rayN.Base
HttpResponseMessage response = await client.GetAsync(url, token); HttpResponseMessage response = await client.GetAsync(url, 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($"The request returned with HTTP status code {response.StatusCode}");
} }
return await response.Content.ReadAsStringAsync(); return await response.Content.ReadAsStringAsync();
} }
@ -77,11 +76,11 @@ namespace v2rayN.Base
{ {
if (string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(url))
{ {
throw new ArgumentNullException("url"); throw new ArgumentNullException(nameof(url));
} }
if (string.IsNullOrEmpty(fileName)) if (string.IsNullOrEmpty(fileName))
{ {
throw new ArgumentNullException("fileName"); throw new ArgumentNullException(nameof(fileName));
} }
if (File.Exists(fileName)) if (File.Exists(fileName))
{ {
@ -92,59 +91,55 @@ namespace v2rayN.Base
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
throw new Exception(string.Format("The request returned with HTTP status code {0}", response.StatusCode)); throw new Exception($"The request returned with HTTP status code {response.StatusCode}");
} }
var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L; var total = response.Content.Headers.ContentLength ?? -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;
var progressPercentage = 0;
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
var progressPercentage = 0; {
var data = new byte[read];
buffer.ToList().CopyTo(0, data, 0, read);
do // TODO: put here the code to write the file to disk
{ await file.WriteAsync(data, 0, read, token);
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);
file.Close();
if (canReportProgress)
{
progress.Report(101);
} }
} }
@ -152,68 +147,66 @@ namespace v2rayN.Base
{ {
if (string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(url))
{ {
throw new ArgumentNullException("url"); throw new ArgumentNullException(nameof(url));
} }
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token); var 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($"The request returned with HTTP status code {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();
var totalRead = 0L;
var buffer = new byte[1024 * 64];
var isMoreToRead = true;
string progressSpeed = string.Empty;
DateTime totalDatetime = DateTime.Now;
do
{ {
var totalRead = 0L; if (token.IsCancellationRequested)
var buffer = new byte[1024 * 64];
var isMoreToRead = true;
string progressSpeed = string.Empty;
DateTime totalDatetime = DateTime.Now;
do
{ {
if (token.IsCancellationRequested) if (totalRead > 0)
{ {
if (totalRead > 0) return;
{
return;
}
else
{
token.ThrowIfCancellationRequested();
}
}
var read = await stream.ReadAsync(buffer, 0, buffer.Length, token);
if (read == 0)
{
isMoreToRead = false;
} }
else else
{ {
var data = new byte[read]; token.ThrowIfCancellationRequested();
buffer.ToList().CopyTo(0, data, 0, read); }
}
// TODO: var read = await stream.ReadAsync(buffer, 0, buffer.Length, token);
totalRead += read;
TimeSpan ts = (DateTime.Now - totalDatetime); if (read == 0)
var speed = (totalRead * 1d / ts.TotalMilliseconds / 1000).ToString("#0.0"); {
if (progress != null) isMoreToRead = false;
}
else
{
var data = new byte[read];
buffer.ToList().CopyTo(0, data, 0, read);
// TODO:
totalRead += read;
TimeSpan ts = (DateTime.Now - totalDatetime);
var speed = (totalRead * 1d / ts.TotalMilliseconds / 1000).ToString("#0.0");
if (progress != null)
{
if (progressSpeed != speed)
{ {
if (progressSpeed != speed) progressSpeed = speed;
{ progress.Report(speed);
progressSpeed = speed;
progress.Report(speed);
}
} }
} }
} while (isMoreToRead); }
} } while (isMoreToRead);
} }
} }

View file

@ -76,14 +76,7 @@ namespace v2rayN.Base
Rectangle itemBounds = GetItemRect(targetIndex); Rectangle itemBounds = GetItemRect(targetIndex);
EnsureVisible(targetIndex); EnsureVisible(targetIndex);
if (targetPoint.Y > itemBounds.Top + (itemBounds.Height / 2)) InsertionMark.AppearsAfterItem = targetPoint.Y > itemBounds.Top + (itemBounds.Height / 2);
{
InsertionMark.AppearsAfterItem = true;
}
else
{
InsertionMark.AppearsAfterItem = false;
}
} }
InsertionMark.Index = targetIndex; InsertionMark.Index = targetIndex;
} }

View file

@ -36,8 +36,7 @@ namespace v2rayN.Base
public static IEnumerable<string> NonWhiteSpaceLines(this TextReader reader) public static IEnumerable<string> NonWhiteSpaceLines(this TextReader reader)
{ {
string line; while (reader.ReadLine() is { } line)
while ((line = reader.ReadLine()) != null)
{ {
if (line.IsWhiteSpace()) continue; if (line.IsWhiteSpace()) continue;
yield return line; yield return line;

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Mode; using v2rayN.Mode;

View file

@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Windows.Forms; using System.Windows.Forms;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Mode; using v2rayN.Mode;

View file

@ -1,6 +1,4 @@
using System; using v2rayN.Mode;
using System.Windows.Forms;
using v2rayN.Mode;
namespace v2rayN.Forms namespace v2rayN.Forms
{ {

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Forms; using System.Windows.Forms;
using v2rayN.Base;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Mode; using v2rayN.Mode;
using v2rayN.Resx; using v2rayN.Resx;
@ -18,10 +17,7 @@ namespace v2rayN.Forms
private void GlobalHotkeySettingForm_Load(object sender, EventArgs e) private void GlobalHotkeySettingForm_Load(object sender, EventArgs e)
{ {
if (config.globalHotkeys == null) config.globalHotkeys ??= new List<KeyEventItem>();
{
config.globalHotkeys = new List<KeyEventItem>();
}
foreach (EGlobalHotkey it in Enum.GetValues(typeof(EGlobalHotkey))) foreach (EGlobalHotkey it in Enum.GetValues(typeof(EGlobalHotkey)))
{ {

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Windows.Forms; using System.Windows.Forms;
using v2rayN.Base; using v2rayN.Base;
using v2rayN.Handler;
using v2rayN.Mode; using v2rayN.Mode;
namespace v2rayN.Forms namespace v2rayN.Forms

View file

@ -18,10 +18,7 @@ namespace v2rayN.Forms
private void GroupSettingForm_Load(object sender, EventArgs e) private void GroupSettingForm_Load(object sender, EventArgs e)
{ {
if (config.groupItem == null) config.groupItem ??= new List<GroupItem>();
{
config.groupItem = new List<GroupItem>();
}
RefreshGroupsView(); RefreshGroupsView();
} }

View file

@ -63,14 +63,7 @@ namespace v2rayN.Forms
private void MainForm_VisibleChanged(object sender, EventArgs e) private void MainForm_VisibleChanged(object sender, EventArgs e)
{ {
if (statistics == null || !statistics.Enable) return; if (statistics == null || !statistics.Enable) return;
if ((sender as Form).Visible) statistics.UpdateUI = (sender as Form).Visible;
{
statistics.UpdateUI = true;
}
else
{
statistics.UpdateUI = false;
}
} }
private void MainForm_Shown(object sender, EventArgs e) private void MainForm_Shown(object sender, EventArgs e)
@ -232,10 +225,7 @@ namespace v2rayN.Forms
.ToList(); .ToList();
ConfigHandler.SetDefaultServer(config, lstVmess); ConfigHandler.SetDefaultServer(config, lstVmess);
BeginInvoke(new Action(() => BeginInvoke(new Action(RefreshServersView));
{
RefreshServersView();
}));
RefreshServersMenu(); RefreshServersMenu();
} }
@ -319,7 +309,7 @@ namespace v2rayN.Forms
Utils.AddSubItem(lvItem, EServerColName.subRemarks.ToString(), item.GetSubRemarks(config)); Utils.AddSubItem(lvItem, EServerColName.subRemarks.ToString(), item.GetSubRemarks(config));
Utils.AddSubItem(lvItem, EServerColName.testResult.ToString(), item.testResult); Utils.AddSubItem(lvItem, EServerColName.testResult.ToString(), item.testResult);
if (statistics != null && statistics.Enable) if (statistics is { Enable: true })
{ {
string totalUp = string.Empty, string totalUp = string.Empty,
totalDown = string.Empty, totalDown = string.Empty,
@ -1048,10 +1038,7 @@ namespace v2rayN.Forms
{ {
HideForm(); HideForm();
string result = await Task.Run(() => string result = await Task.Run(Utils.ScanScreen);
{
return Utils.ScanScreen();
});
ShowForm(); ShowForm();
@ -1234,7 +1221,7 @@ namespace v2rayN.Forms
{ {
up /= (ulong)(config.statisticsFreshRate); up /= (ulong)(config.statisticsFreshRate);
down /= (ulong)(config.statisticsFreshRate); down /= (ulong)(config.statisticsFreshRate);
mainMsgControl.SetToolSslInfo("speed", string.Format("{0}/s↑ | {1}/s↓", Utils.HumanFy(up), Utils.HumanFy(down))); mainMsgControl.SetToolSslInfo("speed", $"{Utils.HumanFy(up)}/s↑ | {Utils.HumanFy(down)}/s↓");
foreach (var it in statistics) foreach (var it in statistics)
{ {
@ -1560,7 +1547,7 @@ namespace v2rayN.Forms
for (int k = 0; k < config.routings.Count; k++) for (int k = 0; k < config.routings.Count; k++)
{ {
var item = config.routings[k]; var item = config.routings[k];
if (item.locked == true) if (item.locked)
{ {
continue; continue;
} }

View file

@ -1,12 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using v2rayN.Base; using v2rayN.Base;
using v2rayN.Mode; using v2rayN.Mode;
@ -89,14 +83,9 @@ namespace v2rayN.Forms
sb.Append($"{ResUI.LabLocal}:"); sb.Append($"{ResUI.LabLocal}:");
sb.Append($"[{Global.InboundSocks}:{config.GetLocalPort(Global.InboundSocks)}]"); sb.Append($"[{Global.InboundSocks}:{config.GetLocalPort(Global.InboundSocks)}]");
sb.Append(" | "); sb.Append(" | ");
if (config.sysProxyType == ESysProxyType.ForcedChange) sb.Append(config.sysProxyType == ESysProxyType.ForcedChange
{ ? $"[{Global.InboundHttp}({ResUI.SystemProxy}):{config.GetLocalPort(Global.InboundHttp)}]"
sb.Append($"[{Global.InboundHttp}({ResUI.SystemProxy}):{config.GetLocalPort(Global.InboundHttp)}]"); : $"[{Global.InboundHttp}:{config.GetLocalPort(Global.InboundHttp)}]");
}
else
{
sb.Append($"[{Global.InboundHttp}:{config.GetLocalPort(Global.InboundHttp)}]");
}
if (config.inbound[0].allowLANConn) if (config.inbound[0].allowLANConn)
{ {

View file

@ -1,11 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
namespace v2rayN.Forms namespace v2rayN.Forms

View file

@ -106,10 +106,7 @@ namespace v2rayN.Forms
private void InitCoreType() private void InitCoreType()
{ {
if (config.coreTypeItem == null) config.coreTypeItem ??= new List<CoreTypeItem>();
{
config.coreTypeItem = new List<CoreTypeItem>();
}
foreach (EConfigType it in Enum.GetValues(typeof(EConfigType))) foreach (EConfigType it in Enum.GetValues(typeof(EConfigType)))
{ {

View file

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Windows.Forms; using System.Windows.Forms;
using v2rayN.Base; using v2rayN.Base;
using v2rayN.Handler;
using v2rayN.Mode; using v2rayN.Mode;
using v2rayN.Resx; using v2rayN.Resx;
@ -118,12 +117,9 @@ namespace v2rayN.Forms
EndBindingData(); EndBindingData();
bool hasRule = bool hasRule =
rulesItem.domain != null rulesItem.domain is { Count: > 0 }
&& rulesItem.domain.Count > 0 || rulesItem.ip is { Count: > 0 }
|| rulesItem.ip != null || rulesItem.protocol is { Count: > 0 }
&& rulesItem.ip.Count > 0
|| rulesItem.protocol != null
&& rulesItem.protocol.Count > 0
|| !Utils.IsNullOrEmpty(rulesItem.port); || !Utils.IsNullOrEmpty(rulesItem.port);
if (!hasRule) if (!hasRule)

View file

@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using v2rayN.Base;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.Mode; using v2rayN.Mode;
using v2rayN.Resx; using v2rayN.Resx;
@ -26,10 +25,7 @@ namespace v2rayN.Forms
private void RoutingRuleSettingForm_Load(object sender, EventArgs e) private void RoutingRuleSettingForm_Load(object sender, EventArgs e)
{ {
routingItem = EditIndex >= 0 ? config.routings[EditIndex] : new RoutingItem(); routingItem = EditIndex >= 0 ? config.routings[EditIndex] : new RoutingItem();
if (routingItem.rules == null) routingItem.rules ??= new List<RulesItem>();
{
routingItem.rules = new List<RulesItem>();
}
txtRemarks.Text = routingItem.remarks ?? string.Empty; txtRemarks.Text = routingItem.remarks ?? string.Empty;
txtUrl.Text = routingItem.url ?? string.Empty; txtUrl.Text = routingItem.url ?? string.Empty;
@ -351,11 +347,7 @@ namespace v2rayN.Forms
} }
private int AddBatchRoutingRules(ref RoutingItem routingItem, string clipboardData) private int AddBatchRoutingRules(ref RoutingItem routingItem, string clipboardData)
{ {
bool blReplace = false; bool blReplace = UI.ShowYesNo(ResUI.AddBatchRoutingRulesYesNo) == DialogResult.No;
if (UI.ShowYesNo(ResUI.AddBatchRoutingRulesYesNo) == DialogResult.No)
{
blReplace = true;
}
return ConfigHandler.AddBatchRoutingRules(ref routingItem, clipboardData, blReplace); return ConfigHandler.AddBatchRoutingRules(ref routingItem, clipboardData, blReplace);
} }

View file

@ -26,10 +26,7 @@ namespace v2rayN.Forms
chkenableRoutingAdvanced.Checked = config.enableRoutingAdvanced; chkenableRoutingAdvanced.Checked = config.enableRoutingAdvanced;
cmbdomainMatcher.Text = config.domainMatcher; cmbdomainMatcher.Text = config.domainMatcher;
if (config.routings == null) config.routings ??= new List<RoutingItem>();
{
config.routings = new List<RoutingItem>();
}
InitRoutingsView(); InitRoutingsView();
RefreshRoutingsView(); RefreshRoutingsView();
@ -162,7 +159,7 @@ namespace v2rayN.Forms
for (int k = 0; k < config.routings.Count; k++) for (int k = 0; k < config.routings.Count; k++)
{ {
var item = config.routings[k]; var item = config.routings[k];
if (item.locked == true) if (item.locked)
{ {
continue; continue;
} }

View file

@ -62,14 +62,7 @@ namespace v2rayN.Forms
subItem.userAgent = txtUserAgent.Text.TrimEx(); subItem.userAgent = txtUserAgent.Text.TrimEx();
var index = groupItem.FindIndex(t => t.remarks == cmbGroup.Text); var index = groupItem.FindIndex(t => t.remarks == cmbGroup.Text);
if (index >= 0) subItem.groupId = index >= 0 ? groupItem[index].id : string.Empty;
{
subItem.groupId = groupItem[index].id;
}
else
{
subItem.groupId = string.Empty;
}
} }
} }
private void txtRemarks_Leave(object sender, EventArgs e) private void txtRemarks_Leave(object sender, EventArgs e)

View file

@ -18,10 +18,7 @@ namespace v2rayN.Forms
private void SubSettingForm_Load(object sender, EventArgs e) private void SubSettingForm_Load(object sender, EventArgs e)
{ {
if (config.subItem == null) config.subItem ??= new List<SubItem>();
{
config.subItem = new List<SubItem>();
}
RefreshSubsView(); RefreshSubsView();
} }

View file

@ -1,12 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net;
using v2rayN.Mode; using v2rayN.Mode;
using v2rayN.Base; using v2rayN.Base;
using System.Linq; using System.Linq;
using v2rayN.Tool; using v2rayN.Tool;
using System.Threading.Tasks;
namespace v2rayN.Handler namespace v2rayN.Handler
{ {
@ -101,36 +99,22 @@ namespace v2rayN.Handler
//} //}
//kcp //kcp
if (config.kcpItem == null) config.kcpItem ??= new KcpItem
{ {
config.kcpItem = new KcpItem mtu = 1350,
{ tti = 50,
mtu = 1350, uplinkCapacity = 12,
tti = 50, downlinkCapacity = 100,
uplinkCapacity = 12, readBufferSize = 2,
downlinkCapacity = 100, writeBufferSize = 2,
readBufferSize = 2, congestion = false
writeBufferSize = 2, };
congestion = false config.uiItem ??= new UIItem()
};
}
if (config.uiItem == null)
{ {
config.uiItem = new UIItem() enableAutoAdjustMainLvColWidth = true
{ };
enableAutoAdjustMainLvColWidth = true config.uiItem.mainLvColWidth ??= new Dictionary<string, int>();
}; config.constItem ??= new ConstItem();
}
if (config.uiItem.mainLvColWidth == null)
{
config.uiItem.mainLvColWidth = new Dictionary<string, int>();
}
if (config.constItem == null)
{
config.constItem = new ConstItem();
}
if (Utils.IsNullOrEmpty(config.constItem.speedTestUrl)) if (Utils.IsNullOrEmpty(config.constItem.speedTestUrl))
{ {
config.constItem.speedTestUrl = Global.SpeedTestUrl; config.constItem.speedTestUrl = Global.SpeedTestUrl;
@ -148,15 +132,9 @@ namespace v2rayN.Handler
// config.remoteDNS = "1.1.1.1"; // config.remoteDNS = "1.1.1.1";
//} //}
if (config.subItem == null) config.subItem ??= new List<SubItem>();
{ config.groupItem ??= new List<GroupItem>();
config.subItem = new List<SubItem>(); if (config.statisticsFreshRate is > 100 or < 1)
}
if (config.groupItem == null)
{
config.groupItem = new List<GroupItem>();
}
if (config.statisticsFreshRate > 100 || config.statisticsFreshRate < 1)
{ {
config.statisticsFreshRate = 1; config.statisticsFreshRate = 1;
} }
@ -1260,10 +1238,7 @@ namespace v2rayN.Handler
public static int AddformMainLvColWidth(ref Config config, string name, int width) public static int AddformMainLvColWidth(ref Config config, string name, int width)
{ {
if (config.uiItem.mainLvColWidth == null) config.uiItem.mainLvColWidth ??= new Dictionary<string, int>();
{
config.uiItem.mainLvColWidth = new Dictionary<string, int>();
}
if (config.uiItem.mainLvColWidth.ContainsKey(name)) if (config.uiItem.mainLvColWidth.ContainsKey(name))
{ {
config.uiItem.mainLvColWidth[name] = width; config.uiItem.mainLvColWidth[name] = width;
@ -1278,18 +1253,8 @@ namespace v2rayN.Handler
} }
public static int GetformMainLvColWidth(ref Config config, string name, int width) public static int GetformMainLvColWidth(ref Config config, string name, int width)
{ {
if (config.uiItem.mainLvColWidth == null) config.uiItem.mainLvColWidth ??= new Dictionary<string, int>();
{ return config.uiItem.mainLvColWidth.ContainsKey(name) ? config.uiItem.mainLvColWidth[name] : width;
config.uiItem.mainLvColWidth = new Dictionary<string, int>();
}
if (config.uiItem.mainLvColWidth.ContainsKey(name))
{
return config.uiItem.mainLvColWidth[name];
}
else
{
return width;
}
} }
#endregion #endregion
@ -1308,7 +1273,7 @@ namespace v2rayN.Handler
} }
//move locked item //move locked item
int index = config.routings.FindIndex(it => it.locked == true); int index = config.routings.FindIndex(it => it.locked);
if (index != -1) if (index != -1)
{ {
var item = Utils.DeepCopy(config.routings[index]); var item = Utils.DeepCopy(config.routings[index]);
@ -1339,7 +1304,7 @@ namespace v2rayN.Handler
else else
{ {
config.routings.Add(item); config.routings.Add(item);
int indexLocked = config.routings.FindIndex(it => it.locked == true); int indexLocked = config.routings.FindIndex(it => it.locked);
if (indexLocked != -1) if (indexLocked != -1)
{ {
var itemLocked = Utils.DeepCopy(config.routings[indexLocked]); var itemLocked = Utils.DeepCopy(config.routings[indexLocked]);
@ -1370,10 +1335,7 @@ namespace v2rayN.Handler
{ {
return -1; return -1;
} }
if (routingItem.rules == null) routingItem.rules ??= new List<RulesItem>();
{
routingItem.rules = new List<RulesItem>();
}
if (blReplace) if (blReplace)
{ {
routingItem.rules.Clear(); routingItem.rules.Clear();
@ -1485,10 +1447,7 @@ namespace v2rayN.Handler
public static int InitBuiltinRouting(ref Config config, bool blImportAdvancedRules = false) public static int InitBuiltinRouting(ref Config config, bool blImportAdvancedRules = false)
{ {
if (config.routings == null) config.routings ??= new List<RoutingItem>();
{
config.routings = new List<RoutingItem>();
}
if (blImportAdvancedRules || config.routings.Count(it => it.locked != true) <= 0) if (blImportAdvancedRules || config.routings.Count(it => it.locked != true) <= 0)
{ {
@ -1543,11 +1502,7 @@ namespace v2rayN.Handler
public static RoutingItem GetLockedRoutingItem(ref Config config) public static RoutingItem GetLockedRoutingItem(ref Config config)
{ {
if (config.routings == null) return config.routings?.Find(it => it.locked);
{
return null;
}
return config.routings.Find(it => it.locked == true);
} }
#endregion #endregion
} }

View file

@ -5,7 +5,6 @@ using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using v2rayN.Base; using v2rayN.Base;

View file

@ -48,11 +48,7 @@ namespace v2rayN.Handler
return ECoreType.Xray; return ECoreType.Xray;
} }
var item = _config.coreTypeItem.FirstOrDefault(it => it.configType == eConfigType); var item = _config.coreTypeItem.FirstOrDefault(it => it.configType == eConfigType);
if (item == null) return item?.coreType ?? ECoreType.Xray;
{
return ECoreType.Xray;
}
return item.coreType;
} }
public CoreInfo GetCoreInfo(ECoreType coreType) public CoreInfo GetCoreInfo(ECoreType coreType)
@ -61,144 +57,135 @@ namespace v2rayN.Handler
{ {
InitCoreInfo(); InitCoreInfo();
} }
return coreInfos.Where(t => t.coreType == coreType).FirstOrDefault(); return coreInfos.FirstOrDefault(t => t.coreType == coreType);
} }
private void InitCoreInfo() private void InitCoreInfo()
{ {
coreInfos = new List<CoreInfo>(); coreInfos = new List<CoreInfo>
coreInfos.Add(new CoreInfo
{ {
coreType = ECoreType.v2rayN, new CoreInfo
coreUrl = Global.NUrl, {
coreReleaseApiUrl = Global.NUrl.Replace(@"https://github.com", @"https://api.github.com/repos"), coreType = ECoreType.v2rayN,
coreDownloadUrl32 = Global.NUrl + "/download/{0}/v2rayN.zip", coreUrl = Global.NUrl,
coreDownloadUrl64 = Global.NUrl + "/download/{0}/v2rayN.zip", coreReleaseApiUrl = Global.NUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
}); coreDownloadUrl32 = Global.NUrl + "/download/{0}/v2rayN.zip",
coreDownloadUrl64 = Global.NUrl + "/download/{0}/v2rayN.zip",
coreInfos.Add(new CoreInfo },
{ new CoreInfo
coreType = ECoreType.v2fly, {
coreExes = new List<string> { "wv2ray", "v2ray" }, coreType = ECoreType.v2fly,
arguments = "", coreExes = new List<string> { "wv2ray", "v2ray" },
coreUrl = Global.v2flyCoreUrl, arguments = "",
coreReleaseApiUrl = Global.v2flyCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"), coreUrl = Global.v2flyCoreUrl,
coreDownloadUrl32 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip", coreReleaseApiUrl = Global.v2flyCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
coreDownloadUrl64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip", coreDownloadUrl32 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
match = "V2Ray", coreDownloadUrl64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
versionArg = "-version", match = "V2Ray",
redirectInfo = true, versionArg = "-version",
}); redirectInfo = true,
},
coreInfos.Add(new CoreInfo new CoreInfo
{ {
coreType = ECoreType.SagerNet, coreType = ECoreType.SagerNet,
coreExes = new List<string> { "SagerNet", "v2ray" }, coreExes = new List<string> { "SagerNet", "v2ray" },
arguments = "run", arguments = "run",
coreUrl = Global.SagerNetCoreUrl, coreUrl = Global.SagerNetCoreUrl,
coreReleaseApiUrl = Global.SagerNetCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"), coreReleaseApiUrl = Global.SagerNetCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
coreDownloadUrl32 = Global.SagerNetCoreUrl + "/download/{0}/v2ray-windows-{1}.zip", coreDownloadUrl32 = Global.SagerNetCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrl64 = Global.SagerNetCoreUrl + "/download/{0}/v2ray-windows-{1}.zip", coreDownloadUrl64 = Global.SagerNetCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
match = "V2Ray", match = "V2Ray",
versionArg = "version", versionArg = "version",
redirectInfo = true, redirectInfo = true,
}); },
new CoreInfo
coreInfos.Add(new CoreInfo {
{ coreType = ECoreType.v2fly_v5,
coreType = ECoreType.v2fly_v5, coreExes = new List<string> { "v2ray" },
coreExes = new List<string> { "v2ray" }, arguments = "run",
arguments = "run", coreUrl = Global.v2flyCoreUrl,
coreUrl = Global.v2flyCoreUrl, coreReleaseApiUrl = Global.v2flyCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
coreReleaseApiUrl = Global.v2flyCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"), coreDownloadUrl32 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrl32 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip", coreDownloadUrl64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip",
coreDownloadUrl64 = Global.v2flyCoreUrl + "/download/{0}/v2ray-windows-{1}.zip", match = "V2Ray",
match = "V2Ray", versionArg = "version",
versionArg = "version", redirectInfo = true,
redirectInfo = true, },
}); new CoreInfo
{
coreInfos.Add(new CoreInfo coreType = ECoreType.Xray,
{ coreExes = new List<string> { "xray" },
coreType = ECoreType.Xray, arguments = "",
coreExes = new List<string> { "xray" }, coreUrl = Global.xrayCoreUrl,
arguments = "", coreReleaseApiUrl = Global.xrayCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
coreUrl = Global.xrayCoreUrl, coreDownloadUrl32 = Global.xrayCoreUrl + "/download/{0}/Xray-windows-{1}.zip",
coreReleaseApiUrl = Global.xrayCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"), coreDownloadUrl64 = Global.xrayCoreUrl + "/download/{0}/Xray-windows-{1}.zip",
coreDownloadUrl32 = Global.xrayCoreUrl + "/download/{0}/Xray-windows-{1}.zip", match = "Xray",
coreDownloadUrl64 = Global.xrayCoreUrl + "/download/{0}/Xray-windows-{1}.zip", versionArg = "-version",
match = "Xray", redirectInfo = true,
versionArg = "-version", },
redirectInfo = true, new CoreInfo
}); {
coreType = ECoreType.clash,
coreInfos.Add(new CoreInfo coreExes = new List<string> { "clash-windows-amd64-v3", "clash-windows-amd64", "clash-windows-386", "clash" },
{ arguments = "-f config.json",
coreType = ECoreType.clash, coreUrl = Global.clashCoreUrl,
coreExes = new List<string> { "clash-windows-amd64-v3", "clash-windows-amd64", "clash-windows-386", "clash" }, coreReleaseApiUrl = Global.clashCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
arguments = "-f config.json", coreDownloadUrl32 = Global.clashCoreUrl + "/download/{0}/clash-windows-386-{0}.zip",
coreUrl = Global.clashCoreUrl, coreDownloadUrl64 = Global.clashCoreUrl + "/download/{0}/clash-windows-amd64-{0}.zip",
coreReleaseApiUrl = Global.clashCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"), match = "v",
coreDownloadUrl32 = Global.clashCoreUrl + "/download/{0}/clash-windows-386-{0}.zip", versionArg = "-v",
coreDownloadUrl64 = Global.clashCoreUrl + "/download/{0}/clash-windows-amd64-{0}.zip", redirectInfo = true,
match = "v", },
versionArg = "-v", new CoreInfo
redirectInfo = true, {
}); coreType = ECoreType.clash_meta,
coreExes = new List<string> { "Clash.Meta-windows-amd64-compatible", "Clash.Meta-windows-amd64", "Clash.Meta-windows-386", "Clash.Meta", "clash" },
coreInfos.Add(new CoreInfo arguments = "-f config.json",
{ coreUrl = Global.clashMetaCoreUrl,
coreType = ECoreType.clash_meta, coreReleaseApiUrl = Global.clashMetaCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
coreExes = new List<string> { "Clash.Meta-windows-amd64-compatible", "Clash.Meta-windows-amd64", "Clash.Meta-windows-386", "Clash.Meta", "clash" }, coreDownloadUrl32 = Global.clashMetaCoreUrl + "/download/{0}/Clash.Meta-windows-386-{0}.zip",
arguments = "-f config.json", coreDownloadUrl64 = Global.clashMetaCoreUrl + "/download/{0}/Clash.Meta-windows-amd64-compatible-{0}.zip",
coreUrl = Global.clashMetaCoreUrl, match = "v",
coreReleaseApiUrl = Global.clashMetaCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"), versionArg = "-v",
coreDownloadUrl32 = Global.clashMetaCoreUrl + "/download/{0}/Clash.Meta-windows-386-{0}.zip", redirectInfo = true,
coreDownloadUrl64 = Global.clashMetaCoreUrl + "/download/{0}/Clash.Meta-windows-amd64-compatible-{0}.zip", },
match = "v", new CoreInfo
versionArg = "-v", {
redirectInfo = true, coreType = ECoreType.hysteria,
}); coreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" },
arguments = "",
coreInfos.Add(new CoreInfo coreUrl = Global.hysteriaCoreUrl,
{ coreReleaseApiUrl = Global.hysteriaCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"),
coreType = ECoreType.hysteria, coreDownloadUrl32 = Global.hysteriaCoreUrl + "/download/{0}/hysteria-windows-386.exe",
coreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" }, coreDownloadUrl64 = Global.hysteriaCoreUrl + "/download/{0}/hysteria-windows-amd64.exe",
arguments = "", redirectInfo = true,
coreUrl = Global.hysteriaCoreUrl, },
coreReleaseApiUrl = Global.hysteriaCoreUrl.Replace(@"https://github.com", @"https://api.github.com/repos"), new CoreInfo
coreDownloadUrl32 = Global.hysteriaCoreUrl + "/download/{0}/hysteria-windows-386.exe", {
coreDownloadUrl64 = Global.hysteriaCoreUrl + "/download/{0}/hysteria-windows-amd64.exe", coreType = ECoreType.naiveproxy,
redirectInfo = true, coreExes = new List<string> { "naiveproxy", "naive" },
}); arguments = "config.json",
coreUrl = Global.naiveproxyCoreUrl,
coreInfos.Add(new CoreInfo redirectInfo = false,
{ },
coreType = ECoreType.naiveproxy, new CoreInfo
coreExes = new List<string> { "naiveproxy", "naive" }, {
arguments = "config.json", coreType = ECoreType.tuic,
coreUrl = Global.naiveproxyCoreUrl, coreExes = new List<string> { "tuic-client", "tuic" },
redirectInfo = false, arguments = "-c config.json",
}); coreUrl = Global.tuicCoreUrl,
redirectInfo = true,
coreInfos.Add(new CoreInfo },
{ new CoreInfo
coreType = ECoreType.tuic, {
coreExes = new List<string> { "tuic-client", "tuic" }, coreType = ECoreType.sing_box,
arguments = "-c config.json", coreExes = new List<string> { "sing-box-client", "sing-box" },
coreUrl = Global.tuicCoreUrl, arguments = "run",
redirectInfo = true, coreUrl = Global.singboxCoreUrl,
}); redirectInfo = true,
}
coreInfos.Add(new CoreInfo };
{
coreType = ECoreType.sing_box,
coreExes = new List<string> { "sing-box-client", "sing-box" },
arguments = "run",
coreUrl = Global.singboxCoreUrl,
redirectInfo = true,
});
} }
} }

View file

@ -1,14 +1,12 @@
using NHotkey; using NHotkey;
using NHotkey.WindowsForms; using NHotkey.WindowsForms;
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using v2rayN.Mode; using v2rayN.Mode;
using System.Linq;
using v2rayN.Resx; using v2rayN.Resx;
namespace v2rayN.Handler namespace v2rayN.Handler

View file

@ -2,10 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq; using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web; using System.Web;
using v2rayN.Base; using v2rayN.Base;
using v2rayN.Mode; using v2rayN.Mode;
@ -104,7 +101,7 @@ namespace v2rayN.Handler
//url = Utils.Base64Encode(url); //url = Utils.Base64Encode(url);
//new Sip002 //new Sip002
var pw = Utils.Base64Encode($"{item.security}:{item.id}"); var pw = Utils.Base64Encode($"{item.security}:{item.id}");
url = $"{pw}@{GetIpv6(item.address)}:{ item.port}"; url = $"{pw}@{GetIpv6(item.address)}:{item.port}";
url = $"{Global.ssProtocol}{url}{remark}"; url = $"{Global.ssProtocol}{url}{remark}";
return url; return url;
} }
@ -125,7 +122,7 @@ namespace v2rayN.Handler
//url = Utils.Base64Encode(url); //url = Utils.Base64Encode(url);
//new //new
var pw = Utils.Base64Encode($"{item.security}:{item.id}"); var pw = Utils.Base64Encode($"{item.security}:{item.id}");
url = $"{pw}@{GetIpv6(item.address)}:{ item.port}"; url = $"{pw}@{GetIpv6(item.address)}:{item.port}";
url = $"{Global.socksProtocol}{url}{remark}"; url = $"{Global.socksProtocol}{url}{remark}";
return url; return url;
} }
@ -142,10 +139,7 @@ namespace v2rayN.Handler
GetStdTransport(item, null, ref dicQuery); GetStdTransport(item, null, ref dicQuery);
string query = "?" + string.Join("&", dicQuery.Select(x => x.Key + "=" + x.Value).ToArray()); string query = "?" + string.Join("&", dicQuery.Select(x => x.Key + "=" + x.Value).ToArray());
url = string.Format("{0}@{1}:{2}", url = $"{item.id}@{GetIpv6(item.address)}:{item.port}";
item.id,
GetIpv6(item.address),
item.port);
url = $"{Global.trojanProtocol}{url}{query}{remark}"; url = $"{Global.trojanProtocol}{url}{query}{remark}";
return url; return url;
} }
@ -158,22 +152,14 @@ namespace v2rayN.Handler
{ {
remark = "#" + Utils.UrlEncode(item.remarks); remark = "#" + Utils.UrlEncode(item.remarks);
} }
var dicQuery = new Dictionary<string, string>(); var dicQuery = new Dictionary<string, string>
if (!Utils.IsNullOrEmpty(item.security))
{ {
dicQuery.Add("encryption", item.security); { "encryption", !Utils.IsNullOrEmpty(item.security) ? item.security : "none" }
} };
else
{
dicQuery.Add("encryption", "none");
}
GetStdTransport(item, "none", ref dicQuery); GetStdTransport(item, "none", ref dicQuery);
string query = "?" + string.Join("&", dicQuery.Select(x => x.Key + "=" + x.Value).ToArray()); string query = "?" + string.Join("&", dicQuery.Select(x => x.Key + "=" + x.Value).ToArray());
url = string.Format("{0}@{1}:{2}", url = $"{item.id}@{GetIpv6(item.address)}:{item.port}";
item.id,
GetIpv6(item.address),
item.port);
url = $"{Global.vlessProtocol}{url}{query}{remark}"; url = $"{Global.vlessProtocol}{url}{query}{remark}";
return url; return url;
} }
@ -204,7 +190,7 @@ namespace v2rayN.Handler
{ {
dicQuery.Add("sni", item.sni); dicQuery.Add("sni", item.sni);
} }
if (item.alpn != null && item.alpn.Count > 0) if (item.alpn is { Count: > 0 })
{ {
dicQuery.Add("alpn", Utils.UrlEncode(Utils.List2String(item.alpn))); dicQuery.Add("alpn", Utils.UrlEncode(Utils.List2String(item.alpn)));
} }
@ -261,7 +247,7 @@ namespace v2rayN.Handler
if (!Utils.IsNullOrEmpty(item.path)) if (!Utils.IsNullOrEmpty(item.path))
{ {
dicQuery.Add("serviceName", Utils.UrlEncode(item.path)); dicQuery.Add("serviceName", Utils.UrlEncode(item.path));
if (item.headerType == Global.GrpcgunMode || item.headerType == Global.GrpcmultiMode) if (item.headerType is Global.GrpcgunMode or Global.GrpcmultiMode)
{ {
dicQuery.Add("mode", Utils.UrlEncode(item.headerType)); dicQuery.Add("mode", Utils.UrlEncode(item.headerType));
} }

View file

@ -13,10 +13,10 @@ namespace v2rayN.Handler
{ {
class SpeedtestHandler class SpeedtestHandler
{ {
private Config _config; private readonly Config _config;
private V2rayHandler _v2rayHandler; private readonly V2rayHandler _v2rayHandler;
private List<ServerTestItem> _selecteds; private readonly List<ServerTestItem> _selecteds;
Action<string, string> _updateFunc; private readonly Action<string, string> _updateFunc;
public SpeedtestHandler(Config config) public SpeedtestHandler(Config config)
{ {
@ -137,8 +137,7 @@ namespace v2rayN.Handler
try try
{ {
WebProxy webProxy = new WebProxy(Global.Loopback, it.port); WebProxy webProxy = new WebProxy(Global.Loopback, it.port);
int responseTime = -1; string status = downloadHandle.GetRealPingTime(_config.constItem.speedPingTestUrl, webProxy, out var responseTime);
string status = downloadHandle.GetRealPingTime(_config.constItem.speedPingTestUrl, webProxy, out responseTime);
string output = Utils.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status; string output = Utils.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status;
_config.GetVmessItem(it.indexId)?.SetTestResult(output); _config.GetVmessItem(it.indexId)?.SetTestResult(output);

View file

@ -1,6 +1,7 @@
using Grpc.Core; using Grpc.Core;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
@ -149,24 +150,15 @@ namespace v2rayN.Handler
serverStatistics_ = Utils.FromJson<ServerStatistics>(result); serverStatistics_ = Utils.FromJson<ServerStatistics>(result);
} }
if (serverStatistics_ == null) serverStatistics_ ??= new ServerStatistics();
{ serverStatistics_.server ??= new List<ServerStatItem>();
serverStatistics_ = new ServerStatistics();
}
if (serverStatistics_.server == null)
{
serverStatistics_.server = new List<ServerStatItem>();
}
long ticks = DateTime.Now.Date.Ticks; long ticks = DateTime.Now.Date.Ticks;
foreach (ServerStatItem item in serverStatistics_.server) foreach (var item in serverStatistics_.server.Where(item => item.dateNow != ticks))
{ {
if (item.dateNow != ticks) item.todayUp = 0;
{ item.todayDown = 0;
item.todayUp = 0; item.dateNow = ticks;
item.todayDown = 0;
item.dateNow = ticks;
}
} }
} }
catch (Exception ex) catch (Exception ex)

View file

@ -144,85 +144,81 @@ namespace v2rayN.Handler
// using event to avoid hanging when redirect standard output/error // using event to avoid hanging when redirect standard output/error
// ref: https://stackoverflow.com/questions/139593/processstartinfo-hanging-on-waitforexit-why // ref: https://stackoverflow.com/questions/139593/processstartinfo-hanging-on-waitforexit-why
// and http://blog.csdn.net/zhangweixing0/article/details/7356841 // and http://blog.csdn.net/zhangweixing0/article/details/7356841
using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false)) using AutoResetEvent outputWaitHandle = new AutoResetEvent(false);
using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false)) using AutoResetEvent errorWaitHandle = new AutoResetEvent(false);
using Process process = new Process();
// Configure the process using the StartInfo properties.
process.StartInfo.FileName = Utils.GetTempPath("sysproxy.exe");
process.StartInfo.Arguments = arguments;
process.StartInfo.WorkingDirectory = Utils.GetTempPath();
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
// Need to provide encoding info, or output/error strings we got will be wrong.
process.StartInfo.StandardOutputEncoding = Encoding.Unicode;
process.StartInfo.StandardErrorEncoding = Encoding.Unicode;
process.StartInfo.CreateNoWindow = true;
StringBuilder output = new StringBuilder();
StringBuilder error = new StringBuilder();
process.OutputDataReceived += (sender, e) =>
{ {
using (Process process = new Process()) if (e.Data == null)
{ {
// Configure the process using the StartInfo properties. outputWaitHandle.Set();
process.StartInfo.FileName = Utils.GetTempPath("sysproxy.exe");
process.StartInfo.Arguments = arguments;
process.StartInfo.WorkingDirectory = Utils.GetTempPath();
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
// Need to provide encoding info, or output/error strings we got will be wrong.
process.StartInfo.StandardOutputEncoding = Encoding.Unicode;
process.StartInfo.StandardErrorEncoding = Encoding.Unicode;
process.StartInfo.CreateNoWindow = true;
StringBuilder output = new StringBuilder();
StringBuilder error = new StringBuilder();
process.OutputDataReceived += (sender, e) =>
{
if (e.Data == null)
{
outputWaitHandle.Set();
}
else
{
output.AppendLine(e.Data);
}
};
process.ErrorDataReceived += (sender, e) =>
{
if (e.Data == null)
{
errorWaitHandle.Set();
}
else
{
error.AppendLine(e.Data);
}
};
try
{
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.WaitForExit();
}
catch (System.ComponentModel.Win32Exception e)
{
// log the arguments
throw new Exception(process.StartInfo.Arguments);
}
string stderr = error.ToString();
string stdout = output.ToString();
int exitCode = process.ExitCode;
if (exitCode != (int)RET_ERRORS.RET_NO_ERROR)
{
throw new Exception(stderr);
}
//if (arguments == "query")
//{
// if (stdout.IsNullOrWhiteSpace() || stdout.IsNullOrEmpty())
// {
// throw new Exception("failed to query wininet settings");
// }
// _queryStr = stdout;
//}
} }
else
{
output.AppendLine(e.Data);
}
};
process.ErrorDataReceived += (sender, e) =>
{
if (e.Data == null)
{
errorWaitHandle.Set();
}
else
{
error.AppendLine(e.Data);
}
};
try
{
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.WaitForExit();
} }
catch (System.ComponentModel.Win32Exception e)
{
// log the arguments
throw new Exception(process.StartInfo.Arguments);
}
string stderr = error.ToString();
string stdout = output.ToString();
int exitCode = process.ExitCode;
if (exitCode != (int)RET_ERRORS.RET_NO_ERROR)
{
throw new Exception(stderr);
}
//if (arguments == "query")
//{
// if (stdout.IsNullOrWhiteSpace() || stdout.IsNullOrEmpty())
// {
// throw new Exception("failed to query wininet settings");
// }
// _queryStr = stdout;
//}
} }

View file

@ -8,7 +8,6 @@ using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using Newtonsoft.Json;
using v2rayN.Base; using v2rayN.Base;
using v2rayN.Mode; using v2rayN.Mode;
using v2rayN.Resx; using v2rayN.Resx;
@ -405,15 +404,7 @@ namespace v2rayN.Handler
try try
{ {
var gitHubReleases = Utils.FromJson<List<GitHubRelease>>(gitHubReleaseApi); var gitHubReleases = Utils.FromJson<List<GitHubRelease>>(gitHubReleaseApi);
string version; var version = preRelease ? gitHubReleases!.First().TagName : gitHubReleases!.First(r => r.Prerelease == false).TagName;
if (preRelease)
{
version = gitHubReleases!.First().TagName;
}
else
{
version = gitHubReleases!.First(r => r.Prerelease == false).TagName;
}
var coreInfo = LazyConfig.Instance.GetCoreInfo(type); var coreInfo = LazyConfig.Instance.GetCoreInfo(type);
string curVersion; string curVersion;
@ -437,14 +428,9 @@ namespace v2rayN.Handler
{ {
curVersion = getCoreVersion(type); curVersion = getCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, curVersion); message = string.Format(ResUI.IsLatestCore, curVersion);
if (Environment.Is64BitProcess) url = string.Format(Environment.Is64BitProcess
{ ? coreInfo.coreDownloadUrl64
url = string.Format(coreInfo.coreDownloadUrl64, version); : coreInfo.coreDownloadUrl32, version);
}
else
{
url = string.Format(coreInfo.coreDownloadUrl32, version);
}
break; break;
} }
case ECoreType.v2rayN: case ECoreType.v2rayN:

View file

@ -246,21 +246,21 @@ namespace v2rayN.Handler
{ {
rules.port = null; rules.port = null;
} }
if (rules.domain != null && rules.domain.Count == 0) if (rules.domain is { Count: 0 })
{ {
rules.domain = null; rules.domain = null;
} }
if (rules.ip != null && rules.ip.Count == 0) if (rules.ip is { Count: 0 })
{ {
rules.ip = null; rules.ip = null;
} }
if (rules.protocol != null && rules.protocol.Count == 0) if (rules.protocol is { Count: 0 })
{ {
rules.protocol = null; rules.protocol = null;
} }
var hasDomainIp = false; var hasDomainIp = false;
if (rules.domain != null && rules.domain.Count > 0) if (rules.domain is { Count: > 0 })
{ {
var it = Utils.DeepCopy(rules); var it = Utils.DeepCopy(rules);
it.ip = null; it.ip = null;
@ -284,7 +284,7 @@ namespace v2rayN.Handler
v2rayConfig.routing.rules.Add(it); v2rayConfig.routing.rules.Add(it);
hasDomainIp = true; hasDomainIp = true;
} }
if (rules.ip != null && rules.ip.Count > 0) if (rules.ip is { Count: > 0 })
{ {
var it = Utils.DeepCopy(rules); var it = Utils.DeepCopy(rules);
it.domain = null; it.domain = null;
@ -314,7 +314,7 @@ namespace v2rayN.Handler
it.type = "field"; it.type = "field";
v2rayConfig.routing.rules.Add(it); v2rayConfig.routing.rules.Add(it);
} }
else if (rules.protocol != null && rules.protocol.Count > 0) else if (rules.protocol is { Count: > 0 })
{ {
var it = Utils.DeepCopy(rules); var it = Utils.DeepCopy(rules);
//it.domain = null; //it.domain = null;
@ -377,14 +377,7 @@ namespace v2rayN.Handler
usersItem.id = node.id; usersItem.id = node.id;
usersItem.alterId = node.alterId; usersItem.alterId = node.alterId;
usersItem.email = Global.userEMail; usersItem.email = Global.userEMail;
if (Global.vmessSecuritys.Contains(node.security)) usersItem.security = Global.vmessSecuritys.Contains(node.security) ? node.security : Global.DefaultSecurity;
{
usersItem.security = node.security;
}
else
{
usersItem.security = Global.DefaultSecurity;
}
//Mux //Mux
outbound.mux.enabled = config.muxEnabled; outbound.mux.enabled = config.muxEnabled;
@ -503,14 +496,7 @@ namespace v2rayN.Handler
//if xtls //if xtls
if (node.streamSecurity == Global.StreamSecurityX) if (node.streamSecurity == Global.StreamSecurityX)
{ {
if (Utils.IsNullOrEmpty(node.flow)) usersItem.flow = Utils.IsNullOrEmpty(node.flow) ? Global.xtlsFlows[1] : node.flow.Replace("splice", "direct");
{
usersItem.flow = Global.xtlsFlows[1];
}
else
{
usersItem.flow = node.flow.Replace("splice", "direct");
}
outbound.mux.enabled = false; outbound.mux.enabled = false;
outbound.mux.concurrency = -1; outbound.mux.concurrency = -1;
@ -553,14 +539,9 @@ namespace v2rayN.Handler
//if xtls //if xtls
if (node.streamSecurity == Global.StreamSecurityX) if (node.streamSecurity == Global.StreamSecurityX)
{ {
if (Utils.IsNullOrEmpty(node.flow)) serversItem.flow = Utils.IsNullOrEmpty(node.flow)
{ ? Global.xtlsFlows[1]
serversItem.flow = Global.xtlsFlows[1]; : node.flow.Replace("splice", "direct");
}
else
{
serversItem.flow = node.flow.Replace("splice", "direct");
}
outbound.mux.enabled = false; outbound.mux.enabled = false;
outbound.mux.concurrency = -1; outbound.mux.concurrency = -1;
@ -660,7 +641,7 @@ namespace v2rayN.Handler
} }
else if (iobound.Equals("in")) else if (iobound.Equals("in"))
{ {
kcpSettings.uplinkCapacity = config.kcpItem.downlinkCapacity; ; kcpSettings.uplinkCapacity = config.kcpItem.downlinkCapacity;
kcpSettings.downlinkCapacity = config.kcpItem.downlinkCapacity; kcpSettings.downlinkCapacity = config.kcpItem.downlinkCapacity;
} }
else else
@ -1423,10 +1404,6 @@ namespace v2rayN.Handler
if (!Utils.IsNullOrEmpty(request)) if (!Utils.IsNullOrEmpty(request))
{ {
V2rayTcpRequest v2rayTcpRequest = Utils.FromJson<V2rayTcpRequest>(request); V2rayTcpRequest v2rayTcpRequest = Utils.FromJson<V2rayTcpRequest>(request);
if (v2rayTcpRequest != null
&& v2rayTcpRequest.headers != null
&& v2rayTcpRequest.headers.Host != null
&& v2rayTcpRequest.headers.Host.Count > 0)
{ {
vmessItem.requestHost = v2rayTcpRequest.headers.Host[0]; vmessItem.requestHost = v2rayTcpRequest.headers.Host[0];
} }
@ -1465,17 +1442,14 @@ namespace v2rayN.Handler
{ {
vmessItem.path = inbound.streamSettings.httpSettings.path; vmessItem.path = inbound.streamSettings.httpSettings.path;
} }
if (inbound.streamSettings.httpSettings.host != null if (inbound.streamSettings.httpSettings.host is { Count: > 0 })
&& inbound.streamSettings.httpSettings.host.Count > 0)
{ {
vmessItem.requestHost = Utils.List2String(inbound.streamSettings.httpSettings.host); vmessItem.requestHost = Utils.List2String(inbound.streamSettings.httpSettings.host);
} }
} }
//tls //tls
if (inbound.streamSettings != null if (inbound.streamSettings is { security: Global.StreamSecurity })
&& inbound.streamSettings.security != null
&& inbound.streamSettings.security == Global.StreamSecurity)
{ {
vmessItem.streamSecurity = Global.StreamSecurity; vmessItem.streamSecurity = Global.StreamSecurity;
} }

View file

@ -63,7 +63,7 @@ namespace v2rayN.Handler
} }
//start a socks service //start a socks service
if (_process != null && !_process.HasExited && item.configType == EConfigType.Custom && item.preSocksPort > 0) if (_process is { HasExited: false } && item.configType == EConfigType.Custom && item.preSocksPort > 0)
{ {
var itemSocks = new VmessItem() var itemSocks = new VmessItem()
{ {

View file

@ -275,11 +275,9 @@ namespace v2rayN.Mode
public string GetGroupRemarks(string groupId) public string GetGroupRemarks(string groupId)
{ {
if (string.IsNullOrEmpty(groupId)) return string.IsNullOrEmpty(groupId)
{ ? string.Empty
return string.Empty; : groupItem.FirstOrDefault(it => it.id == groupId)?.remarks;
}
return groupItem.Where(it => it.id == groupId).FirstOrDefault()?.remarks;
} }
#endregion #endregion
@ -316,21 +314,14 @@ namespace v2rayN.Mode
#region function #region function
public string GetSummary() public string GetSummary()
{ {
string summary = string.Format("[{0}] ", (configType).ToString()); string summary = $"[{(configType).ToString()}] ";
string[] arrAddr = address.Split('.'); string[] arrAddr = address.Split('.');
string addr; string addr = arrAddr.Length switch
if (arrAddr.Length > 2)
{ {
addr = $"{arrAddr[0]}***{arrAddr[arrAddr.Length - 1]}"; > 2 => $"{arrAddr[0]}***{arrAddr[arrAddr.Length - 1]}",
} > 1 => $"***{arrAddr[arrAddr.Length - 1]}",
else if (arrAddr.Length > 1) _ => address
{ };
addr = $"***{arrAddr[arrAddr.Length - 1]}";
}
else
{
addr = address;
}
switch (configType) switch (configType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
@ -338,10 +329,10 @@ namespace v2rayN.Mode
case EConfigType.Socks: case EConfigType.Socks:
case EConfigType.VLESS: case EConfigType.VLESS:
case EConfigType.Trojan: case EConfigType.Trojan:
summary += string.Format("{0}({1}:{2})", remarks, addr, port); summary += $"{remarks}({addr}:{port})";
break; break;
default: default:
summary += string.Format("{0}", remarks); summary += $"{remarks}";
break; break;
} }
return summary; return summary;
@ -372,23 +363,12 @@ namespace v2rayN.Mode
return subRemarks; return subRemarks;
} }
var group = config.groupItem.FirstOrDefault(t => t.id == groupId); var group = config.groupItem.FirstOrDefault(t => t.id == groupId);
if (group != null) return group != null ? group.remarks : groupId.Substring(0, 4);
{
return group.remarks;
}
return groupId.Substring(0, 4);
} }
public List<string> GetAlpn() public List<string> GetAlpn()
{ {
if (alpn != null && alpn.Count > 0) return alpn is { Count: > 0 } ? alpn : null;
{
return alpn;
}
else
{
return null;
}
} }
public string GetNetwork() public string GetNetwork()
{ {

View file

@ -1,8 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace v2rayN.Mode namespace v2rayN.Mode
{ {

View file

@ -11,8 +11,8 @@ namespace v2rayN.Tool
{ {
try try
{ {
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) using FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
fs.Write(content, 0, content.Length); fs.Write(content, 0, content.Length);
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
@ -31,14 +31,12 @@ namespace v2rayN.Tool
byte[] buffer = new byte[4096]; byte[] buffer = new byte[4096];
int n; int n;
using (FileStream fs = File.Create(fileName)) using FileStream fs = File.Create(fileName);
using (GZipStream input = new GZipStream(new MemoryStream(content), using GZipStream input = new GZipStream(new MemoryStream(content),
CompressionMode.Decompress, false)) CompressionMode.Decompress, false);
while ((n = input.Read(buffer, 0, buffer.Length)) > 0)
{ {
while ((n = input.Read(buffer, 0, buffer.Length)) > 0) fs.Write(buffer, 0, n);
{
fs.Write(buffer, 0, n);
}
} }
} }
catch (Exception ex) catch (Exception ex)
@ -56,11 +54,9 @@ namespace v2rayN.Tool
{ {
try try
{ {
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (StreamReader sr = new StreamReader(fs, encoding)) using StreamReader sr = new StreamReader(fs, encoding);
{ return sr.ReadToEnd();
return sr.ReadToEnd();
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -111,18 +107,16 @@ namespace v2rayN.Tool
{ {
try try
{ {
using (ZipArchive archive = ZipFile.OpenRead(fileName)) using ZipArchive archive = ZipFile.OpenRead(fileName);
foreach (ZipArchiveEntry entry in archive.Entries)
{ {
foreach (ZipArchiveEntry entry in archive.Entries) if (entry.Length == 0)
{ continue;
if (entry.Length == 0)
continue;
string entryOuputPath = Utils.GetPath(entry.FullName); string entryOuputPath = Utils.GetPath(entry.FullName);
FileInfo fileInfo = new FileInfo(entryOuputPath); FileInfo fileInfo = new FileInfo(entryOuputPath);
fileInfo.Directory.Create(); fileInfo.Directory.Create();
entry.ExtractToFile(entryOuputPath, true); entry.ExtractToFile(entryOuputPath, true);
}
} }
} }
catch (Exception ex) catch (Exception ex)

View file

@ -35,8 +35,7 @@ namespace v2rayN
if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr,
(uint) length)) (uint) length))
throw new Exception(string.Format("Unable to set information. Error: {0}", throw new Exception($"Unable to set information. Error: {Marshal.GetLastWin32Error()}");
Marshal.GetLastWin32Error()));
} }
finally finally
{ {

View file

@ -9,14 +9,14 @@ namespace v2rayN.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(query, propertyName, false);
} }
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName) public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName)
{ {
return _OrderBy<T>(query, propertyName, true); return _OrderBy(query, propertyName, true);
} }
static IOrderedQueryable<T> _OrderBy<T>(IQueryable<T> query, string propertyName, bool isDesc) private static IOrderedQueryable<T> _OrderBy<T>(IQueryable<T> query, string propertyName, bool isDesc)
{ {
string methodname = (isDesc) ? "OrderByDescendingInternal" : "OrderByInternal"; string methodname = (isDesc) ? "OrderByDescendingInternal" : "OrderByInternal";
@ -35,7 +35,8 @@ namespace v2rayN.Tool
{//public {//public
return query.OrderByDescending(_GetLamba<T, TProp>(memberProperty)); return query.OrderByDescending(_GetLamba<T, TProp>(memberProperty));
} }
static Expression<Func<T, TProp>> _GetLamba<T, TProp>(PropertyInfo memberProperty)
private static Expression<Func<T, TProp>> _GetLamba<T, TProp>(PropertyInfo memberProperty)
{ {
if (memberProperty.PropertyType != typeof(TProp)) throw new Exception(); if (memberProperty.PropertyType != typeof(TProp)) throw new Exception();

View file

@ -45,11 +45,9 @@ namespace v2rayN
try try
{ {
Assembly assembly = Assembly.GetExecutingAssembly(); Assembly assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(res)) using Stream stream = assembly.GetManifestResourceStream(res);
using (StreamReader reader = new StreamReader(stream)) using StreamReader reader = new StreamReader(stream);
{ result = reader.ReadToEnd();
result = reader.ReadToEnd();
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -69,10 +67,8 @@ namespace v2rayN
try try
{ {
using (StreamReader reader = new StreamReader(res)) using StreamReader reader = new StreamReader(res);
{ result = reader.ReadToEnd();
result = reader.ReadToEnd();
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -385,7 +381,7 @@ namespace v2rayN
public static string HumanFy(ulong amount) public static string HumanFy(ulong amount)
{ {
ToHumanReadable(amount, out double result, out string unit); ToHumanReadable(amount, out double result, out string unit);
return $"{string.Format("{0:f1}", result)} {unit}"; return $"{$"{result:f1}"} {unit}";
} }
@ -545,29 +541,18 @@ namespace v2rayN
#region #region
private static string autoRunName private static string autoRunName => $"v2rayNAutoRun_{GetMD5(StartupPath())}";
{
get
{
return $"v2rayNAutoRun_{GetMD5(StartupPath())}";
}
}
private static string autoRunRegPath
{
get
{
return @"Software\Microsoft\Windows\CurrentVersion\Run";
//if (Environment.Is64BitProcess)
//{
// return @"Software\Microsoft\Windows\CurrentVersion\Run";
//}
//else
//{
// return @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run";
//}
}
}
private static string autoRunRegPath => @"Software\Microsoft\Windows\CurrentVersion\Run";
//if (Environment.Is64BitProcess)
//{
// return @"Software\Microsoft\Windows\CurrentVersion\Run";
//}
//else
//{
// return @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run";
//}
/// <summary> /// <summary>
/// 开机自动启动 /// 开机自动启动
/// </summary> /// </summary>
@ -703,23 +688,16 @@ namespace v2rayN
public static bool CheckForDotNetVersion(int release = 528040) public static bool CheckForDotNetVersion(int release = 528040)
{ {
const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\"; const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey)) using RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey);
if (ndpKey != null && ndpKey.GetValue("Release") != null)
{ {
if (ndpKey != null && ndpKey.GetValue("Release") != null) return (int)ndpKey.GetValue("Release") >= release ? true : false;
{
return (int)ndpKey.GetValue("Release") >= release ? true : false;
}
return false;
} }
return false;
} }
public static string MainMsgFilterKey public static string MainMsgFilterKey => $"MainMsgFilter_{GetMD5(StartupPath())}";
{
get
{
return $"MainMsgFilter_{GetMD5(StartupPath())}";
}
}
#endregion #endregion
#region #region
@ -837,14 +815,12 @@ namespace v2rayN
string location = GetExePath(); string location = GetExePath();
if (blFull) if (blFull)
{ {
return string.Format("v2rayN - V{0} - {1}", return
FileVersionInfo.GetVersionInfo(location).FileVersion.ToString(), $"v2rayN - V{FileVersionInfo.GetVersionInfo(location).FileVersion.ToString()} - {File.GetLastWriteTime(location).ToString("yyyy/MM/dd")}";
File.GetLastWriteTime(location).ToString("yyyy/MM/dd"));
} }
else else
{ {
return string.Format("v2rayN/{0}", return $"v2rayN/{FileVersionInfo.GetVersionInfo(location).FileVersion.ToString()}";
FileVersionInfo.GetVersionInfo(location).FileVersion.ToString());
} }
} }
catch (Exception ex) catch (Exception ex)
@ -1076,42 +1052,40 @@ namespace v2rayN
{ {
foreach (Screen screen in Screen.AllScreens) foreach (Screen screen in Screen.AllScreens)
{ {
using (Bitmap fullImage = new Bitmap(screen.Bounds.Width, using Bitmap fullImage = new Bitmap(screen.Bounds.Width,
screen.Bounds.Height)) screen.Bounds.Height);
using (Graphics g = Graphics.FromImage(fullImage))
{ {
using (Graphics g = Graphics.FromImage(fullImage)) g.CopyFromScreen(screen.Bounds.X,
screen.Bounds.Y,
0, 0,
fullImage.Size,
CopyPixelOperation.SourceCopy);
}
int maxTry = 10;
for (int i = 0; i < maxTry; i++)
{
int marginLeft = (int)((double)fullImage.Width * i / 2.5 / maxTry);
int marginTop = (int)((double)fullImage.Height * i / 2.5 / maxTry);
Rectangle cropRect = new Rectangle(marginLeft, marginTop, fullImage.Width - marginLeft * 2, fullImage.Height - marginTop * 2);
Bitmap target = new Bitmap(screen.Bounds.Width, screen.Bounds.Height);
double imageScale = (double)screen.Bounds.Width / (double)cropRect.Width;
using (Graphics g = Graphics.FromImage(target))
{ {
g.CopyFromScreen(screen.Bounds.X, g.DrawImage(fullImage, new Rectangle(0, 0, target.Width, target.Height),
screen.Bounds.Y, cropRect,
0, 0, GraphicsUnit.Pixel);
fullImage.Size,
CopyPixelOperation.SourceCopy);
} }
int maxTry = 10;
for (int i = 0; i < maxTry; i++) BitmapLuminanceSource source = new BitmapLuminanceSource(target);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
QRCodeReader reader = new QRCodeReader();
Result result = reader.decode(bitmap);
if (result != null)
{ {
int marginLeft = (int)((double)fullImage.Width * i / 2.5 / maxTry); string ret = result.Text;
int marginTop = (int)((double)fullImage.Height * i / 2.5 / maxTry); return ret;
Rectangle cropRect = new Rectangle(marginLeft, marginTop, fullImage.Width - marginLeft * 2, fullImage.Height - marginTop * 2);
Bitmap target = new Bitmap(screen.Bounds.Width, screen.Bounds.Height);
double imageScale = (double)screen.Bounds.Width / (double)cropRect.Width;
using (Graphics g = Graphics.FromImage(target))
{
g.DrawImage(fullImage, new Rectangle(0, 0, target.Width, target.Height),
cropRect,
GraphicsUnit.Pixel);
}
BitmapLuminanceSource source = new BitmapLuminanceSource(target);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
QRCodeReader reader = new QRCodeReader();
Result result = reader.decode(bitmap);
if (result != null)
{
string ret = result.Text;
return ret;
}
} }
} }
} }
@ -1128,13 +1102,7 @@ namespace v2rayN
#region Windows API #region Windows API
public static string WindowHwndKey public static string WindowHwndKey => $"WindowHwnd_{GetMD5(StartupPath())}";
{
get
{
return $"WindowHwnd_{GetMD5(StartupPath())}";
}
}
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool SetProcessDPIAware(); public static extern bool SetProcessDPIAware();