diff --git a/v2rayN/Directory.Build.props b/v2rayN/Directory.Build.props index 499e349f..946d141a 100644 --- a/v2rayN/Directory.Build.props +++ b/v2rayN/Directory.Build.props @@ -1,7 +1,7 @@ - 7.11.0 + 7.11.1 diff --git a/v2rayN/ServiceLib/Common/AesUtils.cs b/v2rayN/ServiceLib/Common/AesUtils.cs index c32c3bff..05f1cb38 100644 --- a/v2rayN/ServiceLib/Common/AesUtils.cs +++ b/v2rayN/ServiceLib/Common/AesUtils.cs @@ -8,7 +8,7 @@ public class AesUtils private const int KeySize = 256; // AES-256 private const int IvSize = 16; // AES block size private const int Iterations = 10000; - private static readonly byte[] Salt = Encoding.ASCII.GetBytes("saltysalt".PadRight(16, ' ')); // google浏览器默认盐值 + private static readonly byte[] Salt = Encoding.ASCII.GetBytes("saltysalt".PadRight(16, ' ')); private static readonly string DefaultPassword = Utils.GetMd5(Utils.GetHomePath() + "AesUtils"); /// diff --git a/v2rayN/ServiceLib/Common/JsonUtils.cs b/v2rayN/ServiceLib/Common/JsonUtils.cs index 9ffa00ca..773ba79c 100644 --- a/v2rayN/ServiceLib/Common/JsonUtils.cs +++ b/v2rayN/ServiceLib/Common/JsonUtils.cs @@ -1,3 +1,4 @@ +using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; @@ -86,7 +87,8 @@ public class JsonUtils var options = new JsonSerializerOptions { WriteIndented = indented, - DefaultIgnoreCondition = nullValue ? JsonIgnoreCondition.Never : JsonIgnoreCondition.WhenWritingNull + DefaultIgnoreCondition = nullValue ? JsonIgnoreCondition.Never : JsonIgnoreCondition.WhenWritingNull, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }; result = JsonSerializer.Serialize(obj, options); } diff --git a/v2rayN/ServiceLib/Common/YamlUtils.cs b/v2rayN/ServiceLib/Common/YamlUtils.cs index e9be015f..a95e1b0a 100644 --- a/v2rayN/ServiceLib/Common/YamlUtils.cs +++ b/v2rayN/ServiceLib/Common/YamlUtils.cs @@ -11,7 +11,7 @@ public class YamlUtils #region YAML /// - /// 反序列化成对象 + /// Deserialize /// /// /// @@ -34,7 +34,7 @@ public class YamlUtils } /// - /// 序列化 + /// Serialize /// /// /// diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs index 50b2cd2e..78459920 100644 --- a/v2rayN/ServiceLib/Global.cs +++ b/v2rayN/ServiceLib/Global.cs @@ -125,7 +125,7 @@ public class Global [ "", @"https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/{0}.dat", - @"https://cdn.jsdelivr.net/gh/chocolate4u/Iran-v2ray-rules@release/{0}.dat" + @"https://github.com/Chocolate4U/Iran-v2ray-rules/releases/latest/download/{0}.dat" ]; public static readonly List SingboxRulesetSources = diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs index 03a0d9a5..a23b1c67 100644 --- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs +++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs @@ -3,9 +3,6 @@ using System.Text.RegularExpressions; namespace ServiceLib.Handler; -/// -/// 本软件配置文件处理类 -/// public class ConfigHandler { private static readonly string _configRes = Global.ConfigFileName; @@ -14,10 +11,12 @@ public class ConfigHandler #region ConfigHandler /// - /// 载入配置文件 + /// Load the application configuration file + /// If the file exists, deserialize it from JSON + /// If not found, create a new Config object with default settings + /// Initialize default values for missing configuration sections /// - /// - /// + /// Config object containing application settings or null if there's an error public static Config? LoadConfig() { Config? config = null; @@ -169,10 +168,11 @@ public class ConfigHandler } /// - /// 保参数 + /// Save the configuration to a file + /// First writes to a temporary file, then replaces the original file /// - /// - /// + /// Configuration object to be saved + /// 0 if successful, -1 if failed public static async Task SaveConfig(Config config) { try @@ -204,6 +204,13 @@ public class ConfigHandler #region Server + /// + /// Add a server profile to the configuration + /// Dispatches the request to the appropriate method based on the config type + /// + /// Current configuration + /// Server profile to add + /// Result of the operation (0 if successful, -1 if failed) public static async Task AddServer(Config config, ProfileItem profileItem) { var item = await AppHandler.Instance.GetProfileItem(profileItem.IndexId); @@ -258,11 +265,13 @@ public class ConfigHandler } /// - /// Add or edit server + /// Add or edit a VMess server + /// Validates and processes VMess-specific settings /// - /// - /// - /// + /// Current configuration + /// VMess profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed public static async Task AddVMessServer(Config config, ProfileItem profileItem, bool toFile = true) { profileItem.ConfigType = EConfigType.VMess; @@ -291,11 +300,11 @@ public class ConfigHandler } /// - /// 移除服务器 + /// Remove multiple servers from the configuration /// - /// - /// - /// + /// Current configuration + /// List of server profiles to remove + /// 0 if successful public static async Task RemoveServers(Config config, List indexes) { var subid = "TempRemoveSubId"; @@ -311,11 +320,12 @@ public class ConfigHandler } /// - /// 克隆服务器 + /// Clone server profiles + /// Creates copies of the specified server profiles with "-clone" appended to the remarks /// - /// - /// - /// + /// Current configuration + /// List of server profiles to clone + /// 0 if successful public static async Task CopyServer(Config config, List indexes) { foreach (var it in indexes) @@ -347,11 +357,12 @@ public class ConfigHandler } /// - /// 设置活动服务器 + /// Set the default server by its index ID + /// Updates the configuration to use the specified server as default /// - /// - /// - /// + /// Current configuration + /// Index ID of the server to set as default + /// 0 if successful, -1 if failed public static async Task SetDefaultServerIndex(Config config, string? indexId) { if (indexId.IsNullOrEmpty()) @@ -366,6 +377,13 @@ public class ConfigHandler return 0; } + /// + /// Set a default server from the provided list of profiles + /// Ensures there's always a valid default server selected + /// + /// Current configuration + /// List of profile models to choose from + /// Result of SetDefaultServerIndex operation public static async Task SetDefaultServer(Config config, List lstProfile) { if (lstProfile.Exists(t => t.IndexId == config.IndexId)) @@ -386,6 +404,12 @@ public class ConfigHandler return await SetDefaultServerIndex(config, item?.IndexId); } + /// + /// Get the current default server profile + /// If the current default is invalid, selects a new default + /// + /// Current configuration + /// The default profile item or null if none exists public static async Task GetDefaultServer(Config config) { var item = await AppHandler.Instance.GetProfileItem(config.IndexId); @@ -400,13 +424,15 @@ public class ConfigHandler } /// - /// 移动服务器 + /// Move a server in the list to a different position + /// Supports moving to top, up, down, bottom or specific position /// - /// - /// - /// - /// - /// + /// Current configuration + /// List of server profiles + /// Index of the server to move + /// Direction to move the server + /// Target position when using EMove.Position + /// 0 if successful, -1 if failed public static async Task MoveServer(Config config, List lstProfile, int index, EMove eMove, int pos = -1) { int count = lstProfile.Count; @@ -474,11 +500,13 @@ public class ConfigHandler } /// - /// 添加自定义服务器 + /// Add a custom server configuration from a file + /// Copies the configuration file to the app's config directory /// - /// - /// - /// + /// Current configuration + /// Profile item with the file path in Address + /// Whether to delete the source file after copying + /// 0 if successful, -1 if failed public static async Task AddCustomServer(Config config, ProfileItem profileItem, bool blDelete) { var fileName = profileItem.Address; @@ -517,11 +545,12 @@ public class ConfigHandler } /// - /// Add or edit server + /// Edit an existing custom server configuration + /// Updates the server's properties without changing the file /// - /// - /// - /// + /// Current configuration + /// Profile item with updated properties + /// 0 if successful, -1 if failed public static async Task EditCustomServer(Config config, ProfileItem profileItem) { var item = await AppHandler.Instance.GetProfileItem(profileItem.IndexId); @@ -551,11 +580,13 @@ public class ConfigHandler } /// - /// Add or edit server + /// Add or edit a Shadowsocks server + /// Validates and processes Shadowsocks-specific settings /// - /// - /// - /// + /// Current configuration + /// Shadowsocks profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed public static async Task AddShadowsocksServer(Config config, ProfileItem profileItem, bool toFile = true) { profileItem.ConfigType = EConfigType.Shadowsocks; @@ -579,11 +610,13 @@ public class ConfigHandler } /// - /// Add or edit server + /// Add or edit a SOCKS server + /// Processes SOCKS-specific settings /// - /// - /// - /// + /// Current configuration + /// SOCKS profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed public static async Task AddSocksServer(Config config, ProfileItem profileItem, bool toFile = true) { profileItem.ConfigType = EConfigType.SOCKS; @@ -596,11 +629,13 @@ public class ConfigHandler } /// - /// Add or edit server + /// Add or edit an HTTP server + /// Processes HTTP-specific settings /// - /// - /// - /// + /// Current configuration + /// HTTP profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed public static async Task AddHttpServer(Config config, ProfileItem profileItem, bool toFile = true) { profileItem.ConfigType = EConfigType.HTTP; @@ -613,11 +648,13 @@ public class ConfigHandler } /// - /// Add or edit server + /// Add or edit a Trojan server + /// Validates and processes Trojan-specific settings /// - /// - /// - /// + /// Current configuration + /// Trojan profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed public static async Task AddTrojanServer(Config config, ProfileItem profileItem, bool toFile = true) { profileItem.ConfigType = EConfigType.Trojan; @@ -639,11 +676,14 @@ public class ConfigHandler } /// - /// Add or edit server + /// Add or edit a Hysteria2 server + /// Validates and processes Hysteria2-specific settings + /// Sets the core type to sing_box as required by Hysteria2 /// - /// - /// - /// + /// Current configuration + /// Hysteria2 profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed public static async Task AddHysteria2Server(Config config, ProfileItem profileItem, bool toFile = true) { profileItem.ConfigType = EConfigType.Hysteria2; @@ -669,11 +709,14 @@ public class ConfigHandler } /// - /// Add or edit server + /// Add or edit a TUIC server + /// Validates and processes TUIC-specific settings + /// Sets the core type to sing_box as required by TUIC /// - /// - /// - /// + /// Current configuration + /// TUIC profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed public static async Task AddTuicServer(Config config, ProfileItem profileItem, bool toFile = true) { profileItem.ConfigType = EConfigType.TUIC; @@ -708,15 +751,16 @@ public class ConfigHandler } /// - /// Add or edit server + /// Add or edit a WireGuard server + /// Validates and processes WireGuard-specific settings /// - /// - /// - /// + /// Current configuration + /// WireGuard profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed public static async Task AddWireguardServer(Config config, ProfileItem profileItem, bool toFile = true) { profileItem.ConfigType = EConfigType.WireGuard; - profileItem.CoreType = ECoreType.sing_box; profileItem.Address = profileItem.Address.TrimEx(); profileItem.Id = profileItem.Id.TrimEx(); @@ -739,6 +783,15 @@ public class ConfigHandler return 0; } + /// + /// Sort the server list by the specified column + /// Updates the sort order in the profile extension data + /// + /// Current configuration + /// Subscription ID to filter servers + /// Column name to sort by + /// Sort in ascending order if true, descending if false + /// 0 if successful, -1 if failed public static async Task SortServers(Config config, string subId, string colName, bool asc) { var lstModel = await AppHandler.Instance.ProfileItems(subId, ""); @@ -832,11 +885,13 @@ public class ConfigHandler } /// - /// Add or edit server + /// Add or edit a VLESS server + /// Validates and processes VLESS-specific settings /// - /// - /// - /// + /// Current configuration + /// VLESS profile to add + /// Whether to save to file + /// 0 if successful, -1 if failed public static async Task AddVlessServer(Config config, ProfileItem profileItem, bool toFile = true) { profileItem.ConfigType = EConfigType.VLESS; @@ -868,6 +923,13 @@ public class ConfigHandler return 0; } + /// + /// Remove duplicate servers from a subscription + /// Compares servers based on their properties rather than just names + /// + /// Current configuration + /// Subscription ID to deduplicate + /// Tuple with total count and remaining count after deduplication public static async Task> DedupServerList(Config config, string subId) { var lstProfile = await AppHandler.Instance.ProfileItems(subId); @@ -899,6 +961,14 @@ public class ConfigHandler return new Tuple(lstProfile.Count, lstKeep.Count); } + /// + /// Common server addition logic used by all server types + /// Sets common properties and handles sorting and persistence + /// + /// Current configuration + /// Profile item to add + /// Whether to save to database + /// 0 if successful public static async Task AddServerCommon(Config config, ProfileItem profileItem, bool toFile = true) { profileItem.ConfigVersion = 2; @@ -950,6 +1020,14 @@ public class ConfigHandler return 0; } + /// + /// Compare two profile items to determine if they represent the same server + /// Used for deduplication and server matching + /// + /// First profile item + /// Second profile item + /// Whether to compare remarks + /// True if the profiles match, false otherwise private static bool CompareProfileItem(ProfileItem? o, ProfileItem? n, bool remarks) { if (o == null || n == null) @@ -981,6 +1059,13 @@ public class ConfigHandler } } + /// + /// Remove a single server profile by its index ID + /// Deletes the configuration file if it's a custom config + /// + /// Current configuration + /// Index ID of the profile to remove + /// 0 if successful private static async Task RemoveProfileItem(Config config, string indexId) { try @@ -1005,6 +1090,15 @@ public class ConfigHandler return 0; } + /// + /// Create a custom server that combines multiple servers for load balancing + /// Generates a configuration file that references multiple servers + /// + /// Current configuration + /// Selected servers to combine + /// Core type to use (Xray or sing_box) + /// Load balancing algorithm + /// Result object with success state and data public static async Task AddCustomServer4Multiple(Config config, List selecteds, ECoreType coreType, EMultipleLoad multipleLoad) { var indexId = Utils.GetMd5(Global.CoreMultipleLoadConfigFileName); @@ -1023,14 +1117,21 @@ public class ConfigHandler var profileItem = await AppHandler.Instance.GetProfileItem(indexId) ?? new(); profileItem.IndexId = indexId; - profileItem.Remarks = multipleLoad switch + if (coreType == ECoreType.Xray) { - EMultipleLoad.Random => ResUI.menuSetDefaultMultipleServerXrayRandom, - EMultipleLoad.RoundRobin => ResUI.menuSetDefaultMultipleServerXrayRoundRobin, - EMultipleLoad.LeastPing => ResUI.menuSetDefaultMultipleServerXrayLeastPing, - EMultipleLoad.LeastLoad => ResUI.menuSetDefaultMultipleServerXrayLeastLoad, - _ => ResUI.menuSetDefaultMultipleServerXrayRoundRobin, - }; + profileItem.Remarks = multipleLoad switch + { + EMultipleLoad.Random => ResUI.menuSetDefaultMultipleServerXrayRandom, + EMultipleLoad.RoundRobin => ResUI.menuSetDefaultMultipleServerXrayRoundRobin, + EMultipleLoad.LeastPing => ResUI.menuSetDefaultMultipleServerXrayLeastPing, + EMultipleLoad.LeastLoad => ResUI.menuSetDefaultMultipleServerXrayLeastLoad, + _ => ResUI.menuSetDefaultMultipleServerXrayRoundRobin, + }; + } + else if (coreType == ECoreType.sing_box) + { + profileItem.Remarks = ResUI.menuSetDefaultMultipleServerSingBoxLeastPing; + } profileItem.Address = Global.CoreMultipleLoadConfigFileName; profileItem.ConfigType = EConfigType.Custom; profileItem.CoreType = coreType; @@ -1041,6 +1142,14 @@ public class ConfigHandler return result; } + /// + /// Get a SOCKS server profile for pre-SOCKS functionality + /// Used when TUN mode is enabled or when a custom config has a pre-SOCKS port + /// + /// Current configuration + /// Server node that might need pre-SOCKS + /// Core type being used + /// A SOCKS profile item or null if not needed public static async Task GetPreSocksItem(Config config, ProfileItem node, ECoreType coreType) { ProfileItem? itemSocks = null; @@ -1070,6 +1179,13 @@ public class ConfigHandler return itemSocks; } + /// + /// Remove servers with invalid test results (timeout) + /// Useful for cleaning up subscription lists + /// + /// Current configuration + /// Subscription ID to filter servers + /// Number of removed servers or -1 if failed public static async Task RemoveInvalidServerResult(Config config, string subid) { var lstModel = await AppHandler.Instance.ProfileItems(subid, ""); @@ -1093,12 +1209,14 @@ public class ConfigHandler #region Batch add servers /// - /// 批量添加服务器 + /// Add multiple servers from string data (common protocols) + /// Parses the string data into server profiles /// - /// - /// - /// - /// 成功导入的数量 + /// Current configuration + /// String data containing server information + /// Subscription ID to associate with the servers + /// Whether this is from a subscription + /// Number of successfully imported servers or -1 if failed private static async Task AddBatchServersCommon(Config config, string strData, string subid, bool isSub) { if (strData.IsNullOrEmpty()) @@ -1178,6 +1296,15 @@ public class ConfigHandler return countServers; } + /// + /// Add servers from custom configuration formats (sing-box, v2ray, etc.) + /// Handles various configuration formats and imports them as custom configs + /// + /// Current configuration + /// String data containing server information + /// Subscription ID to associate with the servers + /// Whether this is from a subscription + /// Number of successfully imported servers or -1 if failed private static async Task AddBatchServers4Custom(Config config, string strData, string subid, bool isSub) { if (strData.IsNullOrEmpty()) @@ -1276,6 +1403,15 @@ public class ConfigHandler } } + /// + /// Add Shadowsocks servers from SIP008 format + /// SIP008 is a JSON-based format for Shadowsocks servers + /// + /// Current configuration + /// String data in SIP008 format + /// Subscription ID to associate with the servers + /// Whether this is from a subscription + /// Number of successfully imported servers or -1 if failed private static async Task AddBatchServers4SsSIP008(Config config, string strData, string subid, bool isSub) { if (strData.IsNullOrEmpty()) @@ -1308,6 +1444,15 @@ public class ConfigHandler return -1; } + /// + /// Main entry point for adding batch servers from various formats + /// Tries different parsing methods to import as many servers as possible + /// + /// Current configuration + /// String data containing server information + /// Subscription ID to associate with the servers + /// Whether this is from a subscription + /// Number of successfully imported servers or -1 if failed public static async Task AddBatchServers(Config config, string strData, string subid, bool isSub) { if (strData.IsNullOrEmpty()) @@ -1380,11 +1525,12 @@ public class ConfigHandler #region Sub & Group /// - /// add sub + /// Add a subscription item from URL + /// Creates a new subscription with default settings /// - /// - /// - /// + /// Current configuration + /// Subscription URL + /// 0 if successful, -1 if failed public static async Task AddSubItem(Config config, string url) { //already exists @@ -1416,6 +1562,12 @@ public class ConfigHandler return await AddSubItem(config, subItem); } + /// + /// Add or update a subscription item + /// + /// Current configuration + /// Subscription item to add or update + /// 0 if successful, -1 if failed public static async Task AddSubItem(Config config, SubItem subItem) { var item = await AppHandler.Instance.GetSubItem(subItem.Id); @@ -1467,11 +1619,12 @@ public class ConfigHandler } /// - /// 移除服务器 + /// Remove servers associated with a subscription ID /// - /// - /// - /// + /// Current configuration + /// Subscription ID + /// Whether to only remove servers marked as subscription items + /// 0 if successful, -1 if failed public static async Task RemoveServersViaSubid(Config config, string subid, bool isSub) { if (subid.IsNullOrEmpty()) @@ -1495,6 +1648,12 @@ public class ConfigHandler return 0; } + /// + /// Delete a subscription item and all its associated servers + /// + /// Current configuration + /// Subscription ID to delete + /// 0 if successful public static async Task DeleteSubItem(Config config, string id) { var item = await AppHandler.Instance.GetSubItem(id); @@ -1508,6 +1667,13 @@ public class ConfigHandler return 0; } + /// + /// Move servers to a different group (subscription) + /// + /// Current configuration + /// List of profiles to move + /// Target subscription ID + /// 0 if successful public static async Task MoveToGroup(Config config, List lstProfile, string subid) { foreach (var item in lstProfile) @@ -1523,6 +1689,12 @@ public class ConfigHandler #region Routing + /// + /// Save a routing item to the database + /// + /// Current configuration + /// Routing item to save + /// 0 if successful, -1 if failed public static async Task SaveRoutingItem(Config config, RoutingItem item) { if (item.Id.IsNullOrEmpty()) @@ -1541,11 +1713,11 @@ public class ConfigHandler } /// - /// AddBatchRoutingRules + /// Add multiple routing rules to a routing item /// - /// - /// - /// + /// Routing item to add rules to + /// JSON string containing rules data + /// 0 if successful, -1 if failed public static async Task AddBatchRoutingRules(RoutingItem routingItem, string strData) { if (strData.IsNullOrEmpty()) @@ -1582,12 +1754,14 @@ public class ConfigHandler } /// - /// MoveRoutingRule + /// Move a routing rule within a rules list + /// Supports moving to top, up, down, bottom or specific position /// - /// - /// - /// - /// + /// List of routing rules + /// Index of the rule to move + /// Direction to move the rule + /// Target position when using EMove.Position + /// 0 if successful, -1 if failed public static async Task MoveRoutingRule(List rules, int index, EMove eMove, int pos = -1) { int count = rules.Count; @@ -1658,6 +1832,12 @@ public class ConfigHandler return await Task.FromResult(0); } + /// + /// Set the default routing configuration + /// + /// Current configuration + /// Routing item to set as default + /// 0 if successful public static async Task SetDefaultRouting(Config config, RoutingItem routingItem) { if (await SQLiteHelper.Instance.TableAsync().Where(t => t.Id == routingItem.Id).CountAsync() > 0) @@ -1670,6 +1850,12 @@ public class ConfigHandler return 0; } + /// + /// Get the current default routing configuration + /// If no default is set, selects the first available routing item + /// + /// Current configuration + /// The default routing item public static async Task GetDefaultRouting(Config config) { var item = await AppHandler.Instance.GetRoutingItem(config.RoutingBasicItem.RoutingIndexId); @@ -1683,6 +1869,12 @@ public class ConfigHandler return item; } + /// + /// Initialize routing rules from built-in or external templates + /// + /// Current configuration + /// Whether to import advanced rules + /// 0 if successful public static async Task InitRouting(Config config, bool blImportAdvancedRules = false) { if (config.ConstItem.RouteRulesTemplateSourceUrl.IsNullOrEmpty()) @@ -1697,6 +1889,13 @@ public class ConfigHandler return 0; } + /// + /// Initialize routing rules from external templates + /// Downloads and processes routing templates from a URL + /// + /// Current configuration + /// Whether to import advanced rules + /// 0 if successful public static async Task InitExternalRouting(Config config, bool blImportAdvancedRules = false) { var downloadHandle = new DownloadService(); @@ -1745,6 +1944,13 @@ public class ConfigHandler return 0; } + /// + /// Initialize built-in routing rules + /// Creates default routing configurations (whitelist, blacklist, global) + /// + /// Current configuration + /// Whether to import advanced rules + /// 0 if successful public static async Task InitBuiltinRouting(Config config, bool blImportAdvancedRules = false) { var ver = "V3-"; @@ -1798,6 +2004,10 @@ public class ConfigHandler return 0; } + /// + /// Remove a routing item from the database + /// + /// Routing item to remove public static async Task RemoveRoutingItem(RoutingItem routingItem) { await SQLiteHelper.Instance.DeleteAsync(routingItem); @@ -1807,6 +2017,12 @@ public class ConfigHandler #region DNS + /// + /// Initialize built-in DNS configurations + /// Creates default DNS items for V2Ray and sing-box + /// + /// Current configuration + /// 0 if successful public static async Task InitBuiltinDNS(Config config) { var items = await AppHandler.Instance.DNSItems(); @@ -1830,6 +2046,12 @@ public class ConfigHandler return 0; } + /// + /// Save a DNS item to the database + /// + /// Current configuration + /// DNS item to save + /// 0 if successful, -1 if failed public static async Task SaveDNSItems(Config config, DNSItem item) { if (item == null) @@ -1852,6 +2074,13 @@ public class ConfigHandler } } + /// + /// Get an external DNS configuration from URL + /// Downloads and processes DNS templates + /// + /// Core type (Xray or sing-box) + /// URL of the DNS template + /// DNS item with configuration from the URL public static async Task GetExternalDNSItem(ECoreType type, string url) { var currentItem = await AppHandler.Instance.GetDNSItem(type); @@ -1883,6 +2112,13 @@ public class ConfigHandler #region Regional Presets + /// + /// Apply regional presets for geo-specific configurations + /// Sets up geo files, routing rules, and DNS for specific regions + /// + /// Current configuration + /// Type of preset (Default, Russia, Iran) + /// True if successful public static async Task ApplyRegionalPreset(Config config, EPresetType type) { switch (type) diff --git a/v2rayN/ServiceLib/Handler/CoreHandler.cs b/v2rayN/ServiceLib/Handler/CoreHandler.cs index c3535a4a..41ea866d 100644 --- a/v2rayN/ServiceLib/Handler/CoreHandler.cs +++ b/v2rayN/ServiceLib/Handler/CoreHandler.cs @@ -101,7 +101,7 @@ public class CoreHandler public async Task LoadCoreConfigSpeedtest(List selecteds) { - var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard) ? ECoreType.sing_box : ECoreType.Xray; + var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC) ? ECoreType.sing_box : ECoreType.Xray; var fileName = string.Format(Global.CoreSpeedtestConfigFileName, Utils.GetGuid(false)); var configPath = Utils.GetBinConfigPath(fileName); var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType); diff --git a/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs index 31b2e02d..86b92fa0 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs @@ -8,10 +8,13 @@ public class BaseFmt { if (Utils.IsIpv6(address)) { - // 检查地址是否已经被方括号包围,如果没有,则添加方括号 + // Check if the address is already surrounded by square brackets, if not, add square brackets return address.StartsWith('[') && address.EndsWith(']') ? address : $"[{address}]"; } - return address; // 如果不是IPv6地址,直接返回原地址 + else + { + return address; + } } protected static int GetStdTransport(ProfileItem item, string? securityDef, ref Dictionary dicQuery) diff --git a/v2rayN/ServiceLib/Models/Config.cs b/v2rayN/ServiceLib/Models/Config.cs index 7a1e423c..15996608 100644 --- a/v2rayN/ServiceLib/Models/Config.cs +++ b/v2rayN/ServiceLib/Models/Config.cs @@ -1,8 +1,5 @@ namespace ServiceLib.Models; -/// -/// 本软件配置文件实体类 -/// [Serializable] public class Config { diff --git a/v2rayN/ServiceLib/Models/V2rayConfig.cs b/v2rayN/ServiceLib/Models/V2rayConfig.cs index ca6636b7..d080d14c 100644 --- a/v2rayN/ServiceLib/Models/V2rayConfig.cs +++ b/v2rayN/ServiceLib/Models/V2rayConfig.cs @@ -127,6 +127,26 @@ public class Outboundsettings4Ray public int? userLevel { get; set; } public FragmentItem4Ray? fragment { get; set; } + + public string? secretKey { get; set; } + + public List? address { get; set; } + + public List? peers { get; set; } + + public bool? noKernelTun { get; set; } + + public int? mtu { get; set; } + + public List? reserved { get; set; } + + public int? workers { get; set; } +} + +public class WireguardPeer4Ray +{ + public string endpoint { get; set; } + public string publicKey { get; set; } } public class VnextItem4Ray diff --git a/v2rayN/ServiceLib/Models/V2rayTcpRequest.cs b/v2rayN/ServiceLib/Models/V2rayTcpRequest.cs index 07a31d3d..c08284b4 100644 --- a/v2rayN/ServiceLib/Models/V2rayTcpRequest.cs +++ b/v2rayN/ServiceLib/Models/V2rayTcpRequest.cs @@ -1,8 +1,5 @@ namespace ServiceLib.Models; -/// -/// Tcp伪装http的Request,只要Host -/// public class V2rayTcpRequest { /// diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index e3d7ff50..0b9cc936 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -88,7 +88,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Please check the server settings first. 的本地化字符串。 + /// 查找类似 Please check the Configuration settings first. 的本地化字符串。 /// public static string CheckServerSettings { get { @@ -178,7 +178,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Failed to import custom configuration server 的本地化字符串。 + /// 查找类似 Failed to import custom configuration Configuration 的本地化字符串。 /// public static string FailedImportedCustomServer { get { @@ -214,7 +214,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Please enter the correct server port format. 的本地化字符串。 + /// 查找类似 Please enter the correct port format. 的本地化字符串。 /// public static string FillCorrectServerPort { get { @@ -241,7 +241,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Please enter the server address. 的本地化字符串。 + /// 查找类似 Please enter the address. 的本地化字符串。 /// public static string FillServerAddress { get { @@ -250,7 +250,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Please browse to import server configuration 的本地化字符串。 + /// 查找类似 Please browse to import Configuration configuration 的本地化字符串。 /// public static string FillServerAddressCustom { get { @@ -466,7 +466,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Next proxy remarks 的本地化字符串。 + /// 查找类似 Next proxy Configuration remarks 的本地化字符串。 /// public static string LvNextProfile { get { @@ -484,7 +484,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Previous proxy remarks 的本地化字符串。 + /// 查找类似 Previous proxy Configuration remarks 的本地化字符串。 /// public static string LvPrevProfile { get { @@ -493,7 +493,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Please make sure the remarks exist and are unique 的本地化字符串。 + /// 查找类似 Please make sure the Configuration remarks exist and are unique 的本地化字符串。 /// public static string LvPrevProfileTip { get { @@ -673,7 +673,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Add a custom configuration server 的本地化字符串。 + /// 查找类似 Add a custom configuration Configuration 的本地化字符串。 /// public static string menuAddCustomServer { get { @@ -682,7 +682,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Add [HTTP] server 的本地化字符串。 + /// 查找类似 Add [HTTP] Configuration 的本地化字符串。 /// public static string menuAddHttpServer { get { @@ -691,7 +691,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Add [Hysteria2] server 的本地化字符串。 + /// 查找类似 Add [Hysteria2] Configuration 的本地化字符串。 /// public static string menuAddHysteria2Server { get { @@ -727,7 +727,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Add [Shadowsocks] server 的本地化字符串。 + /// 查找类似 Add [Shadowsocks] Configuration 的本地化字符串。 /// public static string menuAddShadowsocksServer { get { @@ -736,7 +736,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Add [SOCKS] server 的本地化字符串。 + /// 查找类似 Add [SOCKS] Configuration 的本地化字符串。 /// public static string menuAddSocksServer { get { @@ -745,7 +745,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Add [Trojan] server 的本地化字符串。 + /// 查找类似 Add [Trojan] Configuration 的本地化字符串。 /// public static string menuAddTrojanServer { get { @@ -754,7 +754,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Add [TUIC] server 的本地化字符串。 + /// 查找类似 Add [TUIC] Configuration 的本地化字符串。 /// public static string menuAddTuicServer { get { @@ -763,7 +763,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Add [VLESS] server 的本地化字符串。 + /// 查找类似 Add [VLESS] Configuration 的本地化字符串。 /// public static string menuAddVlessServer { get { @@ -772,7 +772,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Add [VMess] server 的本地化字符串。 + /// 查找类似 Add [VMess] Configuration 的本地化字符串。 /// public static string menuAddVmessServer { get { @@ -781,7 +781,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Add [WireGuard] server 的本地化字符串。 + /// 查找类似 Add [WireGuard] Configuration 的本地化字符串。 /// public static string menuAddWireguardServer { get { @@ -853,7 +853,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Clone selected server 的本地化字符串。 + /// 查找类似 Clone selected Configuration 的本地化字符串。 /// public static string menuCopyServer { get { @@ -871,7 +871,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Edit Server (Ctrl+D) 的本地化字符串。 + /// 查找类似 Edit Configuration (Ctrl+D) 的本地化字符串。 /// public static string menuEditServer { get { @@ -898,7 +898,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Export selected server for complete configuration 的本地化字符串。 + /// 查找类似 Export selected Configuration for complete configuration 的本地化字符串。 /// public static string menuExport2ClientConfig { get { @@ -907,7 +907,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Export selected server for complete configuration to clipboard 的本地化字符串。 + /// 查找类似 Export selected Configuration for complete configuration to clipboard 的本地化字符串。 /// public static string menuExport2ClientConfigClipboard { get { @@ -934,7 +934,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Export server 的本地化字符串。 + /// 查找类似 Export Configuration 的本地化字符串。 /// public static string menuExportConfig { get { @@ -1222,7 +1222,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Test servers real delay (Ctrl+R) 的本地化字符串。 + /// 查找类似 Test Configurations real delay (Ctrl+R) 的本地化字符串。 /// public static string menuRealPingServer { get { @@ -1312,7 +1312,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Remove duplicate servers 的本地化字符串。 + /// 查找类似 Remove duplicate Configurations 的本地化字符串。 /// public static string menuRemoveDuplicateServer { get { @@ -1330,7 +1330,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Remove selected servers (Delete) 的本地化字符串。 + /// 查找类似 Remove selected Configurations (Delete) 的本地化字符串。 /// public static string menuRemoveServer { get { @@ -1474,7 +1474,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Servers 的本地化字符串。 + /// 查找类似 Configurations 的本地化字符串。 /// public static string menuServers { get { @@ -1483,7 +1483,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Multi-server to custom configuration 的本地化字符串。 + /// 查找类似 Multi-Configuration to custom configuration 的本地化字符串。 /// public static string menuSetDefaultMultipleServer { get { @@ -1492,7 +1492,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Multi-server LeastPing by sing-box 的本地化字符串。 + /// 查找类似 Multi-Configuration LeastPing by sing-box 的本地化字符串。 /// public static string menuSetDefaultMultipleServerSingBoxLeastPing { get { @@ -1501,7 +1501,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Multi-server LeastLoad by Xray 的本地化字符串。 + /// 查找类似 Multi-Configuration LeastLoad by Xray 的本地化字符串。 /// public static string menuSetDefaultMultipleServerXrayLeastLoad { get { @@ -1510,7 +1510,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Multi-server LeastPing by Xray 的本地化字符串。 + /// 查找类似 Multi-Configuration LeastPing by Xray 的本地化字符串。 /// public static string menuSetDefaultMultipleServerXrayLeastPing { get { @@ -1519,7 +1519,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Multi-server Random by Xray 的本地化字符串。 + /// 查找类似 Multi-Configuration Random by Xray 的本地化字符串。 /// public static string menuSetDefaultMultipleServerXrayRandom { get { @@ -1528,7 +1528,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Multi-server RoundRobin by Xray 的本地化字符串。 + /// 查找类似 Multi-Configuration RoundRobin by Xray 的本地化字符串。 /// public static string menuSetDefaultMultipleServerXrayRoundRobin { get { @@ -1537,7 +1537,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Set as active server (Enter) 的本地化字符串。 + /// 查找类似 Set as active Configuration (Enter) 的本地化字符串。 /// public static string menuSetDefaultServer { get { @@ -1555,7 +1555,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Share Server (Ctrl+F) 的本地化字符串。 + /// 查找类似 Share Configuration (Ctrl+F) 的本地化字符串。 /// public static string menuShareServer { get { @@ -1582,7 +1582,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Test servers download speed (Ctrl+T) 的本地化字符串。 + /// 查找类似 Test Configurations download speed (Ctrl+T) 的本地化字符串。 /// public static string menuSpeedServer { get { @@ -1726,7 +1726,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Test servers with tcping (Ctrl+O) 的本地化字符串。 + /// 查找类似 Test Configurations with tcping (Ctrl+O) 的本地化字符串。 /// public static string menuTcpingServer { get { @@ -1834,7 +1834,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Server filter, press Enter to execute 的本地化字符串。 + /// 查找类似 Configuration filter, press Enter to execute 的本地化字符串。 /// public static string MsgServerTitle { get { @@ -2023,7 +2023,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Please select the server first 的本地化字符串。 + /// 查找类似 Please select the Configuration first 的本地化字符串。 /// public static string PleaseSelectServer { get { @@ -2050,7 +2050,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Servers deduplication completed. Old: {0}, New: {1}. 的本地化字符串。 + /// 查找类似 Configurations deduplication completed. Old: {0}, New: {1}. 的本地化字符串。 /// public static string RemoveDuplicateServerResult { get { @@ -2077,7 +2077,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Are you sure you want to remove the server? 的本地化字符串。 + /// 查找类似 Are you sure you want to remove the Configuration? 的本地化字符串。 /// public static string RemoveServer { get { @@ -2203,7 +2203,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Custom configuration server imported successfully 的本地化字符串。 + /// 查找类似 Custom configuration Configuration imported successfully 的本地化字符串。 /// public static string SuccessfullyImportedCustomServer { get { @@ -2212,7 +2212,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 {0} servers have been imported from clipboard 的本地化字符串。 + /// 查找类似 {0} Configurations have been imported from clipboard 的本地化字符串。 /// public static string SuccessfullyImportedServerViaClipboard { get { @@ -2581,7 +2581,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Server port range 的本地化字符串。 + /// 查找类似 Configuration port range 的本地化字符串。 /// public static string TbPorts7 { get { @@ -3040,7 +3040,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Double-clicking server makes it active 的本地化字符串。 + /// 查找类似 Double-clicking Configuration makes it active 的本地化字符串。 /// public static string TbSettingsDoubleClick2Activate { get { @@ -3076,7 +3076,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Enable sorting servers by drag-n-drop (requires restart) 的本地化字符串。 + /// 查找类似 Enable sorting Configurations by drag-n-drop (requires restart) 的本地化字符串。 /// public static string TbSettingsEnableDragDropSort { get { @@ -3526,7 +3526,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Tray right-click menu servers display limit 的本地化字符串。 + /// 查找类似 Tray right-click menu Configurations display limit 的本地化字符串。 /// public static string TbSettingsTrayMenuServersLimit { get { diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index 54a487f4..1fb3d23b 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -121,7 +121,7 @@ Export share link to clipboard successfully - Please check the server settings first. + Please check the Configuration settings first. Invalid configuration format. @@ -148,13 +148,13 @@ Failed to get the default configuration - Failed to import custom configuration server + Failed to import custom configuration Configuration Failed to read configuration file - Please enter the correct server port format. + Please enter the correct port format. Please enter the local listening port. @@ -163,7 +163,7 @@ Please enter the password. - Please enter the server address. + Please enter the address. Please enter the user ID. @@ -271,13 +271,13 @@ Please select a protocol - Please select the server first + Please select the Configuration first - Servers deduplication completed. Old: {0}, New: {1}. + Configurations deduplication completed. Old: {0}, New: {1}. - Are you sure you want to remove the server? + Are you sure you want to remove the Configuration? The client configuration file is saved at: {0} @@ -289,10 +289,10 @@ Configuration successful. {0} - Custom configuration server imported successfully + Custom configuration Configuration imported successfully - {0} servers have been imported from clipboard + {0} Configurations have been imported from clipboard Successfully scanned and imported the shared link @@ -394,7 +394,7 @@ All - Please browse to import server configuration + Please browse to import Configuration configuration Testing... @@ -406,7 +406,7 @@ Local - Server filter, press Enter to execute + Configuration filter, press Enter to execute Check Update @@ -436,7 +436,7 @@ Routing Setting - Servers + Configurations Settings @@ -487,55 +487,55 @@ Scan QR code on the screen (Ctrl+S) - Clone selected server + Clone selected Configuration - Remove duplicate servers + Remove duplicate Configurations - Remove selected servers (Delete) + Remove selected Configurations (Delete) - Set as active server (Enter) + Set as active Configuration (Enter) Clear all service statistics - Test servers real delay (Ctrl+R) + Test Configurations real delay (Ctrl+R) Sort by test result - Test servers download speed (Ctrl+T) + Test Configurations download speed (Ctrl+T) - Test servers with tcping (Ctrl+O) + Test Configurations with tcping (Ctrl+O) - Export selected server for complete configuration + Export selected Configuration for complete configuration Export Share Link to Clipboard (Ctrl+C) - Add a custom configuration server + Add a custom configuration Configuration - Add [Shadowsocks] server + Add [Shadowsocks] Configuration - Add [SOCKS] server + Add [SOCKS] Configuration - Add [Trojan] server + Add [Trojan] Configuration - Add [VLESS] server + Add [VLESS] Configuration - Add [VMess] server + Add [VMess] Configuration Select all (Ctrl+A) @@ -760,7 +760,7 @@ Enable Security Protocol TLS v1.3 (subscription/update) - Tray right-click menu servers display limit + Tray right-click menu Configurations display limit Enable UDP @@ -793,7 +793,7 @@ PAC mode - Share Server (Ctrl+F) + Share Configuration (Ctrl+F) Routing @@ -940,7 +940,7 @@ Move to group - Enable sorting servers by drag-n-drop (requires restart) + Enable sorting Configurations by drag-n-drop (requires restart) Auto refresh @@ -949,10 +949,10 @@ Skip test - Edit Server (Ctrl+D) + Edit Configuration (Ctrl+D) - Double-clicking server makes it active + Double-clicking Configuration makes it active Test completed @@ -1060,7 +1060,7 @@ Domain - Add [Hysteria2] server + Add [Hysteria2] Configuration Hysteria Max bandwidth (Up/Down) @@ -1069,19 +1069,19 @@ Use System Hosts - Add [TUIC] server + Add [TUIC] Configuration Congestion control - Previous proxy remarks + Previous proxy Configuration remarks - Next proxy remarks + Next proxy Configuration remarks - Please make sure the remarks exist and are unique + Please make sure the Configuration remarks exist and are unique Enable additional Inbound @@ -1090,7 +1090,7 @@ Enable IPv6 Address - Add [WireGuard] server + Add [WireGuard] Configuration Private Key @@ -1123,7 +1123,7 @@ *grpc Authority - Add [HTTP] server + Add [HTTP] Configuration Use Xray and enable non-Tun mode, which conflicts with the group previous proxy @@ -1237,7 +1237,7 @@ Export Base64-encoded Share Links to Clipboard - Export selected server for complete configuration to clipboard + Export selected Configuration for complete configuration to clipboard Show or hide the main window @@ -1390,30 +1390,30 @@ Removed {0} invalid test results. - Server port range + Configuration port range Will cover the port, separate with commas (,) - Multi-server to custom configuration + Multi-Configuration to custom configuration - Multi-server Random by Xray + Multi-Configuration Random by Xray - Multi-server RoundRobin by Xray + Multi-Configuration RoundRobin by Xray - Multi-server LeastPing by Xray + Multi-Configuration LeastPing by Xray - Multi-server LeastLoad by Xray + Multi-Configuration LeastLoad by Xray - Multi-server LeastPing by sing-box + Multi-Configuration LeastPing by sing-box - Export server + Export Configuration \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index 3ccb6462..a5f07957 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -121,7 +121,7 @@ 导出分享链接至剪贴板成功 - 请先检查服务器设置 + 请先检查配置文件设置 配置格式不正确 @@ -148,13 +148,13 @@ 获取默认配置失败 - 导入自定义配置服务器失败 + 导入自定义配置文件失败 读取配置文件失败 - 请填写正确格式的服务器端口 + 请填写正确格式的端口 请填写本地监听端口 @@ -163,7 +163,7 @@ 请填写密码 - 请填写服务器地址 + 请填写地址 请填写用户 ID @@ -271,13 +271,13 @@ 请选择协议 - 请先选择服务器 + 请先选择配置文件 - 服务器去重完成。原数量: {0},现数量: {1}。 + 配置文件去重完成。原数量: {0},现数量: {1}。 - 是否确定移除服务器? + 是否确定移除配置文件? 客户端配置文件保存在:{0} @@ -289,10 +289,10 @@ 配置成功。 {0} - 成功导入自定义配置服务器 + 成功导入自定义配置文件 - 成功从剪贴板导入 {0} 个服务器 + 成功从剪贴板导入 {0} 个配置文件 扫描导入分享链接成功 @@ -388,13 +388,13 @@ 注册全局热键 {0} 成功 - 未分组服务器 + 未分组配置文件 所有 - 请浏览导入服务器配置 + 请浏览导入配置文件配置 测试中... @@ -406,7 +406,7 @@ 本地 - 服务器过滤器,按回车执行 + 配置文件过滤器,按回车执行 检查更新 @@ -436,7 +436,7 @@ 路由设置 - 服务器 + 配置文件 设置 @@ -487,55 +487,55 @@ 扫描屏幕上的二维码 (Ctrl+S) - 克隆所选服务器 + 克隆所选配置文件 - 移除重复的服务器 + 移除重复的配置文件 - 移除所选服务器 (多选) (Delete) + 移除所选配置文件 (多选) (Delete) - 设为活动服务器 (Enter) + 设为活动配置文件 (Enter) 清除所有服务统计数据 - 测试服务器真连接延迟 (多选) (Ctrl+R) + 测试配置文件真连接延迟 (多选) (Ctrl+R) 按测试结果排序 - 测试服务器速度 (多选) (Ctrl+T) + 测试配置文件速度 (多选) (Ctrl+T) - 测试服务器延迟 Tcping (多选) (Ctrl+O) + 测试配置文件延迟 Tcping (多选) (Ctrl+O) - 导出所选服务器完整配置 + 导出所选配置文件完整配置 导出分享链接至剪贴板 (多选) (Ctrl+C) - 添加自定义配置服务器 + 添加自定义配置文件 - 添加 [Shadowsocks] 服务器 + 添加 [Shadowsocks] 配置文件 - 添加 [SOCKS] 服务器 + 添加 [SOCKS] 配置文件 - 添加 [Trojan] 服务器 + 添加 [Trojan] 配置文件 - 添加 [VLESS] 服务器 + 添加 [VLESS] 配置文件 - 添加 [VMess] 服务器 + 添加 [VMess] 配置文件 全选 (Ctrl+A) @@ -700,7 +700,7 @@ Outbound Freedom domainStrategy - 自动调整服务器列宽在更新订阅后 + 自动调整配置文件列宽在更新订阅后 检查 Pre-Release 更新 (请谨慎启用) @@ -760,7 +760,7 @@ 启用安全协议 TLS v1.3 (订阅/检查更新) - 托盘右键菜单服务器展示数量限制 + 托盘右键菜单配置文件展示数量限制 开启 UDP @@ -793,7 +793,7 @@ Pac 模式 - 分享服务器 (Ctrl+F) + 分享配置文件 (Ctrl+F) 路由 @@ -940,7 +940,7 @@ 移至订阅分组 - 启用服务器拖放排序(需重启) + 启用配置文件拖放排序(需重启) 自动刷新 @@ -949,10 +949,10 @@ 跳过测试 - 编辑服务器 (Ctrl+D) + 编辑配置文件 (Ctrl+D) - 主界面双击设为活动服务器 + 主界面双击设为活动配置文件 测试完成 @@ -1057,7 +1057,7 @@ Domain - 添加 [Hysteria2] 服务器 + 添加 [Hysteria2] 配置文件 Hysteria 最大带宽 (Up/Dw) @@ -1066,19 +1066,19 @@ 使用系统 hosts - 添加 [TUIC] 服务器 + 添加 [TUIC] 配置文件 拥塞控制算法 - - 前置代理别名 + + 前置代理配置文件别名 - - 落地代理別名 + + 落地代理配置文件別名 - - 请确保别名存在并唯一 + + 请确保配置文件别名存在并唯一 启用额外监听端口 @@ -1087,7 +1087,7 @@ 启用 IPv6 - 添加 [WireGuard] 服务器 + 添加 [WireGuard] 配置文件 PrivateKey @@ -1120,7 +1120,7 @@ *grpc Authority - 添加 [HTTP] 服务器 + 添加 [HTTP] 配置文件 使用 Xray 且非 Tun 模式启用,和分组前置代理冲突 @@ -1234,7 +1234,7 @@ 导出分享链接至剪贴板 (多选) Base64 编码 - 导出所选服务器完整配置至剪贴板 + 导出所选配置文件完整配置至剪贴板 显示或隐藏主界面 @@ -1393,24 +1393,24 @@ 会覆盖端口,多组时用逗号 (,) 隔开 - 多服务器产生自定义配置 (多选) + 多配置文件产生自定义配置 (多选) - 多服务器随机 Xray + 多配置文件随机 Xray - 多服务器负载均衡 Xray + 多配置文件负载均衡  Xray - 多服务器最低延迟 Xray + 多配置文件最低延迟  Xray - 多服务器最稳定 Xray + 多配置文件最稳定  Xray - 多服务器最低延迟 sing-box + 多配置文件最低延迟 sing-box - 导出服务器 + 导出配置文件 diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index 0f827408..b8a5011a 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -121,7 +121,7 @@ 匯出分享链接至剪貼簿成功 - 請先檢查伺服器設定 + 請先檢查設定檔設定 設定格式不正確 @@ -148,13 +148,13 @@ 獲取預設設定失敗 - 匯入自訂設定伺服器失敗 + 匯入自訂設定設定檔失敗 讀取設定檔失敗 - 請填寫正確格式的伺服器埠 + 請填寫正確格式的埠 請填寫本機偵聽埠 @@ -163,7 +163,7 @@ 請填寫密碼 - 請填寫伺服器位址 + 請填寫位址 請填寫使用者 ID @@ -271,13 +271,13 @@ 請選擇協定 - 請先選擇伺服器 + 請先選擇設定檔 - 伺服器去重完成。原數量: {0},現數量: {1}。 + 設定檔去重完成。原數量: {0},現數量: {1}。 - 是否確定移除伺服器? + 是否確定移除設定檔? 用戶端設定檔儲存在:{0} @@ -289,10 +289,10 @@ 設定成功。{0} - 成功匯入自訂設定伺服器 + 成功匯入自訂設定設定檔 - 成功從剪貼簿匯入 {0} 個伺服器 + 成功從剪貼簿匯入 {0} 個設定檔 掃描匯入分享链接成功 @@ -388,13 +388,13 @@ 註冊全域快速鍵 {0} 成功 - 未分組伺服器 + 未分組設定檔 所有 - 請瀏覽匯入伺服器設定 + 請瀏覽匯入設定檔設定 測試中... @@ -406,7 +406,7 @@ 本機 - 伺服器過濾,按 Enter 執行 + 設定檔過濾,按 Enter 執行 檢查更新 @@ -436,7 +436,7 @@ 路由設定 - 伺服器 + 設定檔 設定 @@ -487,55 +487,55 @@ 掃描螢幕上的二維碼 (Ctrl+S) - 複製所選伺服器 + 複製所選設定檔 - 移除重複的伺服器 + 移除重複的設定檔 - 移除所選伺服器 (多選) (Delete) + 移除所選設定檔 (多選) (Delete) - 設為活動伺服器 (Enter) + 設為活動設定檔 (Enter) 清除所有服務統計資料 - 測試伺服器真連線延遲 (多選) (Ctrl+R) + 測試設定檔真連線延遲 (多選) (Ctrl+R) 按測試結果排序 - 測試伺服器速度 (多選) (Ctrl+T) + 測試設定檔速度 (多選) (Ctrl+T) - 測試伺服器延遲 Tcping (多選) (Ctrl+O) + 測試設定檔延遲 Tcping (多選) (Ctrl+O) - 匯出所選伺服器完整設定 + 匯出所選設定檔完整設定 匯出分享链接至剪貼簿 (多選) (Ctrl+C) - 新增自訂設定伺服器 + 新增自訂設定設定檔 - 新增 [Shadowsocks] 伺服器 + 新增 [Shadowsocks] 設定檔 - 新增 [SOCKS] 伺服器 + 新增 [SOCKS] 設定檔 - 新增 [Trojan] 伺服器 + 新增 [Trojan] 設定檔 - 新增 [VLESS] 伺服器 + 新增 [VLESS] 設定檔 - 新增 [VMess] 伺服器 + 新增 [VMess] 設定檔 全選 (Ctrl+A) @@ -700,7 +700,7 @@ Outbound Freedom domainStrategy - 在更新訂閱後自動調整伺服器列寬 + 在更新訂閱後自動調整設定檔列寬 檢查 Pre-Release 更新 (請謹慎啟用) @@ -760,7 +760,7 @@ 啟用安全協定 TLS v1.3 (訂閱/檢查更新) - 工具列右鍵選單伺服器展示數量限制 + 工具列右鍵選單設定檔展示數量限制 開啟 UDP @@ -793,7 +793,7 @@ PAC 模式 - 分享伺服器 (Ctrl+F) + 分享設定檔 (Ctrl+F) 路由 @@ -940,7 +940,7 @@ 移至訂閱分組 - 啟動伺服器拖放排序 (需重啟) + 啟動設定檔拖放排序 (需重啟) 自動重新整理 @@ -949,10 +949,10 @@ 跳過測試 - 編輯伺服器 (Ctrl+D) + 編輯設定檔 (Ctrl+D) - 主介面輕按兩下設為活動伺服器 + 主介面輕按兩下設為活動設定檔 測試完成 @@ -1057,7 +1057,7 @@ Domain - 添加 [Hysteria2] 伺服器 + 添加 [Hysteria2] 設定檔 Hysteria 最大頻寬 (Up/Dw) @@ -1066,19 +1066,19 @@ 使用系統 hosts - 新增 [TUIC] 伺服器 + 新增 [TUIC] 設定檔 擁塞控制算法 - - 前置代理別名 + + 前置代理設定檔別名 - - 落地代理別名 + + 落地代理設定檔別名 - - 請確保別名存在並且唯一 + + 請確保設定檔別名存在並且唯一 啟用額外偵聽連接埠 @@ -1087,7 +1087,7 @@ 啟用 IPv6 - 添加 [WireGuard] 伺服器 + 添加 [WireGuard] 設定檔 PrivateKey @@ -1120,7 +1120,7 @@ *grpc Authority - 新增 [HTTP] 伺服器 + 新增 [HTTP] 設定檔 使用 Xray 且非 Tun 模式啟用,和分組前置代理衝突 @@ -1234,7 +1234,7 @@ 匯出分享链接至剪貼簿 (多選) Base64 编码 - 匯出所選伺服器完整設定至剪貼簿 + 匯出所選設定檔完整設定至剪貼簿 顯示或隱藏主介面 @@ -1393,24 +1393,24 @@ 會覆蓋端口,多組時用逗號 (,) 隔開 - 多伺服器產生自訂配置 (多選) + 多設定檔產生自訂配置 (多選) - 多伺服器隨機 Xray + 多設定檔隨機 Xray - 多伺服器負載平衡 Xray + 多設定檔負載平衡 Xray - 多伺服器最低延遲 Xray + 多設定檔最低延遲 Xray - 多伺服器最穩定 Xray + 多設定檔最穩定 Xray - 多伺服器最低延遲 sing-box + 多設定檔最低延遲 sing-box - 匯出伺服器 + 匯出設定檔 diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs index d6256e6a..481ae92d 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs @@ -12,14 +12,7 @@ public class CoreConfigClashService { _config = config; } - - /// - /// 生成配置文件 - /// - /// - /// - /// - /// + public async Task GenerateClientCustomConfig(ProfileItem node, string? fileName) { var ret = new RetResult(); diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs index c09d325d..1bd23872 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs @@ -120,7 +120,7 @@ public class CoreConfigV2rayService { continue; } - if (it.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard) + if (it.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC) { continue; } @@ -661,7 +661,7 @@ public class CoreConfigV2rayService { usersItem = vnextItem.users.First(); } - //远程服务器用户ID + usersItem.id = node.Id; usersItem.alterId = node.AlterId; usersItem.email = Global.UserEMail; @@ -805,6 +805,26 @@ public class CoreConfigV2rayService outbound.settings.vnext = null; break; } + case EConfigType.WireGuard: + { + var peer = new WireguardPeer4Ray + { + publicKey = node.PublicKey, + endpoint = node.Address + ":" + node.Port.ToString() + }; + var setting = new Outboundsettings4Ray + { + address = Utils.String2List(node.RequestHost), + secretKey = node.Id, + reserved = Utils.String2List(node.Path)?.Select(int.Parse).ToList(), + mtu = node.ShortId.IsNullOrEmpty() ? Global.TunMtus.First() : node.ShortId.ToInt(), + peers = new List { peer } + }; + outbound.settings = setting; + outbound.settings.vnext = null; + outbound.settings.servers = null; + break; + } } outbound.protocol = Global.ProtocolTypes[node.ConfigType]; @@ -1123,7 +1143,7 @@ public class CoreConfigV2rayService obj["servers"] = JsonUtils.SerializeToNode(servers); } - // 追加至 dns 设置 + // Append to dns settings if (item.UseSystemHosts) { var systemHosts = Utils.GetSystemHosts(); @@ -1270,8 +1290,7 @@ public class CoreConfigV2rayService if (prevNode is not null && prevNode.ConfigType != EConfigType.Custom && prevNode.ConfigType != EConfigType.Hysteria2 - && prevNode.ConfigType != EConfigType.TUIC - && prevNode.ConfigType != EConfigType.WireGuard) + && prevNode.ConfigType != EConfigType.TUIC) { var prevOutbound = JsonUtils.Deserialize(txtOutbound); await GenOutbound(prevNode, prevOutbound); @@ -1289,8 +1308,7 @@ public class CoreConfigV2rayService if (nextNode is not null && nextNode.ConfigType != EConfigType.Custom && nextNode.ConfigType != EConfigType.Hysteria2 - && nextNode.ConfigType != EConfigType.TUIC - && nextNode.ConfigType != EConfigType.WireGuard) + && nextNode.ConfigType != EConfigType.TUIC) { var nextOutbound = JsonUtils.Deserialize(txtOutbound); await GenOutbound(nextNode, nextOutbound); diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index 040d12ed..b99339d6 100644 --- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -100,6 +100,7 @@ public class OptionSettingViewModel : MyReactiveObject [Reactive] public string CoreType4 { get; set; } [Reactive] public string CoreType5 { get; set; } [Reactive] public string CoreType6 { get; set; } + [Reactive] public string CoreType9 { get; set; } #endregion CoreType @@ -259,6 +260,10 @@ public class OptionSettingViewModel : MyReactiveObject case 6: CoreType6 = type; break; + + case 9: + CoreType9 = type; + break; } }); await Task.CompletedTask; @@ -407,6 +412,10 @@ public class OptionSettingViewModel : MyReactiveObject type = CoreType6; break; + case 9: + type = CoreType9; + break; + default: continue; } diff --git a/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs index 5ccfc13d..dd033a11 100644 --- a/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs @@ -131,7 +131,6 @@ public partial class AddServerWindow : ReactiveWindow sepa2.IsVisible = false; gridTransport.IsVisible = false; gridTls.IsVisible = false; - cmbCoreType.IsEnabled = false; break; } diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml index 47df97d2..8c9351d7 100644 --- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml @@ -813,7 +813,7 @@ + RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto"> + + + diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs index ea8ba8a7..58aceaf1 100644 --- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs @@ -64,6 +64,7 @@ public partial class OptionSettingWindow : ReactiveWindow vm.CoreType4, v => v.cmbCoreType4.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType5, v => v.cmbCoreType5.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType6, v => v.cmbCoreType6.SelectedValue).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.CoreType9, v => v.cmbCoreType9.SelectedValue).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); }); diff --git a/v2rayN/v2rayN/App.xaml.cs b/v2rayN/v2rayN/App.xaml.cs index 4d2f5bc8..86518fa0 100644 --- a/v2rayN/v2rayN/App.xaml.cs +++ b/v2rayN/v2rayN/App.xaml.cs @@ -19,7 +19,7 @@ public partial class App : Application } /// - /// 只打开一个进程 + /// Open only one process /// /// protected override void OnStartup(StartupEventArgs e) diff --git a/v2rayN/v2rayN/Common/WindowsUtils.cs b/v2rayN/v2rayN/Common/WindowsUtils.cs index ad798cfb..346c7763 100644 --- a/v2rayN/v2rayN/Common/WindowsUtils.cs +++ b/v2rayN/v2rayN/Common/WindowsUtils.cs @@ -12,10 +12,6 @@ internal static class WindowsUtils { private static readonly string _tag = "WindowsUtils"; - /// - /// 获取剪贴板数 - /// - /// public static string? GetClipboardData() { var strData = string.Empty; @@ -35,10 +31,6 @@ internal static class WindowsUtils return strData; } - /// - /// 拷贝至剪贴板 - /// - /// public static void SetClipboardData(string strData) { try diff --git a/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs b/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs index 694f4e2a..cd9c41be 100644 --- a/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs @@ -125,7 +125,6 @@ public partial class AddServerWindow sepa2.Visibility = Visibility.Collapsed; gridTransport.Visibility = Visibility.Collapsed; gridTls.Visibility = Visibility.Collapsed; - cmbCoreType.IsEnabled = false; break; } diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml index a5d7aeee..374dce35 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml @@ -1098,6 +1098,7 @@ + @@ -1192,6 +1193,21 @@ Width="200" Margin="{StaticResource Margin8}" Style="{StaticResource DefComboBox}" /> + + + diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs index 3bb433bc..b0b5440c 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs @@ -66,6 +66,7 @@ public partial class OptionSettingWindow cmbCoreType4.Items.Add(it); cmbCoreType5.Items.Add(it); cmbCoreType6.Items.Add(it); + cmbCoreType9.Items.Add(it); }); for (var i = 2; i <= 8; i++) @@ -178,6 +179,7 @@ public partial class OptionSettingWindow this.Bind(ViewModel, vm => vm.CoreType4, v => v.cmbCoreType4.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType5, v => v.cmbCoreType5.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType6, v => v.cmbCoreType6.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.CoreType9, v => v.cmbCoreType9.Text).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); });