diff --git a/v2rayN/v2rayN/Forms/AddServer2Form.cs b/v2rayN/v2rayN/Forms/AddServer2Form.cs index f19794f2..adc881a4 100644 --- a/v2rayN/v2rayN/Forms/AddServer2Form.cs +++ b/v2rayN/v2rayN/Forms/AddServer2Form.cs @@ -128,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")); @@ -148,7 +148,7 @@ namespace v2rayN.Forms return; } - address = Path.Combine(Utils.GetTempPath(), address); + address = Path.Combine(Utils.GetConfigPath(), address); Process.Start(address); } } diff --git a/v2rayN/v2rayN/Forms/MainForm.cs b/v2rayN/v2rayN/Forms/MainForm.cs index 30b959e2..6f325a62 100644 --- a/v2rayN/v2rayN/Forms/MainForm.cs +++ b/v2rayN/v2rayN/Forms/MainForm.cs @@ -586,7 +586,7 @@ namespace v2rayN.Forms else { fm = new AddServerForm(); - } + } fm.vmessItem = index >= 0 ? lstVmess[index] : null; fm.groupId = groupId; fm.eConfigType = configType; @@ -688,8 +688,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)); @@ -964,7 +963,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 +993,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(); diff --git a/v2rayN/v2rayN/Forms/OptionSettingForm.cs b/v2rayN/v2rayN/Forms/OptionSettingForm.cs index 33a5c1b8..6268daf7 100644 --- a/v2rayN/v2rayN/Forms/OptionSettingForm.cs +++ b/v2rayN/v2rayN/Forms/OptionSettingForm.cs @@ -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++) diff --git a/v2rayN/v2rayN/Handler/ConfigHandler.cs b/v2rayN/v2rayN/Handler/ConfigHandler.cs index b196fc1f..631f2bc3 100644 --- a/v2rayN/v2rayN/Handler/ConfigHandler.cs +++ b/v2rayN/v2rayN/Handler/ConfigHandler.cs @@ -184,6 +184,28 @@ namespace v2rayN.Handler LazyConfig.Instance.SetConfig(ref config); return 0; } + /// + /// 保参数 + /// + /// + /// + public static int SaveConfig(ref Config config, bool reload = true) + { + Global.reloadV2ray = reload; + + ToJsonFile(config); + + return 0; + } + + /// + /// 存储文件 + /// + /// + 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]; } - /// - /// 保参数 - /// - /// - /// - public static int SaveConfig(ref Config config, bool reload = true) - { - Global.reloadV2ray = reload; - - ToJsonFile(config); - - return 0; - } - - /// - /// 存储文件 - /// - /// - private static void ToJsonFile(Config config) - { - Utils.ToJsonFile(config, Utils.GetPath(configRes)); - } - /// /// 移动服务器 /// @@ -423,7 +422,7 @@ namespace v2rayN.Handler /// /// /// - public static int AddCustomServer(ref Config config, VmessItem vmessItem) + public static int AddCustomServer(ref Config config, VmessItem vmessItem, bool blDelete) { var fileName = vmessItem.address; if (!File.Exists(fileName)) @@ -436,7 +435,11 @@ namespace v2rayN.Handler try { - File.Copy(fileName, Path.Combine(Utils.GetTempPath(), newFileName)); + File.Copy(fileName, Path.Combine(Utils.GetConfigPath(), newFileName)); + if (blDelete) + { + File.Delete(fileName); + } } catch { @@ -522,7 +525,6 @@ namespace v2rayN.Handler return 0; } - /// /// 添加服务器或编辑 /// @@ -619,178 +621,6 @@ namespace v2rayN.Handler return 0; } - /// - /// 批量添加服务器 - /// - /// - /// - /// - /// 成功导入的数量 - public static int AddBatchServers(ref Config config, string clipboardData, string subid, List 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; - } - - /// - /// add sub - /// - /// - /// - /// - 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); - } - - /// - /// save sub - /// - /// - /// - 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; - } - - /// - /// 移除服务器 - /// - /// - /// - /// - 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 lstVmess, EServerColName name, bool asc) { if (lstVmess.Count <= 0) @@ -884,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) @@ -949,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 + + /// + /// 批量添加服务器 + /// + /// + /// + /// + /// 成功导入的数量 + private static int AddBatchServers(ref Config config, string clipboardData, string subid, List 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 lstOriSub, string groupId) + { + if (Utils.IsNullOrEmpty(clipboardData)) + { + return -1; + } + + VmessItem vmessItem = new VmessItem(); + //Is v2ray configuration + V2rayConfig v2rayConfig = Utils.FromJson(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 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 + + /// + /// add sub + /// + /// + /// + /// + 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); + } + + /// + /// save sub + /// + /// + /// + 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; + } + + /// + /// 移除服务器 + /// + /// + /// + /// + 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; + } + + /// /// save Group /// @@ -999,6 +1114,8 @@ namespace v2rayN.Handler ToJsonFile(config); return 0; } + + #endregion #region UI diff --git a/v2rayN/v2rayN/Handler/DownloadHandle.cs b/v2rayN/v2rayN/Handler/DownloadHandle.cs index 2a1778ff..0bc47214 100644 --- a/v2rayN/v2rayN/Handler/DownloadHandle.cs +++ b/v2rayN/v2rayN/Handler/DownloadHandle.cs @@ -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) diff --git a/v2rayN/v2rayN/Handler/MainFormHandler.cs b/v2rayN/v2rayN/Handler/MainFormHandler.cs index 1661bbd2..7da72180 100644 --- a/v2rayN/v2rayN/Handler/MainFormHandler.cs +++ b/v2rayN/v2rayN/Handler/MainFormHandler.cs @@ -159,29 +159,12 @@ namespace v2rayN.Handler } } - public int AddBatchServers(Config config, string clipboardData, string subid, string groupId) - { - List 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 { diff --git a/v2rayN/v2rayN/Handler/UpdateHandle.cs b/v2rayN/v2rayN/Handler/UpdateHandle.cs index 5d005685..5b280883 100644 --- a/v2rayN/v2rayN/Handler/UpdateHandle.cs +++ b/v2rayN/v2rayN/Handler/UpdateHandle.cs @@ -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(); diff --git a/v2rayN/v2rayN/Handler/V2rayConfigHandler.cs b/v2rayN/v2rayN/Handler/V2rayConfigHandler.cs index dae03c68..1e299c9e 100644 --- a/v2rayN/v2rayN/Handler/V2rayConfigHandler.cs +++ b/v2rayN/v2rayN/Handler/V2rayConfigHandler.cs @@ -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)) { diff --git a/v2rayN/v2rayN/Mode/Config.cs b/v2rayN/v2rayN/Mode/Config.cs index d8ccb076..f158768b 100644 --- a/v2rayN/v2rayN/Mode/Config.cs +++ b/v2rayN/v2rayN/Mode/Config.cs @@ -289,12 +289,12 @@ namespace v2rayN.Mode { if (coreTypeItem == null) { - return ECoreType.v2fly; + return ECoreType.Xray; } var item = coreTypeItem.FirstOrDefault(it => it.configType == eConfigType); if (item == null) { - return ECoreType.v2fly; + return ECoreType.Xray; } return item.coreType; } diff --git a/v2rayN/v2rayN/Tool/Utils.cs b/v2rayN/v2rayN/Tool/Utils.cs index f0f3076d..49384694 100644 --- a/v2rayN/v2rayN/Tool/Utils.cs +++ b/v2rayN/v2rayN/Tool/Utils.cs @@ -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