Compare commits

..

9 Commits
5.3 ... 5.6

Author SHA1 Message Date
2dust
d20791bf73 Update AssemblyInfo.cs 2022-03-23 18:56:01 +08:00
2dust
7bb91f57ac Custom configuration overwrite port 2022-03-23 18:49:28 +08:00
2dust
b7a6004830 some improvements 2022-03-23 18:48:57 +08:00
2dust
dee5613f2f add move servers to group 2022-03-23 18:47:59 +08:00
2dust
e58e0d6ac7 Update AssemblyInfo.cs 2022-03-21 20:36:07 +08:00
2dust
a2679e009d refactor some code 2022-03-21 20:20:29 +08:00
2dust
78d6bcd57a Full profile can be subscribed 2022-03-20 20:40:07 +08:00
2dust
026936c92f Update AssemblyInfo.cs 2022-03-19 19:27:14 +08:00
2dust
5e5893362c add clash core 2022-03-19 19:26:51 +08:00
25 changed files with 609 additions and 328 deletions

View File

@@ -18,6 +18,7 @@ namespace v2rayN.Forms
private void AddServer2Form_Load(object sender, EventArgs e)
{
cmbCoreType.Items.AddRange(Global.coreTypes.ToArray());
cmbCoreType.Items.Add("clash");
cmbCoreType.Items.Add(string.Empty);
txtAddress.ReadOnly = true;
@@ -112,7 +113,7 @@ namespace v2rayN.Forms
OpenFileDialog fileDialog = new OpenFileDialog
{
Multiselect = false,
Filter = "Config|*.json|All|*.*"
Filter = "Config|*.json|YAML|*.yaml|All|*.*"
};
if (fileDialog.ShowDialog() != DialogResult.OK)
{
@@ -127,7 +128,7 @@ namespace v2rayN.Forms
vmessItem.address = fileName;
vmessItem.remarks = txtRemarks.Text;
if (ConfigHandler.AddCustomServer(ref config, vmessItem) == 0)
if (ConfigHandler.AddCustomServer(ref config, vmessItem, false) == 0)
{
BindingServer();
UI.Show(UIRes.I18N("SuccessfullyImportedCustomServer"));
@@ -147,7 +148,7 @@ namespace v2rayN.Forms
return;
}
address = Path.Combine(Utils.GetTempPath(), address);
address = Path.Combine(Utils.GetConfigPath(), address);
Process.Start(address);
}
}

View File

@@ -16,13 +16,7 @@ namespace v2rayN.Forms
private void AddServerForm_Load(object sender, EventArgs e)
{
this.Text = (eConfigType).ToString();
cmbSecurity.Items.AddRange(Global.vmessSecuritys.ToArray());
cmbSecurity3.Items.AddRange(config.GetShadowsocksSecuritys().ToArray());
cmbFlow5.Items.AddRange(Global.xtlsFlows.ToArray());
cmbFlow6.Items.AddRange(Global.xtlsFlows.ToArray());
cmbCoreType.Items.AddRange(Global.coreTypes.ToArray());
cmbCoreType.Items.Add(string.Empty);
@@ -31,12 +25,16 @@ namespace v2rayN.Forms
case EConfigType.Vmess:
panVmess.Dock = DockStyle.Fill;
panVmess.Visible = true;
cmbSecurity.Items.AddRange(Global.vmessSecuritys.ToArray());
break;
case EConfigType.Shadowsocks:
panSs.Dock = DockStyle.Fill;
panSs.Visible = true;
panTran.Visible = false;
this.Height = this.Height - panTran.Height;
cmbSecurity3.Items.AddRange(LazyConfig.Instance.GetShadowsocksSecuritys().ToArray());
break;
case EConfigType.Socks:
panSocks.Dock = DockStyle.Fill;
@@ -48,11 +46,15 @@ namespace v2rayN.Forms
panVless.Dock = DockStyle.Fill;
panVless.Visible = true;
transportControl.AllowXtls = true;
cmbFlow5.Items.AddRange(Global.xtlsFlows.ToArray());
break;
case EConfigType.Trojan:
panTrojan.Dock = DockStyle.Fill;
panTrojan.Visible = true;
transportControl.AllowXtls = true;
cmbFlow6.Items.AddRange(Global.xtlsFlows.ToArray());
break;
}

View File

