diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile
index fc23531b..6bde8b32 100644
--- a/luci-app-passwall/Makefile
+++ b/luci-app-passwall/Makefile
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.9.1
-PKG_RELEASE:=257
+PKG_RELEASE:=258
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \
diff --git a/luci-app-passwall/htdocs/luci-static/resources/view/passwall/func.js b/luci-app-passwall/htdocs/luci-static/resources/view/passwall/func.js
index 8c9e27c8..26eeabb7 100644
--- a/luci-app-passwall/htdocs/luci-static/resources/view/passwall/func.js
+++ b/luci-app-passwall/htdocs/luci-static/resources/view/passwall/func.js
@@ -47,6 +47,11 @@ function waitForElement(selector, callback) {
observer.observe(document.body, { childList: true, subtree: true });
}
+function waitForElementId(id, callback) {
+ waitForElement("#" + CSS.escape(id), callback);
+ //waitForElement('[id="' + id + '"]', callback);
+}
+
function get_current_url() {
return window.location.origin + window.location.pathname;
}
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua
index ade58c03..11d8918e 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua
@@ -192,10 +192,15 @@ o.rmempty = false
o:depends({ _hide_node_option = "1", ['!reverse'] = true })
o = s:option(ListValue, "node", "" .. translate("Proxy Node") .. "")
-o.default = ""
+o.group = {}
o:depends({ _hide_node_option = false, use_global_config = false })
o.template = m:template_path("/cbi/nodes_listvalue")
-o.group = {}
+
+current_node_id = o:formvalue(arg[1])
+if not current_node_id then
+ current_node_id = m:get(arg[1], "node")
+end
+current_node = current_node_id and m:get(current_node_id) or {}
o = s:option(DummyValue, "_acl_node_bool", "")
o.template = m:template_path("/cbi/hidevalue")
@@ -519,6 +524,8 @@ o.description = desc .. ""
o:depends({dns_shunt = "dnsmasq", tcp_proxy_mode = "proxy", chn_list = "direct"})
local o_node = s.fields["node"]
+local shunt_list = {}
+
for k, v in pairs(socks_list) do
o_node:value(v.id, v["remark"])
o_node.group[#o_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
@@ -528,7 +535,7 @@ for k, v in pairs(nodes_table) do
s.fields["dns_mode"]:depends({ _acl_node_bool = "1" })
break
end
- if v.protocol == "_shunt" then
+ if v.protocol and v.protocol == "_shunt" then
if v.type == "Xray" and has_xray then
o_node:value(v.id, v["remark"])
o_node.group[#o_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
@@ -544,6 +551,7 @@ for k, v in pairs(nodes_table) do
s.fields["_node_sel_shunt"]:depends({ node = v.id })
s.fields["remote_rewrite_ttl"]:depends({ _acl_node_bool = "1", node = v.id })
end
+ shunt_list[#shunt_list + 1] = v
else
o_node:value(v.id, v["remark"])
o_node.group[#o_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
@@ -552,4 +560,19 @@ end
m:appendTemplate("/acl/config_footer", {section = arg[1]})
+--[[
+-- Shunt
+if current_node.protocol == "_shunt" then
+ local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall/client/include/shunt_options.lua")
+ setfenv(shunt_lua, getfenv(1))(m, s, {
+ s_cfgid = s.section,
+ node_id = current_node_id,
+ node = current_node,
+ verify_option = s.fields["node"]
+ })
+end
+
+m:appendTemplate("/acl/shunt", { shunt_list = api.jsonc.stringify(shunt_list), section = s.section })
+]]--
+
return api.return_map(m)
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
index dba26f67..e92e0c52 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
@@ -139,7 +139,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
tips.cfgvalue = function(t, n)
return string.format('%s', translate("There are no available nodes, please add or subscribe nodes first."))
end
- tips:depends({ node = "", ["!reverse"] = true })
+ tips:depends("_node", "1")
for k, v in pairs(shunt_list) do
tips:depends("node", v.id)
end
@@ -153,7 +153,7 @@ o = s:taboption("Main", Value, "node_socks_port", translate("Node") .. " Socks "
o.default = 1070
o.placeholder = 1070
o.datatype = "range(1,65535)"
-o:depends({ node = "", ["!reverse"] = true })
+o:depends("_node", "1")
--[[
if has_singbox or has_xray then
o = s:taboption("Main", Value, "node_http_port", translate("Node") .. " HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
@@ -163,7 +163,12 @@ end
]]--
o = s:taboption("Main", Flag, "node_socks_bind_local", translate("Node") .. " Socks " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
o.default = "1"
-o:depends({ node = "", ["!reverse"] = true })
+o:depends("_node", "1")
+
+o = s:taboption("Main", DummyValue, "_node", "")
+o.template = m:template_path("/cbi/hidevalue")
+o.value = "1"
+o:depends({ node = "", ['!reverse'] = true })
-- Node → DNS Depends Settings
o = s:taboption("Main", DummyValue, "_node_sel_shunt", "")
@@ -787,7 +792,7 @@ for k, v in pairs(nodes_table) do
if #normal_list == 0 and #iface_list == 0 then
break
end
- if v.protocol == "_shunt" then
+ if v.protocol and v.protocol == "_shunt" then
if has_singbox or has_xray then
o_node:value(v.id, v["remark"])
o_node.group[#o_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/include/shunt_options.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/include/shunt_options.lua
index 60fff90b..0528992a 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/include/shunt_options.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/include/shunt_options.lua
@@ -4,6 +4,7 @@ if not data.node_id or not data.node then
return
end
+local api = m.api
local s_cfgid = data.s_cfgid
local current_node_id = data.node_id
local node_list = data.node_list or api.get_node_list()
diff --git a/luci-app-passwall/luasrc/passwall/api.lua b/luci-app-passwall/luasrc/passwall/api.lua
index 53a8e0a2..8a939d8d 100644
--- a/luci-app-passwall/luasrc/passwall/api.lua
+++ b/luci-app-passwall/luasrc/passwall/api.lua
@@ -13,7 +13,7 @@ jsonc = require "luci.jsonc"
i18n = require "luci.i18n"
appname = "passwall"
-curl_args = { "-skfL", "--connect-timeout 3", "--retry 3" }
+curl_args = { "-skfL", "--connect-timeout 3", "--retry 3", "-H 'Accept: */*'" }
command_timeout = 300
OPENWRT_ARCH = nil
DISTRIB_ARCH = nil
diff --git a/luci-app-passwall/luasrc/passwall/util_sing-box.lua b/luci-app-passwall/luasrc/passwall/util_sing-box.lua
index c02d1fa2..df1deaf6 100644
--- a/luci-app-passwall/luasrc/passwall/util_sing-box.lua
+++ b/luci-app-passwall/luasrc/passwall/util_sing-box.lua
@@ -1196,7 +1196,7 @@ function gen_config(var)
format = format,
path = _type == "local" and w or nil,
url = _type == "remote" and w or nil,
- http_client = _type == "remote" and "remote_http_client" or nil,
+ http_client = (_type == "remote" and version_ge_1_14_0) and "remote_http_client" or nil,
--update_interval = _type == "remote" and "1d" or nil,
}
end
@@ -2281,7 +2281,7 @@ function gen_config(var)
-- 实验性
experimental = experimental,
-- HTTP Client
- http_clients = http_clients
+ http_clients = version_ge_1_14_0 and http_clients or nil,
}
table.insert(outbounds, {
type = "direct",
diff --git a/luci-app-passwall/luasrc/view/passwall/acl/shunt.htm b/luci-app-passwall/luasrc/view/passwall/acl/shunt.htm
new file mode 100644
index 00000000..27ad7fb2
--- /dev/null
+++ b/luci-app-passwall/luasrc/view/passwall/acl/shunt.htm
@@ -0,0 +1,59 @@
+<%
+local map = self.map
+local api = map.api
+local appname = map.config
+local section = self.section
+-%>
+
diff --git a/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm b/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm
index 947e4d22..93ed4cab 100644
--- a/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm
+++ b/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm
@@ -421,10 +421,10 @@ table td, .table .td {
<%- else %>
(function() {
if (typeof(cbi_t_switch) === "function") {
- var old_switch = cbi_t_switch;
+ const ori_cbi_t_switch = cbi_t_switch;
cbi_t_switch = function(section, tab) {
dechecked_all_node();
- return old_switch(section, tab);
+ return ori_cbi_t_switch(section, tab);
};
}
})();
@@ -1516,36 +1516,70 @@ table td, .table .td {
//Node list option saving logic
document.addEventListener("DOMContentLoaded", function () {
- function onChange(option, value) {
+ function onChange(option, value, refresh) {
ajax.abortAll();
XHR.get('<%=api.url("save_node_list_opt")%>', {
option: option,
value: value
}, function(x) {
if (x && x.status == 200) {
- document.getElementById("node_list").innerHTML = "";
- loadNodeList();
+ if (refresh) {
+ document.getElementById("node_list").innerHTML = "";
+ loadNodeList();
+ }
} else {
alert("<%:Error%>");
}
});
}
- waitForElement('input[type="checkbox"][name*="<%=appname%>"][name*="show_node_info"]', function(el) {
- el.addEventListener("change", () => {
- el.blur();
- show_node_info = el.checked ? "1" : "0";
- onChange("show_node_info", show_node_info);
+ function dom_event() {
+ waitForElement('input[type="checkbox"][name*="<%=appname%>"][name*="show_node_info"]', function(el) {
+ el.addEventListener("change", () => {
+ el.blur();
+ show_node_info = el.checked ? "1" : "0";
+ onChange("auto_detection_time", auto_detection_time, true);
+ });
});
- });
- waitForElement('select[name*="<%=appname%>"][name*="auto_detection_time"]', function(el) {
- el.addEventListener("change", () => {
- el.blur();
- auto_detection_time = el.value;
- onChange("auto_detection_time", auto_detection_time);
- });
- });
+ <% if api.is_js_luci() then -%>
+ waitForElement('div[id*="cbid.<%=appname%>"][id*="url_test_url"]', function(el) {
+ el.addEventListener("cbi-dropdown-change", () => {
+ if (el.value && (!el.new_val || el.new_val != el.value)) {
+ onChange("url_test_url", el.value, false);
+ el.new_val = el.value;
+ }
+ });
+ });
+ <% else -%>
+ waitForElement('select[id*="<%=appname%>"][id*="url_test_url"]', function(el) {
+ el.addEventListener("change", () => {
+ if (el.value && (!el.new_val || el.new_val != el.value)) {
+ onChange("url_test_url", el.value, false);
+ el.new_val = el.value;
+ }
+ });
+ });
+
+ waitForElement('input[id*="<%=appname%>"][id*="url_test_url"]', function(el) {
+ el.addEventListener("change", () => {
+ if (el.value && (!el.new_val || el.new_val != el.value)) {
+ onChange("url_test_url", el.value, false);
+ el.new_val = el.value;
+ }
+ });
+ });
+ <% end -%>
+ }
+
+ <% if not api.is_js_luci() then -%>
+ const ori_cbi_d_update = cbi_d_update;
+ cbi_d_update = function() {
+ ori_cbi_d_update();
+ dom_event();
+ };
+ <% end -%>
+ dom_event();
const links = document.querySelectorAll('a');
links.forEach(link => {
diff --git a/luci-app-passwall/root/usr/share/passwall/haproxy.lua b/luci-app-passwall/root/usr/share/passwall/haproxy.lua
index fb24c2ea..d6168f06 100644
--- a/luci-app-passwall/root/usr/share/passwall/haproxy.lua
+++ b/luci-app-passwall/root/usr/share/passwall/haproxy.lua
@@ -111,7 +111,7 @@ api.uci_foreach_c("haproxy_config", function(t)
if server_node.type ~= "Socks" then
local relay_port = server_node.port
local new_port = api.get_new_port()
- local config_file = string.format("haproxy_%s_%s.json", t[".name"], new_port)
+ local config_file = string.format("%s_%s.json", t[".name"], new_port)
sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null',
appname,
string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s",
diff --git a/luci-app-passwall/root/usr/share/passwall/lease2hosts.sh b/luci-app-passwall/root/usr/share/passwall/lease2hosts.sh
index d81de507..bfb43632 100755
--- a/luci-app-passwall/root/usr/share/passwall/lease2hosts.sh
+++ b/luci-app-passwall/root/usr/share/passwall/lease2hosts.sh
@@ -4,7 +4,8 @@
. /usr/share/passwall/utils.sh
LOCK_FILE=${LOCK_PATH}/${CONFIG}_lease2hosts.lock
-LEASE_FILE="/tmp/dhcp.leases"
+LEASE_FILE=$(uci -q get "dhcp.@dnsmasq[0].leasefile")
+LEASE_FILE=${LEASE_FILE:="/tmp/dhcp.leases"}
HOSTS_FILE="$TMP_PATH2/dhcp-hosts"
TMP_FILE="/tmp/dhcp-hosts.tmp"
diff --git a/luci-app-passwall/root/usr/share/passwall/rule_update.lua b/luci-app-passwall/root/usr/share/passwall/rule_update.lua
index 3146adc6..c4c483d0 100755
--- a/luci-app-passwall/root/usr/share/passwall/rule_update.lua
+++ b/luci-app-passwall/root/usr/share/passwall/rule_update.lua
@@ -103,6 +103,7 @@ local function curl(url, file)
"--connect-timeout 3",
"--max-time 300",
"--speed-limit 51200 --speed-time 15",
+ "-H 'Accept: */*'",
'-A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36"',
"--dump-header -",
"-w '\\n%{http_code}'"
diff --git a/luci-app-passwall/root/usr/share/passwall/subscribe.lua b/luci-app-passwall/root/usr/share/passwall/subscribe.lua
index b64da677..65a48d0b 100755
--- a/luci-app-passwall/root/usr/share/passwall/subscribe.lua
+++ b/luci-app-passwall/root/usr/share/passwall/subscribe.lua
@@ -1708,6 +1708,7 @@ local function curl(url, file, ua, mode)
"-fskL",
"--retry 3",
"--connect-timeout 3",
+ "-H 'Accept: */*'",
"-H 'Accept-Encoding: identity'",
"--dump-header -",
"-w '\\n%{http_code}'"
diff --git a/luci-app-passwall/root/usr/share/passwall/utils.sh b/luci-app-passwall/root/usr/share/passwall/utils.sh
index 7745773e..65984815 100755
--- a/luci-app-passwall/root/usr/share/passwall/utils.sh
+++ b/luci-app-passwall/root/usr/share/passwall/utils.sh
@@ -40,9 +40,10 @@ config_n_get() {
echo "${ret:=$3}"
}
-config_t_set() {
+config_t_get() {
local index=${4:-0}
- local ret=$(uci -q set "${CONFIG}.@${1}[${index}].${2}=${3}" 2>/dev/null)
+ local ret=$(uci -q get "${CONFIG}.@${1}[${index}].${2}" 2>/dev/null)
+ echo "${ret:=${3}}"
}
first_type() {