🎨 Sync 2025-11-16 00:10:11

This commit is contained in:
actions-user
2025-11-16 00:10:11 +08:00
parent 7d627be079
commit e8a77828f8
7 changed files with 82 additions and 62 deletions

View File

@@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall PKG_NAME:=luci-app-passwall
PKG_VERSION:=25.11.14 PKG_VERSION:=25.11.15
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_PO_VERSION:=$(PKG_VERSION) PKG_PO_VERSION:=$(PKG_VERSION)

View File

@@ -20,11 +20,17 @@ local port_validate = function(self, value, t)
end end
local nodes_table = {} local nodes_table = {}
local shunt_list = {} for _, e in ipairs(api.get_valid_nodes()) do
for k, e in ipairs(api.get_valid_nodes()) do
nodes_table[#nodes_table + 1] = e nodes_table[#nodes_table + 1] = e
end end
local normal_list = {}
for _, v in pairs(nodes_table) do
if v.node_type == "normal" then
normal_list[#normal_list + 1] = v
end
end
local dynamicList_write = function(self, section, value) local dynamicList_write = function(self, section, value)
local t = {} local t = {}
local t2 = {} local t2 = {}
@@ -198,14 +204,6 @@ o:value("", translate("Close"))
o:value("tcp", translate("Same as the tcp node")) o:value("tcp", translate("Same as the tcp node"))
o:depends({ _tcp_node_bool = "1" }) o:depends({ _tcp_node_bool = "1" })
for k, v in pairs(nodes_table) do
s.fields["tcp_node"]:value(v.id, v["remark"])
s.fields["udp_node"]:value(v.id, v["remark"])
if v.protocol and v.protocol == "_shunt" then
shunt_list[#shunt_list + 1] = v
end
end
o = s:option(DummyValue, "_udp_node_bool", "") o = s:option(DummyValue, "_udp_node_bool", "")
o.template = "passwall/cbi/hidevalue" o.template = "passwall/cbi/hidevalue"
o.value = "1" o.value = "1"
@@ -258,6 +256,8 @@ o.cfgvalue = function(t, n)
return string.format('<font color="red">%s</font>', return string.format('<font color="red">%s</font>',
translate("The port settings support single ports and ranges.<br>Separate multiple ports with commas (,).<br>Example: 21,80,443,1000:2000.")) translate("The port settings support single ports and ranges.<br>Separate multiple ports with commas (,).<br>Example: 21,80,443,1000:2000."))
end end
o:depends({ use_global_config = true })
o:depends({ _tcp_node_bool = "1" })
o = s:option(Flag, "use_direct_list", translatef("Use %s", translate("Direct List"))) o = s:option(Flag, "use_direct_list", translatef("Use %s", translate("Direct List")))
o.default = "1" o.default = "1"
@@ -331,10 +331,18 @@ o.remove = function(self, section)
if id_val == "" then if id_val == "" then
return m:del(section, self.option) return m:del(section, self.option)
end end
for k, v in pairs(shunt_list) do for _, v in pairs(nodes_table) do
if v.id == id_val then if v.id == id_val then
local new_val = (v.type == "Xray") and "xray" or "sing-box" local new_val = (v.type == "Xray") and "xray" or "sing-box"
return m:set(section, self.option, new_val) m:set(section, self.option, new_val)
local dns_field = s.fields[new_val .. "_dns_mode"]
local v2ray_dns_mode = dns_field and dns_field:formvalue(section)
if v2ray_dns_mode then
m:set(section, "v2ray_dns_mode", v2ray_dns_mode)
end
break
end end
end end
end end
@@ -451,20 +459,29 @@ o.description = desc .. "</ul>"
o:depends({dns_shunt = "dnsmasq", tcp_proxy_mode = "proxy", chn_list = "direct"}) o:depends({dns_shunt = "dnsmasq", tcp_proxy_mode = "proxy", chn_list = "direct"})
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
if v.protocol ~= "_shunt" then if #normal_list == 0 then
s.fields["dns_mode"]:depends({ _tcp_node_bool = "1" })
break
end
if v.protocol == "_shunt" then
if v.type == "Xray" and has_xray then
s.fields["tcp_node"]:value(v.id, v["remark"])
s.fields["udp_node"]:value(v.id, v["remark"])
s.fields["xray_dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id })
end
if v.type == "sing-box" and has_singbox then
s.fields["tcp_node"]:value(v.id, v["remark"])
s.fields["udp_node"]:value(v.id, v["remark"])
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 })
end
else
s.fields["tcp_node"]:value(v.id, v["remark"])
s.fields["udp_node"]:value(v.id, v["remark"])
s.fields["dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id }) s.fields["dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id })
end end
end end
for k, v in pairs(shunt_list) do
if v.type == "Xray" and has_xray then
s.fields["xray_dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id })
end
if v.type == "sing-box" and has_singbox then
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 })
end
end
return m return m