@@ -47,6 +47,7 @@
this.menuCopyServer = new System.Windows.Forms.ToolStripMenuItem();
this.menuSetDefaultServer = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.menuMoveToGroup = new System.Windows.Forms.ToolStripMenuItem();
this.menuMoveTop = new System.Windows.Forms.ToolStripMenuItem();
this.menuMoveUp = new System.Windows.Forms.ToolStripMenuItem();
this.menuMoveDown = new System.Windows.Forms.ToolStripMenuItem();
@@ -64,9 +65,9 @@
this.menuExport2ServerConfig = new System.Windows.Forms.ToolStripMenuItem();
this.menuExport2ShareUrl = new System.Windows.Forms.ToolStripMenuItem();
this.menuExport2SubContent = new System.Windows.Forms.ToolStripMenuItem();
this.tsbServer = new System.Windows.Forms.ToolStripDropDownButton();
this.tabGroup = new System.Windows.Forms.TabControl();
this.qrCodeControl = new v2rayN.Forms.QRCodeControl();
this.tsbServer = new System.Windows.Forms.ToolStripDropDownButton();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.gbMsgTitle = new System.Windows.Forms.GroupBox();
@@ -208,6 +209,7 @@
this.menuCopyServer,
this.menuSetDefaultServer,
this.toolStripSeparator3,
this.menuMoveToGroup,
this.menuMoveTop,
this.menuMoveUp,
this.menuMoveDown,
@@ -226,6 +228,7 @@
this.menuExport2ShareUrl,
this.menuExport2SubContent});
this.cmsLv.Name = "cmsLv";
this.cmsLv.OwnerItem = this.tsbServer;
resources.ApplyResources(this.cmsLv, "cmsLv");
//
// menuAddVmessServer
@@ -310,6 +313,12 @@
this.toolStripSeparator3.Name = "toolStripSeparator3";
resources.ApplyResources(this.toolStripSeparator3, "toolStripSeparator3");
//
// menuMoveToGroup
//
this.menuMoveToGroup.Name = "menuMoveToGroup";
resources.ApplyResources(this.menuMoveToGroup, "menuMoveToGroup");
this.menuMoveToGroup.Click += new System.EventHandler(this.menuMoveToGroup_Click);
//
// menuMoveTop
//
this.menuMoveTop.Name = "menuMoveTop";
@@ -410,6 +419,13 @@
resources.ApplyResources(this.menuExport2SubContent, "menuExport2SubContent");
this.menuExport2SubContent.Click += new System.EventHandler(this.menuExport2SubContent_Click);
//
// tsbServer
//
this.tsbServer.DropDown = this.cmsLv;
this.tsbServer.Image = global::v2rayN.Properties.Resources.server;
resources.ApplyResources(this.tsbServer, "tsbServer");
this.tsbServer.Name = "tsbServer";
//
// tabGroup
//
resources.ApplyResources(this.tabGroup, "tabGroup");
@@ -422,13 +438,6 @@
resources.ApplyResources(this.qrCodeControl, "qrCodeControl");
this.qrCodeControl.Name = "qrCodeControl";
//
// tsbServer
//
this.tsbServer.DropDown = this.cmsLv;
this.tsbServer.Image = global::v2rayN.Properties.Resources.server;
resources.ApplyResources(this.tsbServer, "tsbServer");
this.tsbServer.Name = "tsbServer";
//
// splitContainer1
//
resources.ApplyResources(this.splitContainer1, "splitContainer1");
@@ -1076,6 +1085,7 @@
private System.Windows.Forms.ToolStripMenuItem tsbGlobalHotkeySetting;
private System.Windows.Forms.TabControl tabGroup;
private System.Windows.Forms.ToolStripMenuItem tsbGroupSetting;
private System.Windows.Forms.ToolStripMenuItem menuMoveToGroup;
}
}

View File

