Update On Tue Dec 16 19:42:47 CET 2025

This commit is contained in:
github-action[bot]
2025-12-16 19:42:48 +01:00
parent 4456ecc632
commit 68db8a2905
112 changed files with 4014 additions and 1843 deletions

View File

@@ -308,6 +308,17 @@ o = s:option(DummyValue, "switch_mode", " ")
o.template = appname .. "/global/proxy"
o:depends({ _tcp_node_bool = "1" })
-- Node → DNS Depends Settings
o = s:option(DummyValue, "_node_sel_shunt", "")
o.template = appname .. "/cbi/hidevalue"
o.value = "1"
o:depends({ tcp_node = "__always__" })
o = s:option(DummyValue, "_node_sel_other", "")
o.template = appname .. "/cbi/hidevalue"
o.value = "1"
o:depends({ _node_sel_shunt = "1", ['!reverse'] = true })
---- DNS
o = s:option(ListValue, "dns_shunt", "DNS " .. translate("Shunt"))
o.default = "chinadns-ng"
@@ -333,6 +344,7 @@ end
if has_xray then
o:value("xray", "Xray")
end
o:depends({ _tcp_node_bool = "1", _node_sel_other = "1" })
o.remove = function(self, section)
local f = s.fields["tcp_node"]
local id_val = f and f:formvalue(section) or ""
@@ -362,7 +374,9 @@ o:value("tcp", "TCP")
o:value("tcp+doh", "TCP + DoH (" .. translate("A/AAAA type") .. ")")
o:depends("dns_mode", "xray")
o.cfgvalue = function(self, section)
return m:get(section, "v2ray_dns_mode")
local v = m:get(section, "v2ray_dns_mode")
local key = { udp = true, tcp = true, ["tcp+doh"] = true }
return (v and key[v]) and v or self.default
end
o.write = function(self, section, value)
if s.fields["dns_mode"]:formvalue(section) == "xray" then
@@ -377,7 +391,9 @@ o:value("tcp", "TCP")
o:value("doh", "DoH")
o:depends("dns_mode", "sing-box")
o.cfgvalue = function(self, section)
return m:get(section, "v2ray_dns_mode")
local v = m:get(section, "v2ray_dns_mode")
local key = { udp = true, tcp = true, doh = true }
return (v and key[v]) and v or self.default
end
o.write = function(self, section, value)
if s.fields["dns_mode"]:formvalue(section) == "sing-box" then
@@ -444,6 +460,7 @@ o = s:option(Value, "remote_dns_client_ip", translate("EDNS Client Subnet"))
o.datatype = "ipaddr"
o:depends({dns_mode = "sing-box"})
o:depends({dns_mode = "xray"})
o:depends({_node_sel_shunt = "1"})
o = s:option(ListValue, "chinadns_ng_default_tag", translate("Default DNS"))
o.default = "none"
@@ -485,6 +502,7 @@ for k, v in pairs(nodes_table) do
udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
s.fields["xray_dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id })
s.fields["_node_sel_shunt"]:depends({ tcp_node = v.id })
end
if v.type == "sing-box" and has_singbox then
tcp:value(v.id, v["remark"])
@@ -493,17 +511,13 @@ for k, v in pairs(nodes_table) do
udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
s.fields["singbox_dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id })
end
if has_xray or has_singbox then
s.fields["remote_dns_client_ip"]:depends({ tcp_node = v.id })
s.fields["_node_sel_shunt"]:depends({ tcp_node = v.id })
end
else
tcp:value(v.id, v["remark"])
tcp.group[#tcp.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
udp:value(v.id, v["remark"])
udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
s.fields["dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id })
end
end

View File

@@ -309,6 +309,18 @@ o = s:taboption("Main", Flag, "tcp_node_socks_bind_local", translate("TCP Node")
o.default = "1"
o:depends({ tcp_node = "", ["!reverse"] = true })
-- Node → DNS Depends Settings
o = s:taboption("Main", DummyValue, "_node_sel_shunt", "")
o.template = appname .. "/cbi/hidevalue"
o.value = "1"
o:depends({ tcp_node = "__always__" })
o = s:taboption("Main", DummyValue, "_node_sel_other", "")
o.template = appname .. "/cbi/hidevalue"
o.value = "1"
o:depends({ _node_sel_shunt = "1", ['!reverse'] = true })
-- [[ DNS Settings ]]--
s:tab("DNS", translate("DNS"))
o = s:taboption("DNS", ListValue, "dns_shunt", "DNS " .. translate("Shunt"))
@@ -388,8 +400,8 @@ end
if has_xray then
o:value("xray", "Xray")
end
o:depends({ dns_shunt = "chinadns-ng", tcp_node = "" })
o:depends({ dns_shunt = "dnsmasq", tcp_node = "" })
o:depends({ dns_shunt = "chinadns-ng", _node_sel_other = "1" })
o:depends({ dns_shunt = "dnsmasq", _node_sel_other = "1" })
o.remove = function(self, section)
local f = s.fields["smartdns_dns_mode"]
if f and f:formvalue(section) then
@@ -408,7 +420,7 @@ if api.is_finded("smartdns") then
if has_xray then
o:value("xray", "Xray")
end
o:depends({ dns_shunt = "smartdns", tcp_node = "" })
o:depends({ dns_shunt = "smartdns", _node_sel_other = "1" })
o.remove = function(self, section)
local f = s.fields["dns_mode"]
if f and f:formvalue(section) then
@@ -468,7 +480,9 @@ o:value("tcp+doh", "TCP + DoH (" .. translate("A/AAAA type") .. ")")
o:depends("dns_mode", "xray")
o:depends("smartdns_dns_mode", "xray")
o.cfgvalue = function(self, section)
return m:get(section, "v2ray_dns_mode")
local v = m:get(section, "v2ray_dns_mode")
local key = { udp = true, tcp = true, ["tcp+doh"] = true }
return (v and key[v]) and v or self.default
end
o.write = function(self, section, value)
if s.fields["dns_mode"]:formvalue(section) == "xray" or s.fields["smartdns_dns_mode"]:formvalue(section) == "xray" then
@@ -484,7 +498,9 @@ o:value("doh", "DoH")
o:depends("dns_mode", "sing-box")
o:depends("smartdns_dns_mode", "sing-box")
o.cfgvalue = function(self, section)
return m:get(section, "v2ray_dns_mode")
local v = m:get(section, "v2ray_dns_mode")
local key = { udp = true, tcp = true, doh = true }
return (v and key[v]) and v or self.default
end
o.write = function(self, section, value)
if s.fields["dns_mode"]:formvalue(section) == "sing-box" or s.fields["smartdns_dns_mode"]:formvalue(section) == "sing-box" then
@@ -548,6 +564,7 @@ o.datatype = "ipaddr"
o:depends({dns_mode = "sing-box"})
o:depends({dns_mode = "xray"})
o:depends("dns_shunt", "smartdns")
o:depends("_node_sel_shunt", "1")
o = s:taboption("DNS", Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the shunt domain that proxy."))
o.default = "0"
@@ -557,6 +574,7 @@ o:depends({smartdns_dns_mode = "sing-box", dns_shunt = "smartdns"})
o:depends({dns_mode = "xray", dns_shunt = "dnsmasq"})
o:depends({dns_mode = "xray", dns_shunt = "chinadns-ng"})
o:depends({smartdns_dns_mode = "xray", dns_shunt = "smartdns"})
o:depends("_node_sel_shunt", "1")
o.validate = function(self, value, t)
if value and value == "1" then
local _dns_mode = s.fields["dns_mode"]:formvalue(t)
@@ -810,22 +828,15 @@ for k, v in pairs(nodes_table) do
udp:value(v.id, v["remark"])
udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
s.fields["xray_dns_mode"]:depends({ [v.id .. "-type"] = "Xray", tcp_node = v.id })
s.fields["singbox_dns_mode"]:depends({ [v.id .. "-type"] = "sing-box", tcp_node = v.id })
s.fields["remote_dns_client_ip"]:depends({ tcp_node = v.id })
s.fields["remote_fakedns"]:depends({ tcp_node = v.id })
s.fields["_node_sel_shunt"]:depends({ tcp_node = v.id })
s.fields["xray_dns_mode"]:depends({ [v.id .. "-type"] = "Xray", _node_sel_shunt = "1" })
s.fields["singbox_dns_mode"]:depends({ [v.id .. "-type"] = "sing-box", _node_sel_shunt = "1" })
end
else
tcp:value(v.id, v["remark"])
tcp.group[#tcp.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
udp:value(v.id, v["remark"])
udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
s.fields["dns_mode"]:depends({ dns_shunt = "chinadns-ng", tcp_node = v.id })
s.fields["dns_mode"]:depends({ dns_shunt = "dnsmasq", tcp_node = v.id })
if api.is_finded("smartdns") then
s.fields["smartdns_dns_mode"]:depends({ dns_shunt = "smartdns", tcp_node = v.id })
end
end
if v.type == "Socks" then
if has_singbox or has_xray then

View File

@@ -201,8 +201,8 @@ function gen_outbound(flag, node, tag, proxy_table)
} or nil,
wsSettings = (node.transport == "ws") and {
path = node.ws_path or "/",
headers = (node.ws_host or node.ws_user_agent) and {
Host = node.ws_host,
host = node.ws_host,
headers = node.ws_user_agent and {
["User-Agent"] = node.ws_user_agent
} or nil,
maxEarlyData = tonumber(node.ws_maxEarlyData) or nil,

View File

@@ -139,7 +139,7 @@ window.lv_dropdown_data["<%=cbid%>"] = <%=json.stringify(dropdown_data)%>;
lv_openPanel(cbid,display,panel,listContainer,hiddenSelect,searchInput);
}
});
lv_adaptiveStyle(cbid); // copy select styles
lv_registerAdaptive(cbid);
})();
//]]>
</script>

View File

@@ -244,9 +244,11 @@ local appname = api.appname
return lv_rgbToHex(r, g, b);
}
// copy select styles
function lv_adaptiveStyle(cbid) {
const display = document.getElementById(cbid + ".display");
const hiddenSelect = document.getElementById(cbid);
const panel = document.getElementById(cbid + ".panel");
if (hiddenSelect && display) {
const elOption = hiddenSelect.getElementsByTagName("option")[0]
const styleSelect = window.getComputedStyle(hiddenSelect)
@@ -466,7 +468,13 @@ local appname = api.appname
}
panel.style.left = rect.left + "px";
panel.style.top = top + "px";
panel.style.minWidth = rect.width + "px";
const panelRect = panel.getBoundingClientRect();
const displayWidth = rect.width;
const remainingWidth = window.innerWidth - panelRect.left - 12;
const maxWidth = Math.max(displayWidth, Math.floor(remainingWidth));
panel.style.maxWidth = maxWidth + "px";
panel.style.minWidth = displayWidth + "px";
panel.style.width = "auto";
panel.style.visibility = "";
}
@@ -601,22 +609,24 @@ local appname = api.appname
if(!li || li === listContainer) return;
const key = li.getAttribute('data-key') || "";
const text = li.querySelector(".lv-item-label")?.textContent || li.textContent || key;
if (key !== hiddenSelect.value) {
//动态改值
const changed = key !== hiddenSelect.value;
if (changed) {
//改值
hiddenSelect.options[0].value = key;
hiddenSelect.options[0].text = key;
hiddenSelect.value = key;
labelSpan.textContent = text;
labelSpan.title = text;
setTimeout(() => {
try {
const evt = new Event('change', { bubbles: true });
hiddenSelect.dispatchEvent(evt);
} catch(e){}
}, 0);
lv_highlightSelectedItem(listContainer, hiddenSelect);
lv_updateGroupCounts(cbid, listContainer, hiddenSelect, searchInput);
}
lv_closePanel(cbid,panel,listContainer,hiddenSelect,searchInput);
if (changed) {
setTimeout(() => {
hiddenSelect.dispatchEvent(new Event('change', { bubbles: true }));
}, 0);
}
});
// 搜索功能
@@ -635,27 +645,22 @@ local appname = api.appname
}
});
});
// 设置宽度
panel.style.maxWidth = lv_getPanelMaxWidth(display);
panel.style.minWidth = display.getBoundingClientRect().width + "px";
panel.style.width = "auto";
}
function lv_getPanelMaxWidth(display) {
if (!display) return 0;
const rectW = el => el && el.getBoundingClientRect().width;
const fallback = rectW(display) || 0;
const cbiValue = display.closest(".cbi-value");
if (cbiValue) {
const valueW = rectW(cbiValue);
const titleW = rectW(cbiValue.querySelector(".cbi-value-title"));
if (valueW) {
return Math.floor(titleW ? valueW - titleW : valueW);
}
}
const fieldW = rectW(display.closest(".cbi-value-field"));
return Math.floor(fieldW || fallback);
const lv_adaptiveControls = new Set();
function lv_registerAdaptive(cbid) {
lv_adaptiveControls.add(cbid);
lv_adaptiveStyle(cbid);
}
let lv_adaptiveTicking = false;
window.addEventListener("resize", () => {
if (!lv_adaptiveTicking) {
lv_adaptiveTicking = true;
requestAnimationFrame(() => {
lv_adaptiveControls.forEach(cbid => lv_adaptiveStyle(cbid));
lv_adaptiveTicking = false;
});
}
});
//]]>
</script>