View File

@@ -11,7 +11,7 @@ local has_chnroute = fs.access("/usr/share/passwall/rules/chnroute")
m = Map(appname) m = Map(appname)
local nodes_table = {} local nodes_table = {}
for k, e in ipairs(api.get_valid_nodes()) do for _, e in ipairs(api.get_valid_nodes()) do
nodes_table[#nodes_table + 1] = e nodes_table[#nodes_table + 1] = e
end end
@@ -20,7 +20,7 @@ local balancing_list = {}
local urltest_list = {} local urltest_list = {}
local shunt_list = {} local shunt_list = {}
local iface_list = {} local iface_list = {}
for k, v in pairs(nodes_table) do for _, v in pairs(nodes_table) do
if v.node_type == "normal" then if v.node_type == "normal" then
normal_list[#normal_list + 1] = v normal_list[#normal_list + 1] = v
end end
@@ -135,15 +135,16 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
for k, v in pairs(shunt_list) do for k, v in pairs(shunt_list) do
local vid = v.id local vid = v.id
-- shunt node type, Sing-Box or Xray -- shunt node type, Sing-Box or Xray
local type = s:taboption("Main", ListValue, vid .. "-type", translate("Type")) o = s:taboption("Main", ListValue, vid .. "-type", translate("Type"))
if has_singbox then
type:value("sing-box", "Sing-Box")
end
if has_xray then if has_xray then
type:value("Xray", translate("Xray")) o:value("Xray", translate("Xray"))
end end
type.cfgvalue = get_cfgvalue(v.id, "type") if has_singbox then
type.write = get_write(v.id, "type") o:value("sing-box", "Sing-Box")
end
o:depends("tcp_node", v.id)
o.cfgvalue = get_cfgvalue(v.id, "type")
o.write = get_write(v.id, "type")
-- pre-proxy -- pre-proxy
o = s:taboption("Main", Flag, vid .. "-preproxy_enabled", translate("Preproxy")) o = s:taboption("Main", Flag, vid .. "-preproxy_enabled", translate("Preproxy"))
@@ -172,12 +173,6 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
o.cfgvalue = get_cfgvalue(v.id, "main_node") o.cfgvalue = get_cfgvalue(v.id, "main_node")
o.write = get_write(v.id, "main_node") o.write = get_write(v.id, "main_node")
if (has_singbox and has_xray) or (v.type == "sing-box" and not has_singbox) or (v.type == "Xray" and not has_xray) then
type:depends("tcp_node", v.id)
else
type:depends("tcp_node", "__hide") --不存在的依赖,即始终隐藏
end
m.uci:foreach(appname, "shunt_rules", function(e) m.uci:foreach(appname, "shunt_rules", function(e)
local id = e[".name"] local id = e[".name"]
local node_option = vid .. "-" .. id .. "_node" local node_option = vid .. "-" .. id .. "_node"
@@ -592,7 +587,6 @@ local use_nft = m:get("@global_forwarding[0]", "use_nft") == "1"
local set_title = api.i18n.translate(use_nft and "Clear NFTSET on Reboot" or "Clear IPSET on Reboot") local set_title = api.i18n.translate(use_nft and "Clear NFTSET on Reboot" or "Clear IPSET on Reboot")
o = s:taboption("DNS", Flag, "flush_set_on_reboot", set_title, translate("Clear IPSET/NFTSET on service reboot. This may increase reboot time.")) o = s:taboption("DNS", Flag, "flush_set_on_reboot", set_title, translate("Clear IPSET/NFTSET on service reboot. This may increase reboot time."))
o.default = "0" o.default = "0"
o.rmempty = false
set_title = api.i18n.translate(use_nft and "Clear NFTSET" or "Clear IPSET") set_title = api.i18n.translate(use_nft and "Clear NFTSET" or "Clear IPSET")
o = s:taboption("DNS", DummyValue, "clear_ipset", set_title, translate("Try this feature if the rule modification does not take effect.")) o = s:taboption("DNS", DummyValue, "clear_ipset", set_title, translate("Try this feature if the rule modification does not take effect."))
@@ -771,8 +765,29 @@ if has_singbox or has_xray then
end end
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
s.fields["tcp_node"]:value(v.id, v["remark"]) if #normal_list == 0 then
s.fields["udp_node"]:value(v.id, v["remark"]) break
end
if v.protocol == "_shunt" then
if has_singbox or has_xray then
s.fields["tcp_node"]:value(v.id, v["remark"])
s.fields["udp_node"]:value(v.id, v["remark"])
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 })
end
else
s.fields["tcp_node"]:value(v.id, v["remark"])
s.fields["udp_node"]:value(v.id, v["remark"])
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 v.type == "Socks" then
if has_singbox or has_xray then if has_singbox or has_xray then
s2.fields["node"]:value(v.id, v["remark"]) s2.fields["node"]:value(v.id, v["remark"])
@@ -780,21 +795,6 @@ for k, v in pairs(nodes_table) do
else else
s2.fields["node"]:value(v.id, v["remark"]) s2.fields["node"]:value(v.id, v["remark"])
end end
if v.protocol ~= "_shunt" then
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
end
for k, v in pairs(shunt_list) do
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 })
end end
m:append(Template(appname .. "/global/footer")) m:append(Template(appname .. "/global/footer"))