@@ -485,6 +485,23 @@ namespace v2rayN.Forms
}
tabGroup.SelectedIndex = 0;
//menuMoveToGroup
menuMoveToGroup.DropDownItems.Clear();
List<ToolStripMenuItem> lst = new List<ToolStripMenuItem>();
foreach (var item in config.groupItem)
{
string name = item.remarks;
ToolStripMenuItem ts = new ToolStripMenuItem(name)
{
Tag = item.id,
};
ts.Click += new EventHandler(ts_Group_Click);
lst.Add(ts);
}
menuMoveToGroup.DropDownItems.AddRange(lst.ToArray());
}
private void tabGroup_SelectedIndexChanged(object sender, EventArgs e)
@@ -501,6 +518,29 @@ namespace v2rayN.Forms
lvServers.Focus();
}
private void ts_Group_Click(object sender, EventArgs e)
{
try
{
ToolStripItem ts = (ToolStripItem)sender;
var groupIdSelected = Utils.ToString(ts.Tag);
int index = GetLvSelectedIndex();
if (index < 0)
{
return;
}
if (ConfigHandler.MoveServerToGroup(config, lstSelecteds, groupIdSelected) == 0)
{
RefreshServers();
}
}
catch
{
}
}
#endregion
#region v2ray
@@ -586,7 +626,7 @@ namespace v2rayN.Forms
else
{
fm = new AddServerForm();
}
}
fm.vmessItem = index >= 0 ? lstVmess[index] : null;
fm.groupId = groupId;
fm.eConfigType = configType;
@@ -688,8 +728,7 @@ namespace v2rayN.Forms
private void menuRemoveDuplicateServer_Click(object sender, EventArgs e)
{
int oldCount = lstVmess.Count;
ConfigHandler.DedupServerList(ref config, ref lstVmess);
int newCount = lstVmess.Count;
int newCount = ConfigHandler.DedupServerList(ref config, ref lstVmess);
RefreshServers();
_ = LoadV2ray();
UI.Show(string.Format(UIRes.I18N("RemoveDuplicateServerResult"), oldCount, newCount));
@@ -721,11 +760,11 @@ namespace v2rayN.Forms
private void menuPingServer_Click(object sender, EventArgs e)
{
Speedtest("ping");
Speedtest(ESpeedActionType.Ping);
}
private void menuTcpingServer_Click(object sender, EventArgs e)
{
Speedtest("tcping");
Speedtest(ESpeedActionType.Tcping);
}
private void menuRealPingServer_Click(object sender, EventArgs e)
@@ -738,7 +777,7 @@ namespace v2rayN.Forms
//UI.Show(UIRes.I18N("SpeedServerTips"));
Speedtest("realping");
Speedtest(ESpeedActionType.Realping);
}
private void menuSpeedServer_Click(object sender, EventArgs e)
@@ -751,13 +790,13 @@ namespace v2rayN.Forms
//UI.Show(UIRes.I18N("SpeedServerTips"));
Speedtest("speedtest");
Speedtest(ESpeedActionType.Speedtest);
}
private void Speedtest(string actionType)
private void Speedtest(ESpeedActionType actionType)
{
if (GetLvSelectedIndex() < 0) return;
ClearTestResult();
SpeedtestHandler statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lstSelecteds, actionType, UpdateSpeedtestHandler);
SpeedtestHandler statistics = new SpeedtestHandler(ref config, v2rayHandler, lstSelecteds, actionType, UpdateSpeedtestHandler);
}
private void tsbTestMe_Click(object sender, EventArgs e)
@@ -964,7 +1003,7 @@ namespace v2rayN.Forms
private void menuAddServers_Click(object sender, EventArgs e)
{
string clipboardData = Utils.GetClipboardData();
int ret = MainFormHandler.Instance.AddBatchServers(config, clipboardData, "", groupId);
int ret = ConfigHandler.AddBatchServers(ref config, clipboardData, "", groupId);
if (ret > 0)
{
RefreshServers();
@@ -994,7 +1033,7 @@ namespace v2rayN.Forms
}
else
{
int ret = MainFormHandler.Instance.AddBatchServers(config, result, "", groupId);
int ret = ConfigHandler.AddBatchServers(ref config, result, "", groupId);
if (ret > 0)
{
RefreshServers();
@@ -1281,7 +1320,9 @@ namespace v2rayN.Forms
item.Selected = true;
}
}
private void menuMoveToGroup_Click(object sender, EventArgs e)
{
}
#endregion
#region

View File

@@ -206,6 +206,12 @@
<data name="toolStripSeparator3.Size" type="System.Drawing.Size, System.Drawing">
<value>352, 6</value>
</data>
<data name="menuMoveToGroup.Size" type="System.Drawing.Size, System.Drawing">
<value>355, 22</value>
</data>
<data name="menuMoveToGroup.Text" xml:space="preserve">
<value>Move to Group</value>
</data>
<data name="menuMoveTop.Size" type="System.Drawing.Size, System.Drawing">
<value>355, 22</value>
</data>
@@ -302,8 +308,20 @@
<data name="menuExport2SubContent.Text" xml:space="preserve">
<value>Export subscription (base64) share to clipboard</value>
</data>
<data name="tsbServer.ImageTransparentColor" type="System.Drawing.Color, System.Drawing">
<value>Magenta</value>
</data>
<data name="tsbServer.Size" type="System.Drawing.Size, System.Drawing">
<value>64, 53</value>
</data>
<data name="tsbServer.Text" xml:space="preserve">
<value>Servers</value>
</data>
<data name="tsbServer.TextImageRelation" type="System.Windows.Forms.TextImageRelation, System.Windows.Forms">
<value>ImageAboveText</value>
</data>
<data name="cmsLv.Size" type="System.Drawing.Size, System.Drawing">
<value>356, 622</value>
<value>356, 666</value>
</data>
<data name="&gt;&gt;cmsLv.Name" xml:space="preserve">
<value>cmsLv</value>
@@ -452,18 +470,6 @@
<data name="&gt;&gt;scMain.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="tsbServer.ImageTransparentColor" type="System.Drawing.Color, System.Drawing">
<value>Magenta</value>
</data>
<data name="tsbServer.Size" type="System.Drawing.Size, System.Drawing">
<value>64, 53</value>
</data>
<data name="tsbServer.Text" xml:space="preserve">
<value>Servers</value>
</data>
<data name="tsbServer.TextImageRelation" type="System.Windows.Forms.TextImageRelation, System.Windows.Forms">
<value>ImageAboveText</value>
</data>
<data name="splitContainer1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
@@ -549,7 +555,7 @@
<value>Set message filters</value>
</data>
<data name="cmsMsgBox.Size" type="System.Drawing.Size, System.Drawing">
<value>228, 158</value>
<value>228, 136</value>
</data>
<data name="&gt;&gt;cmsMsgBox.Name" xml:space="preserve">
<value>cmsMsgBox</value>
@@ -1205,6 +1211,12 @@
<data name="&gt;&gt;toolStripSeparator3.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;menuMoveToGroup.Name" xml:space="preserve">
<value>menuMoveToGroup</value>
</data>
<data name="&gt;&gt;menuMoveToGroup.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;menuMoveTop.Name" xml:space="preserve">
<value>menuMoveTop</value>
</data>

View File

@@ -573,4 +573,7 @@
<data name="tsbClose.Text" xml:space="preserve">
<value> 关闭窗口 </value>
</data>
<data name="menuMoveToGroup.Text" xml:space="preserve">
<value>移至分组</value>
</data>
</root>

View File

@@ -146,7 +146,7 @@ namespace v2rayN.Forms
config.coreTypeItem.Add(new CoreTypeItem()
{
configType = it,
coreType = ECoreType.v2fly
coreType = ECoreType.Xray
});
}
for (int k = 1; k <= config.coreTypeItem.Count; k++)

View File

@@ -14,6 +14,9 @@ namespace v2rayN
public const string v2flyCoreUrl = "https://github.com/v2fly/v2ray-core/releases";
public const string xrayCoreUrl = "https://github.com/XTLS/Xray-core/releases";
public const string NUrl = @"https://github.com/2dust/v2rayN/releases";
public const string clashCoreUrl = "https://github.com/Dreamacro/clash/releases";
/// <summary>

View File

