From ceccdbf6715b0d5f1aecfcef2703e8540fea9d6c Mon Sep 17 00:00:00 2001 From: Merutu Kirishima <44743565+Liniya@users.noreply.github.com> Date: Fri, 12 Dec 2025 14:03:28 +0300 Subject: [PATCH] Full template merges standard config DNS settings --- .../Singbox/SingboxConfigTemplateService.cs | 47 +++++++++++++++++++ .../V2ray/V2rayConfigTemplateService.cs | 44 +++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxConfigTemplateService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxConfigTemplateService.cs index 6fe9b35a..5b735086 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxConfigTemplateService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxConfigTemplateService.cs @@ -22,6 +22,53 @@ public partial class CoreConfigSingboxService return JsonUtils.Serialize(singboxConfig); } + // Ensure dns node exists + if (singboxConfig.dns != null) + { + if (fullConfigTemplateNode["dns"] == null) + { + fullConfigTemplateNode["dns"] = JsonNode.Parse(JsonUtils.Serialize(singboxConfig.dns)); + } + else + { + // Handle dns rules - append instead of override + if (fullConfigTemplateNode["dns"]["rules"] is JsonArray customDnsRulesNode) + { + if (JsonNode.Parse(JsonUtils.Serialize(singboxConfig.dns?.rules)) is JsonArray newDnsRules) + { + foreach (var ruleNode in newDnsRules) + { + customDnsRulesNode.Add(ruleNode?.DeepClone()); + } + + fullConfigTemplateNode["dns"]["rules"] = customDnsRulesNode; + } + } + else + { + fullConfigTemplateNode["dns"]["rules"] = JsonNode.Parse(JsonUtils.Serialize(singboxConfig.dns?.rules)); + } + + // Handle dns servers - append instead of override + if (fullConfigTemplateNode["dns"]["servers"] is JsonArray customDnsServersNode) + { + if (JsonNode.Parse(JsonUtils.Serialize(singboxConfig.dns?.servers)) is JsonArray newDnsServers) + { + foreach (var serverNode in newDnsServers) + { + customDnsServersNode.Add(serverNode?.DeepClone()); + } + + fullConfigTemplateNode["dns"]["servers"] = customDnsServersNode; + } + } + else + { + fullConfigTemplateNode["dns"]["servers"] = JsonNode.Parse(JsonUtils.Serialize(singboxConfig.dns?.servers)); + } + } + } + // Process outbounds var customOutboundsNode = fullConfigTemplateNode["outbounds"] is JsonArray outbounds ? outbounds : new JsonArray(); foreach (var outbound in singboxConfig.outbounds) diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayConfigTemplateService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayConfigTemplateService.cs index 1f2583ff..b4eb78d4 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayConfigTemplateService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayConfigTemplateService.cs @@ -16,6 +16,50 @@ public partial class CoreConfigV2rayService return JsonUtils.Serialize(v2rayConfig); } + // Ensure dns node exists + if (fullConfigTemplateNode["dns"] == null) + { + fullConfigTemplateNode["dns"] = JsonNode.Parse(JsonUtils.Serialize(v2rayConfig.dns)); + } + else + { + // Handle dns hosts - append instead of override + if (fullConfigTemplateNode["dns"]["hosts"] is JsonObject customDnsHostsNode) + { + if (JsonNode.Parse(JsonUtils.Serialize(v2rayConfig.dns.hosts)) is JsonObject newDnsHosts) + { + foreach (var hostNode in newDnsHosts) + { + customDnsHostsNode.Add(hostNode.Key, hostNode.Value?.DeepClone()); + } + + fullConfigTemplateNode["dns"]["hosts"] = customDnsHostsNode; + } + } + else + { + fullConfigTemplateNode["dns"]["hosts"] = JsonNode.Parse(JsonUtils.Serialize(v2rayConfig.dns.hosts)); + } + + // Handle dns servers - append instead of override + if (fullConfigTemplateNode["dns"]["servers"] is JsonArray customDnsServersNode) + { + if (JsonNode.Parse(JsonUtils.Serialize(v2rayConfig.dns.servers)) is JsonArray newDnsServers) + { + foreach (var serverNode in newDnsServers) + { + customDnsServersNode.Add(serverNode?.DeepClone()); + } + + fullConfigTemplateNode["dns"]["servers"] = customDnsServersNode; + } + } + else + { + fullConfigTemplateNode["dns"]["servers"] = JsonNode.Parse(JsonUtils.Serialize(v2rayConfig.dns.servers)); + } + } + // Handle balancer and rules modifications (for multiple load scenarios) if (v2rayConfig.routing?.balancers?.Count > 0) {