View File

@@ -182,7 +182,7 @@ o.validate = function(self, value, section)
end end
o.write = function(self, section, value) o.write = function(self, section, value)
local old = m:get(section, self.option) or "" local old = m:get(section, self.option) or ""
if old:lower() ~= value:lower() then if old ~= value then
m.uci:foreach(appname, "nodes", function(e) m.uci:foreach(appname, "nodes", function(e)
if e["group"] and e["group"]:lower() == old:lower() then if e["group"] and e["group"]:lower() == old:lower() then
m.uci:set(appname, e[".name"], "group", value) m.uci:set(appname, e[".name"], "group", value)

View File

@@ -98,7 +98,7 @@ o.validate = function(self, value, section)
end end
o.write = function(self, section, value) o.write = function(self, section, value)
local old = m:get(section, self.option) or "" local old = m:get(section, self.option) or ""
if old:lower() ~= value:lower() then if old ~= value then
m.uci:foreach(appname, "nodes", function(e) m.uci:foreach(appname, "nodes", function(e)
if e["group"] and e["group"]:lower() == old:lower() then if e["group"] and e["group"]:lower() == old:lower() then
m.uci:set(appname, e[".name"], "group", value) m.uci:set(appname, e[".name"], "group", value)

View File

@@ -1139,7 +1139,7 @@ function get_version()
if not version or #version == 0 then if not version or #version == 0 then
version = sys.exec("apk list luci-app-passwall 2>/dev/null | awk '/installed/ {print $1}' | cut -d'-' -f4-") version = sys.exec("apk list luci-app-passwall 2>/dev/null | awk '/installed/ {print $1}' | cut -d'-' -f4-")
end end
return version or "" return (version or ""):gsub("\n", "")
end end
function to_check_self() function to_check_self()

View File

@@ -111,7 +111,10 @@ local version = {}
} else { } else {
btn.disabled = true; btn.disabled = true;
btn.value = noUpdateText; btn.value = noUpdateText;
window['_' + app + '-force_btn'].style.display = "inline"; var forceBtn = document.getElementById('_' + app + '-force_btn');
if (forceBtn) {
forceBtn.style.display = "inline";
}
} }
} }
}, 300); }, 300);