@@ -184,6 +184,28 @@ namespace v2rayN.Handler
LazyConfig.Instance.SetConfig(ref config);
return 0;
}
/// <summary>
/// 保参数
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static int SaveConfig(ref Config config, bool reload = true)
{
Global.reloadV2ray = reload;
ToJsonFile(config);
return 0;
}
/// <summary>
/// 存储文件
/// </summary>
/// <param name="config"></param>
private static void ToJsonFile(Config config)
{
Utils.ToJsonFile(config, Utils.GetPath(configRes));
}
#endregion
@@ -235,7 +257,7 @@ namespace v2rayN.Handler
var index = config.FindIndexId(item.indexId);
if (index >= 0)
{
config.vmess.RemoveAt(index);
RemoveVmessItem(config, index);
}
}
@@ -323,29 +345,6 @@ namespace v2rayN.Handler
return config.vmess[index];
}
/// <summary>
/// 保参数
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static int SaveConfig(ref Config config, bool reload = true)
{
Global.reloadV2ray = reload;
ToJsonFile(config);
return 0;
}
/// <summary>
/// 存储文件
/// </summary>
/// <param name="config"></param>
private static void ToJsonFile(Config config)
{
Utils.ToJsonFile(config, Utils.GetPath(configRes));
}
/// <summary>
/// 移动服务器
/// </summary>
@@ -423,15 +422,24 @@ namespace v2rayN.Handler
/// <param name="config"></param>
/// <param name="vmessItem"></param>
/// <returns></returns>
public static int AddCustomServer(ref Config config, VmessItem vmessItem)
public static int AddCustomServer(ref Config config, VmessItem vmessItem, bool blDelete)
{
var fileName = vmessItem.address;
string newFileName = string.Format("{0}.json", Utils.GetGUID());
if (!File.Exists(fileName))
{
return -1;
}
var ext = Path.GetExtension(fileName);
string newFileName = string.Format("{0}{1}", Utils.GetGUID(), ext);
//newFileName = Path.Combine(Utils.GetTempPath(), newFileName);
try
{
File.Copy(fileName, Path.Combine(Utils.GetTempPath(), newFileName));
File.Copy(fileName, Path.Combine(Utils.GetConfigPath(), newFileName));
if (blDelete)
{
File.Delete(fileName);
}
}
catch
{
@@ -480,7 +488,7 @@ namespace v2rayN.Handler
vmessItem.id = vmessItem.id.TrimEx();
vmessItem.security = vmessItem.security.TrimEx();
if (!config.GetShadowsocksSecuritys().Contains(vmessItem.security))
if (!LazyConfig.Instance.GetShadowsocksSecuritys().Contains(vmessItem.security))
{
return -1;
}
@@ -517,7 +525,6 @@ namespace v2rayN.Handler
return 0;
}
/// <summary>
/// 添加服务器或编辑
/// </summary>
@@ -614,178 +621,6 @@ namespace v2rayN.Handler
return 0;
}
/// <summary>
/// 批量添加服务器
/// </summary>
/// <param name="config"></param>
/// <param name="clipboardData"></param>
/// <param name="subid"></param>
/// <returns>成功导入的数量</returns>
public static int AddBatchServers(ref Config config, string clipboardData, string subid, List<VmessItem> lstOriSub, string groupId)
{
if (Utils.IsNullOrEmpty(clipboardData))
{
return -1;
}
//copy sub items
if (!Utils.IsNullOrEmpty(subid))
{
RemoveServerViaSubid(ref config, subid);
}
//if (clipboardData.IndexOf("vmess") >= 0 && clipboardData.IndexOf("vmess") == clipboardData.LastIndexOf("vmess"))
//{
// clipboardData = clipboardData.Replace("\r\n", "").Replace("\n", "");
//}
int countServers = 0;
//string[] arrData = clipboardData.Split(new string[] { "\r\n" }, StringSplitOptions.None);
string[] arrData = clipboardData.Split(Environment.NewLine.ToCharArray());
foreach (string str in arrData)
{
//maybe sub
if (Utils.IsNullOrEmpty(subid) && (str.StartsWith(Global.httpsProtocol) || str.StartsWith(Global.httpProtocol)))
{
if (AddSubItem(ref config, str) == 0)
{
countServers++;
}
continue;
}
VmessItem vmessItem = ShareHandler.ImportFromClipboardConfig(str, out string msg);
if (vmessItem == null)
{
continue;
}
//exist sub items
if (!Utils.IsNullOrEmpty(subid))
{
var existItem = lstOriSub?.FirstOrDefault(t => CompareVmessItem(t, vmessItem, true));
if (existItem != null)
{
vmessItem = existItem;
}
vmessItem.subid = subid;
}
//groupId
vmessItem.groupId = groupId;
if (vmessItem.configType == EConfigType.Vmess)
{
if (AddServer(ref config, vmessItem, false) == 0)
{
countServers++;
}
}
else if (vmessItem.configType == EConfigType.Shadowsocks)
{
if (AddShadowsocksServer(ref config, vmessItem, false) == 0)
{
countServers++;
}
}
else if (vmessItem.configType == EConfigType.Socks)
{
if (AddSocksServer(ref config, vmessItem, false) == 0)
{
countServers++;
}
}
else if (vmessItem.configType == EConfigType.Trojan)
{
if (AddTrojanServer(ref config, vmessItem, false) == 0)
{
countServers++;
}
}
else if (vmessItem.configType == EConfigType.VLESS)
{
if (AddVlessServer(ref config, vmessItem, false) == 0)
{
countServers++;
}
}
}
ToJsonFile(config);
return countServers;
}
/// <summary>
/// add sub
/// </summary>
/// <param name="config"></param>
/// <param name="url"></param>
/// <returns></returns>
public static int AddSubItem(ref Config config, string url)
{
//already exists
if (config.subItem.FindIndex(e => e.url == url) >= 0)
{
return 0;
}
SubItem subItem = new SubItem
{
id = string.Empty,
remarks = "import sub",
url = url
};
config.subItem.Add(subItem);
return SaveSubItem(ref config);
}
/// <summary>
/// save sub
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static int SaveSubItem(ref Config config)
{
if (config.subItem == null)
{
return -1;
}
foreach (SubItem item in config.subItem)
{
if (Utils.IsNullOrEmpty(item.id))
{
item.id = Utils.GetGUID(false);
}
}
ToJsonFile(config);
return 0;
}
/// <summary>
/// 移除服务器
/// </summary>
/// <param name="config"></param>
/// <param name="subid"></param>
/// <returns></returns>
public static int RemoveServerViaSubid(ref Config config, string subid)
{
if (Utils.IsNullOrEmpty(subid) || config.vmess.Count <= 0)
{
return -1;
}
for (int k = config.vmess.Count - 1; k >= 0; k--)
{
if (config.vmess[k].subid.Equals(subid))
{
config.vmess.RemoveAt(k);
}
}
ToJsonFile(config);
return 0;
}
public static int SortServers(ref Config config, ref List<VmessItem> lstVmess, EServerColName name, bool asc)
{
if (lstVmess.Count <= 0)
@@ -879,14 +714,14 @@ namespace v2rayN.Handler
var index = config.FindIndexId(item.indexId);
if (index >= 0)
{
config.vmess.RemoveAt(index);
RemoveVmessItem(config, index);
}
}
}
//if (!keepOlder) list.Reverse();
//config.vmess = list;
return 0;
return list.Count;
}
public static int AddServerCommon(ref Config config, VmessItem vmessItem)
@@ -944,6 +779,291 @@ namespace v2rayN.Handler
&& (remarks ? o.remarks == n.remarks : true);
}
private static int RemoveVmessItem(Config config, int index)
{
try
{
if (config.vmess[index].configType == EConfigType.Custom)
{
File.Delete(Utils.GetConfigPath(config.vmess[index].address));
}
}
catch (Exception ex)
{
Utils.SaveLog("RemoveVmessItem", ex);
}
config.vmess.RemoveAt(index);
return 0;
}
#endregion
#region Batch add servers
/// <summary>
/// 批量添加服务器
/// </summary>
/// <param name="config"></param>
/// <param name="clipboardData"></param>
/// <param name="subid"></param>
/// <returns>成功导入的数量</returns>
private static int AddBatchServers(ref Config config, string clipboardData, string subid, List<VmessItem> lstOriSub, string groupId)
{
if (Utils.IsNullOrEmpty(clipboardData))
{
return -1;
}
//copy sub items
if (!Utils.IsNullOrEmpty(subid))
{
RemoveServerViaSubid(ref config, subid);
}
//if (clipboardData.IndexOf("vmess") >= 0 && clipboardData.IndexOf("vmess") == clipboardData.LastIndexOf("vmess"))
//{
// clipboardData = clipboardData.Replace("\r\n", "").Replace("\n", "");
//}
int countServers = 0;
//string[] arrData = clipboardData.Split(new string[] { "\r\n" }, StringSplitOptions.None);
string[] arrData = clipboardData.Split(Environment.NewLine.ToCharArray());
foreach (string str in arrData)
{
//maybe sub
if (Utils.IsNullOrEmpty(subid) && (str.StartsWith(Global.httpsProtocol) || str.StartsWith(Global.httpProtocol)))
{
if (AddSubItem(ref config, str) == 0)
{
countServers++;
}
continue;
}
VmessItem vmessItem = ShareHandler.ImportFromClipboardConfig(str, out string msg);
if (vmessItem == null)
{
continue;
}
//exist sub items
if (!Utils.IsNullOrEmpty(subid))
{
var existItem = lstOriSub?.FirstOrDefault(t => CompareVmessItem(t, vmessItem, true));
if (existItem != null)
{
vmessItem = existItem;
}
vmessItem.subid = subid;
}
//groupId
vmessItem.groupId = groupId;
if (vmessItem.configType == EConfigType.Vmess)
{
if (AddServer(ref config, vmessItem, false) == 0)
{
countServers++;
}
}
else if (vmessItem.configType == EConfigType.Shadowsocks)
{
if (AddShadowsocksServer(ref config, vmessItem, false) == 0)
{
countServers++;
}
}
else if (vmessItem.configType == EConfigType.Socks)
{
if (AddSocksServer(ref config, vmessItem, false) == 0)
{
countServers++;
}
}
else if (vmessItem.configType == EConfigType.Trojan)
{
if (AddTrojanServer(ref config, vmessItem, false) == 0)
{
countServers++;
}
}
else if (vmessItem.configType == EConfigType.VLESS)
{
if (AddVlessServer(ref config, vmessItem, false) == 0)
{
countServers++;
}
}
}
ToJsonFile(config);
return countServers;
}
private static int AddBatchServers4Custom(ref Config config, string clipboardData, string subid, List<VmessItem> lstOriSub, string groupId)
{
if (Utils.IsNullOrEmpty(clipboardData))
{
return -1;
}
VmessItem vmessItem = new VmessItem();
//Is v2ray configuration
V2rayConfig v2rayConfig = Utils.FromJson<V2rayConfig>(clipboardData);
if (v2rayConfig != null
&& v2rayConfig.inbounds != null
&& v2rayConfig.inbounds.Count > 0
&& v2rayConfig.outbounds != null
&& v2rayConfig.outbounds.Count > 0)
{
var fileName = Utils.GetTempPath($"{Utils.GetGUID(false)}.json");
File.WriteAllText(fileName, clipboardData);
vmessItem.coreType = ECoreType.Xray;
vmessItem.address = fileName;
vmessItem.remarks = "v2ray_custom";
}
//Is Clash configuration
else if (clipboardData.IndexOf("port") >= 0
&& clipboardData.IndexOf("socks-port") >= 0
&& clipboardData.IndexOf("proxies") >= 0)
{
var fileName = Utils.GetTempPath($"{Utils.GetGUID(false)}.yaml");
File.WriteAllText(fileName, clipboardData);
vmessItem.coreType = ECoreType.clash;
vmessItem.address = fileName;
vmessItem.remarks = "clash_custom";
}
if (!Utils.IsNullOrEmpty(subid))
{
RemoveServerViaSubid(ref config, subid);
}
if (lstOriSub != null && lstOriSub.Count == 1)
{
vmessItem.indexId = lstOriSub[0].indexId;
}
vmessItem.subid = subid;
vmessItem.groupId = groupId;
if (Utils.IsNullOrEmpty(vmessItem.address))
{
return -1;
}
if (AddCustomServer(ref config, vmessItem, true) == 0)
{
return 1;
}
else
{
return -1;
}
}
public static int AddBatchServers(ref Config config, string clipboardData, string subid, string groupId)
{
List<VmessItem> lstOriSub = null;
if (!Utils.IsNullOrEmpty(subid))
{
lstOriSub = config.vmess.Where(it => it.subid == subid).ToList();
}
int counter = AddBatchServers(ref config, clipboardData, subid, lstOriSub, groupId);
if (counter < 1)
{
counter = AddBatchServers(ref config, Utils.Base64Decode(clipboardData), subid, lstOriSub, groupId);
}
//maybe other sub
if (counter < 1)
{
counter = AddBatchServers4Custom(ref config, clipboardData, subid, lstOriSub, groupId);
}
return counter;
}
#endregion
#region Sub & Group
/// <summary>
/// add sub
/// </summary>
/// <param name="config"></param>
/// <param name="url"></param>
/// <returns></returns>
public static int AddSubItem(ref Config config, string url)
{
//already exists
if (config.subItem.FindIndex(e => e.url == url) >= 0)
{
return 0;
}
SubItem subItem = new SubItem
{
id = string.Empty,
remarks = "import sub",
url = url
};
config.subItem.Add(subItem);
return SaveSubItem(ref config);
}
/// <summary>
/// save sub
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static int SaveSubItem(ref Config config)
{
if (config.subItem == null)
{
return -1;
}
foreach (SubItem item in config.subItem)
{
if (Utils.IsNullOrEmpty(item.id))
{
item.id = Utils.GetGUID(false);
}
}
ToJsonFile(config);
return 0;
}
/// <summary>
/// 移除服务器
/// </summary>
/// <param name="config"></param>
/// <param name="subid"></param>
/// <returns></returns>
public static int RemoveServerViaSubid(ref Config config, string subid)
{
if (Utils.IsNullOrEmpty(subid) || config.vmess.Count <= 0)
{
return -1;
}
for (int k = config.vmess.Count - 1; k >= 0; k--)
{
if (config.vmess[k].subid.Equals(subid))
{
RemoveVmessItem(config, k);
}
}
ToJsonFile(config);
return 0;
}
/// <summary>
/// save Group
/// </summary>
@@ -994,6 +1114,18 @@ namespace v2rayN.Handler
ToJsonFile(config);
return 0;
}
public static int MoveServerToGroup(Config config, List<VmessItem> indexs, string groupId)
{
foreach (var item in indexs)
{
item.groupId = groupId;
}
ToJsonFile(config);
return 0;
}
#endregion
#region UI

View File

@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using v2rayN.Base;
namespace v2rayN.Handler
@@ -139,6 +140,7 @@ namespace v2rayN.Handler
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
WebClientEx ws = new WebClientEx();
ws.Encoding = Encoding.UTF8;
if (webProxy != null)
{
ws.Proxy = webProxy;
@@ -197,7 +199,7 @@ namespace v2rayN.Handler
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
WebClientEx ws = new WebClientEx();
ws.Encoding = Encoding.UTF8;
return ws.DownloadString(new Uri(url));
}
catch (Exception ex)

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using v2rayN.Mode;
using System.Linq;
namespace v2rayN.Handler
{
@@ -20,5 +22,34 @@ namespace v2rayN.Handler
{
return _config;
}
public List<string> GetShadowsocksSecuritys()
{
if (GetCoreType(null, EConfigType.Shadowsocks) == ECoreType.v2fly)
{
return Global.ssSecuritys;
}
return Global.ssSecuritysInXray;
}
public ECoreType GetCoreType(VmessItem vmessItem, EConfigType eConfigType)
{
if (vmessItem != null && vmessItem.coreType != null)
{
return (ECoreType)vmessItem.coreType;
}
if (_config.coreTypeItem == null)
{
return ECoreType.Xray;
}
var item = _config.coreTypeItem.FirstOrDefault(it => it.configType == eConfigType);
if (item == null)
{
return ECoreType.Xray;
}
return item.coreType;
}
}
}

View File

@@ -53,7 +53,7 @@ namespace v2rayN.Handler
if (!Utils.IsNullOrEmpty(item.customIcon) && File.Exists(item.customIcon))
{
graphics.FillRectangle(drawBrush, new Rectangle(0, 0, width, height));
graphics.DrawImage(new Bitmap(item.customIcon), 0, 0);
graphics.DrawImage(new Bitmap(item.customIcon), 0, 0, width, height);
customIcon = true;
}
}
@@ -159,29 +159,12 @@ namespace v2rayN.Handler
}
}
public int AddBatchServers(Config config, string clipboardData, string subid, string groupId)
{
List<VmessItem> lstOriSub = null;
if (!Utils.IsNullOrEmpty(subid))
{
lstOriSub = config.vmess.Where(it => it.subid == subid).ToList();
}
int counter = ConfigHandler.AddBatchServers(ref config, clipboardData, subid, lstOriSub, groupId);
if (counter < 1)
{
counter = ConfigHandler.AddBatchServers(ref config, Utils.Base64Decode(clipboardData), subid, lstOriSub, groupId);
}
return counter;
}
public void BackupGuiNConfig(Config config, bool auto = false)
{
string fileName = $"guiNConfig_{DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss_fff")}.json";
if (auto)
{
fileName = Utils.GetTempPath(fileName);
fileName = Utils.GetBackupPath(fileName);
}
else
{

View File

@@ -21,7 +21,7 @@ namespace v2rayN.Handler
_config = config;
}
public SpeedtestHandler(ref Config config, ref V2rayHandler v2rayHandler, List<VmessItem> selecteds, string actionType, Action<string, string> update)
public SpeedtestHandler(ref Config config, V2rayHandler v2rayHandler, List<VmessItem> selecteds, ESpeedActionType actionType, Action<string, string> update)
{
_config = config;
_v2rayHandler = v2rayHandler;
@@ -40,19 +40,19 @@ namespace v2rayN.Handler
});
}
if (actionType == "ping")
if (actionType == ESpeedActionType.Ping)
{
Task.Run(() => RunPing());
}
if (actionType == "tcping")
else if (actionType == ESpeedActionType.Tcping)
{
Task.Run(() => RunTcping());
}
else if (actionType == "realping")
else if (actionType == ESpeedActionType.Realping)
{
Task.Run(() => RunRealPing());
}
else if (actionType == "speedtest")
else if (actionType == ESpeedActionType.Speedtest)
{
Task.Run(() => RunSpeedTest());
}

View File

@@ -182,7 +182,7 @@ namespace v2rayN.Handler
string url = config.subItem[k - 1].url.TrimEx();
string userAgent = config.subItem[k - 1].userAgent.TrimEx();
string groupId = config.subItem[k - 1].groupId.TrimEx();
string hashCode = $"{k}->";
string hashCode = $"{k}){config.subItem[k - 1].remarks}->";
if (config.subItem[k - 1].enabled == false)
{
continue;
@@ -210,7 +210,7 @@ namespace v2rayN.Handler
//ConfigHandler.RemoveServerViaSubid(ref config, id);
//_updateFunc(false, $"{hashCode}{UIRes.I18N("MsgClearSubscription")}");
// RefreshServers();
int ret = MainFormHandler.Instance.AddBatchServers(config, result, id, groupId);
int ret = ConfigHandler.AddBatchServers(ref config, result, id, groupId);
if (ret > 0)
{
// RefreshServers();

View File

@@ -400,7 +400,7 @@ namespace v2rayN.Handler
serversItem.address = node.address;
serversItem.port = node.port;
serversItem.password = node.id;
if (config.GetShadowsocksSecuritys().Contains(node.security))
if (LazyConfig.Instance.GetShadowsocksSecuritys().Contains(node.security))
{
serversItem.method = node.security;
}
@@ -912,7 +912,7 @@ namespace v2rayN.Handler
string addressFileName = node.address;
if (!File.Exists(addressFileName))
{
addressFileName = Path.Combine(Utils.GetTempPath(), addressFileName);
addressFileName = Path.Combine(Utils.GetConfigPath(), addressFileName);
}
if (!File.Exists(addressFileName))
{
@@ -921,10 +921,33 @@ namespace v2rayN.Handler
}
File.Copy(addressFileName, fileName);
//check again
if (!File.Exists(fileName))
{
msg = UIRes.I18N("FailedGenDefaultConfiguration");
return -1;
}
//overwrite port
var fileContent = File.ReadAllLines(fileName).ToList();
var coreType = LazyConfig.Instance.GetCoreType(node, node.configType);
switch (coreType)
{
case ECoreType.v2fly:
case ECoreType.Xray:
break;
case ECoreType.clash:
fileContent.Add($"port: {LazyConfig.Instance.GetConfig().GetLocalPort(Global.InboundHttp)}");
fileContent.Add($"socks-port: {LazyConfig.Instance.GetConfig().GetLocalPort(Global.InboundSocks)}");
break;
}
File.WriteAllLines(fileName, fileContent);
msg = string.Format(UIRes.I18N("SuccessfulConfiguration"), $"[{LazyConfig.Instance.GetConfig().GetGroupRemarks(node.groupId)}] {node.GetSummary()}");
}
catch
catch (Exception ex)
{
Utils.SaveLog("GenerateClientCustomConfig", ex);
msg = UIRes.I18N("FailedGenDefaultConfiguration");
return -1;
}

View File

@@ -21,8 +21,9 @@ namespace v2rayN.Handler
class V2rayHandler
{
private static string v2rayConfigRes = Global.v2rayConfigFileName;
private List<string> lstV2ray;
private List<string> lstCore;
private string coreUrl;
private string coreArguments;
public event ProcessDelegate ProcessEvent;
//private int processId = 0;
private Process _process;
@@ -39,6 +40,12 @@ namespace v2rayN.Handler
if (Global.reloadV2ray)
{
var item = ConfigHandler.GetDefaultServer(ref config);
if (item == null)
{
ShowMsg(false, UIRes.I18N("CheckServerSettings"));
return;
}
SetCore(config, item);
string fileName = Utils.GetPath(v2rayConfigRes);
if (V2rayConfigHandler.GenerateClientConfig(item, fileName, false, out string msg) != 0)
@@ -99,7 +106,7 @@ namespace v2rayN.Handler
}
else
{
foreach (string vName in lstV2ray)
foreach (string vName in lstCore)
{
Process[] existing = Process.GetProcessesByName(vName);
foreach (Process p in existing)
@@ -156,12 +163,10 @@ namespace v2rayN.Handler
}
}
private string V2rayFindexe()
private string V2rayFindexe(List<string> lstCoreTemp)
{
//查找v2ray文件是否存在
string fileName = string.Empty;
//lstV2ray.Reverse();
foreach (string name in lstV2ray)
foreach (string name in lstCoreTemp)
{
string vName = string.Format("{0}.exe", name);
vName = Utils.GetPath(vName);
@@ -188,7 +193,7 @@ namespace v2rayN.Handler
try
{
string fileName = V2rayFindexe();
string fileName = V2rayFindexe(lstCore);
if (fileName == "") return;
Process p = new Process
@@ -196,6 +201,7 @@ namespace v2rayN.Handler
StartInfo = new ProcessStartInfo
{
FileName = fileName,
Arguments = coreArguments,
WorkingDirectory = Utils.StartupPath(),
UseShellExecute = false,
RedirectStandardOutput = true,
@@ -241,7 +247,8 @@ namespace v2rayN.Handler
try
{
string fileName = V2rayFindexe();
coreUrl = Global.xrayCoreUrl;
string fileName = V2rayFindexe(new List<string> { "xray" });
if (fileName == "") return -1;
Process p = new Process
@@ -320,28 +327,41 @@ namespace v2rayN.Handler
private void SetCore(Config config, VmessItem item)
{
var coreType = config.GetCoreType(item.configType);
if (item.coreType != null)
if (item == null)
{
coreType = (ECoreType)item.coreType;
return;
}
var coreType = LazyConfig.Instance.GetCoreType(item, item.configType);
if (coreType == ECoreType.v2fly)
{
lstV2ray = new List<string>
lstCore = new List<string>
{
"wv2ray",
"v2ray"
};
coreUrl = Global.v2flyCoreUrl;
coreArguments = string.Empty;
}
else
else if (coreType == ECoreType.Xray)
{
lstV2ray = new List<string>
lstCore = new List<string>
{
"xray"
};
coreUrl = Global.xrayCoreUrl;
coreArguments = string.Empty;
}
else if (coreType == ECoreType.clash)
{
lstCore = new List<string>
{
"clash-windows-amd64",
"clash-windows-386",
"clash"
};
coreUrl = Global.clashCoreUrl;
coreArguments = "-f config.json";
}
}
}

View File

@@ -256,16 +256,6 @@ namespace v2rayN.Mode
return vmess.FirstOrDefault(it => it.indexId == id);
}
public List<string> GetShadowsocksSecuritys()
{
if (GetCoreType(EConfigType.Shadowsocks) == ECoreType.v2fly)
{
return Global.ssSecuritys;
}
return Global.ssSecuritysInXray;
}
public bool IsActiveNode(VmessItem item)
{
if (!Utils.IsNullOrEmpty(item.indexId) && item.indexId == indexId)
@@ -285,19 +275,6 @@ namespace v2rayN.Mode
return groupItem.Where(it => it.id == groupId).FirstOrDefault()?.remarks;
}
public ECoreType GetCoreType(EConfigType eConfigType)
{
if (coreTypeItem == null)
{
return ECoreType.v2fly;
}
var item = coreTypeItem.FirstOrDefault(it => it.configType == eConfigType);
if (item == null)
{
return ECoreType.v2fly;
}
return item.coreType;
}
#endregion
}
@@ -358,7 +335,7 @@ namespace v2rayN.Mode
break;
default:
summary += string.Format("{0}", remarks);
break;
break;
}
return summary;
}

View File

@@ -4,6 +4,7 @@ namespace v2rayN.Mode
public enum ECoreType
{
v2fly = 1,
Xray = 2
Xray = 2,
clash = 3
}
}

View File

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

namespace v2rayN.Mode
{
public enum ESpeedActionType
{
Ping,
Tcping,
Realping,
Speedtest
}
}

View File

@@ -32,4 +32,4 @@ using System.Runtime.InteropServices;
// 方法是按如下所示使用“*”:
//[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyVersion("1.0.0")]
[assembly: AssemblyFileVersion("5.3")]
[assembly: AssemblyFileVersion("5.6")]

View File

@@ -115,7 +115,7 @@ namespace v2rayN.Resx {
}
/// <summary>
/// 查找类似 Note that custom configuration relies entirely on your own configuration and does not work with all settings. The system agent is available when the socks port is equal to the port in the settings in the custom configuration inbound. 的本地化字符串。
/// 查找类似 Note that custom configuration relies entirely on your own configuration and does not work with all settings. If you want to use the system proxy, please modify the listening port manually. 的本地化字符串。
/// </summary>
internal static string CustomServerTips {
get {

View File

@@ -130,7 +130,7 @@
<value> configuration format is incorrect</value>
</data>
<data name="CustomServerTips" xml:space="preserve">
<value>Note that custom configuration relies entirely on your own configuration and does not work with all settings. The system agent is available when the socks port is equal to the port in the settings in the custom configuration inbound.</value>
<value>Note that custom configuration relies entirely on your own configuration and does not work with all settings. If you want to use the system proxy, please modify the listening port manually.</value>
</data>
<data name="Downloading" xml:space="preserve">
<value>Downloading...</value>

View File

@@ -130,7 +130,7 @@
<value>配置格式不正确</value>
</data>
<data name="CustomServerTips" xml:space="preserve">
<value>注意,自定义配置完全依赖您自己的配置,不能使用所有设置功能。在自定义配置inbound中有socks port等于设置中的port时系统代理才可用</value>
<value>注意,自定义配置完全依赖您自己的配置,不能使用所有设置功能。如需使用系统代理请手工修改监听端口。</value>
</data>
<data name="Downloading" xml:space="preserve">
<value>下载开始...</value>

View File

@@ -943,19 +943,21 @@ namespace v2rayN
#region TempPath
// return path to store temporary files
public static string GetTempPath()
public static string GetTempPath(string filename = "")
{
string _tempPath = Path.Combine(StartupPath(), "v2ray_win_temp");
if (!Directory.Exists(_tempPath))
{
Directory.CreateDirectory(_tempPath);
}
return _tempPath;
}
public static string GetTempPath(string filename)
{
return Path.Combine(GetTempPath(), filename);
if (string.IsNullOrEmpty(filename))
{
return _tempPath;
}
else
{
return Path.Combine(_tempPath, filename);
}
}
public static string UnGzip(byte[] buf)
@@ -970,6 +972,32 @@ namespace v2rayN
return Encoding.UTF8.GetString(sb.ToArray());
}
public static string GetBackupPath(string filename)
{
string _tempPath = Path.Combine(StartupPath(), "guiBackups");
if (!Directory.Exists(_tempPath))
{
Directory.CreateDirectory(_tempPath);
}
return Path.Combine(_tempPath, filename);
}
public static string GetConfigPath(string filename = "")
{
string _tempPath = Path.Combine(StartupPath(), "guiConfigs");
if (!Directory.Exists(_tempPath))
{
Directory.CreateDirectory(_tempPath);
}
if (string.IsNullOrEmpty(filename))
{
return _tempPath;
}
else
{
return Path.Combine(_tempPath, filename);
}
}
#endregion
#region Log

View File

@@ -199,6 +199,7 @@
<SubType>Component</SubType>
</Compile>
<Compile Include="Handler\SysProxyHandle.cs" />
<Compile Include="Mode\ESpeedActionType.cs" />
<Compile Include="Mode\EGlobalHotkey.cs" />
<Compile Include="Mode\ECoreType.cs" />
<Compile Include="Mode\ESysProxyType.cs" />