🤞 Sync 2026-07-14 23:59:34

This commit is contained in:
github-actions[bot] committed 2026-07-14 23:59:34 +08:00
1 parent 09a1b41f45
commit ce598ef156
14 files changed
+254 -95

No files matched your search

+1 -1
View File
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.7.1
PKG_RELEASE:=178
PKG_RELEASE:=179
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \
@@ -81,23 +81,14 @@ o = s:option(Flag, "enable_autoswitch", translate("Auto Switch"))
o.default = 0
o.rmempty = false
o = s:option(Value, "autoswitch_testing_time", translate("How often to test"), translate("Units:seconds"))
o.datatype = "min(10)"
o.default = 30
o = s:option(ListValue, "backup_node_add_mode", translate("Backup Node Addition Method"))
o:depends("enable_autoswitch", true)
o.default = "manual"
o:value("manual", translate("Manual"))
o:value("batch", translate("Batch"))
o = s:option(Value, "autoswitch_connect_timeout", translate("Timeout seconds"), translate("Units:seconds"))
o.datatype = "min(1)"
o.default = 3
o:depends("enable_autoswitch", true)
o = s:option(Value, "autoswitch_retry_num", translate("Timeout retry num"))
o.datatype = "min(1)"
o.default = 1
o:depends("enable_autoswitch", true)
o = s:option(DynamicList, "autoswitch_backup_node", translate("List of backup nodes"))
o:depends("enable_autoswitch", true)
o:depends("backup_node_add_mode", "manual")
o.template = appname .. "/cbi/nodes_dynamiclist"
o.group = {}
o.write = function(self, section, value)
@@ -119,6 +110,44 @@ for i, v in pairs(nodes_table) do
socks_node.group[#socks_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
end
o = s:option(MultiValue, "backup_node_group", translate("Select Group"))
o:depends("backup_node_add_mode", "batch")
o.widget = "checkbox"
o:value("default", translate("default"))
local groups = {}
m.uci:foreach(appname, "nodes", function(s)
if s.group and s.group ~= "" then
groups[s.group] = true
end
end)
for k, v in pairs(groups) do
o:value(api.UrlEncode(k), k)
end
o = s:option(Value, "backup_node_match_rule", translate("Node Matching Rules"))
o:depends("backup_node_add_mode", "batch")
local descrStr = "Example: <code>^A && B && !C && D$</code><br>"
descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
descrStr = descrStr .. "Conditions are joined by <code>&&</code> (AND), and their order does not affect the result.<br>"
descrStr = descrStr .. "Multiple groups can be separated by <code>||</code> (OR), matching succeeds if any group matches.<br>"
descrStr = descrStr .. "Example: <code>A && B || C && D</code> means (A AND B) OR (C AND D)."
o.description = translate(descrStr)
o = s:option(Value, "autoswitch_testing_time", translate("How often to test"), translate("Units:seconds"))
o.datatype = "min(10)"
o.default = 30
o:depends("enable_autoswitch", true)
o = s:option(Value, "autoswitch_connect_timeout", translate("Timeout seconds"), translate("Units:seconds"))
o.datatype = "min(1)"
o.default = 3
o:depends("enable_autoswitch", true)
o = s:option(Value, "autoswitch_retry_num", translate("Timeout retry num"))
o.datatype = "min(1)"
o.default = 1
o:depends("enable_autoswitch", true)
o = s:option(Flag, "autoswitch_restore_switch", translate("Restore Switch"), translate("When detects main node is available, switch back to the main node."))
o:depends("enable_autoswitch", true)
@@ -135,6 +164,6 @@ o:depends("enable_autoswitch", true)
o = s:option(DummyValue, "btn")
o.template = appname .. "/socks_auto_switch/btn"
o:depends("enable_autoswitch", true)
o:depends("backup_node_add_mode", "manual")
return m
+50
View File
@@ -1598,6 +1598,56 @@ function match_node_rule(name, rule)
return false
end
local normal_nodes = {}
function get_batch_nodes(node)
if #normal_nodes == 0 then
for k, e in ipairs(get_valid_nodes()) do
if e.node_type == "normal" and (not e.chain_proxy or e.chain_proxy == "") then
normal_nodes[#normal_nodes + 1] = {
id = e[".name"],
remarks = e["remarks"],
group = e["group"]
}
end
end
end
if not node.node_group or node.node_group == "" then return {} end
local nodes = {}
for g in node.node_group:gmatch("%S+") do
g = UrlDecode(g)
for k, v in pairs(normal_nodes) do
local gn = (v.group and v.group ~= "") and v.group or "default"
if gn:lower() == g:lower() and match_node_rule(v.remarks, node.node_match_rule) then
nodes[#nodes + 1] = v.id
end
end
end
return nodes
end
function get_socks_backup_nodes(id)
id = trim(id)
if id == "" then return "" end
local socks = uci:get_all(appname, id)
local nodes
if socks.backup_node_add_mode and socks.backup_node_add_mode == "batch" then
local node = {}
node.node_group = socks.backup_node_group
node.node_match_rule = socks.backup_node_match_rule
nodes = get_batch_nodes(node)
else
nodes = socks.autoswitch_backup_node
end
local backup_nodes, seen = {}, {}
for _, v in ipairs(nodes or {}) do
if v ~= socks.node and not seen[v] then
seen[v] = true
table.insert(backup_nodes, v)
end
end
return table.concat(backup_nodes, " ")
end
function get_core(field, candidates)
local v = uci:get(appname, "@global_subscribe[0]", field)
if v and v ~= "" then
@@ -1285,33 +1285,6 @@ function gen_config(var)
return result
end
local nodes_list = {}
function get_urltest_batch_nodes(_node)
if #nodes_list == 0 then
for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" and (not e.chain_proxy or e.chain_proxy == "") then
nodes_list[#nodes_list + 1] = {
id = e[".name"],
remarks = e["remarks"],
group = e["group"]
}
end
end
end
if not _node.node_group or _node.node_group == "" then return {} end
local nodes = {}
for g in _node.node_group:gmatch("%S+") do
g = api.UrlDecode(g)
for k, v in pairs(nodes_list) do
local gn = (v.group and v.group ~= "") and v.group or "default"
if gn:lower() == g:lower() and api.match_node_rule(v.remarks, _node.node_match_rule) then
nodes[#nodes + 1] = v.id
end
end
end
return nodes
end
function get_node_by_id(node_id)
if not node_id or node_id == "" or node_id == "nil" then return nil end
if node_id:find("Socks_") then
@@ -1333,7 +1306,7 @@ function gen_config(var)
-- new urltest
local ut_nodes
if _node.node_add_mode and _node.node_add_mode == "batch" then
ut_nodes = get_urltest_batch_nodes(_node)
ut_nodes = api.get_batch_nodes(_node)
else
ut_nodes = _node.urltest_node
end
@@ -1016,33 +1016,6 @@ function gen_config(var)
end
end
local nodes_list = {}
function get_balancer_batch_nodes(_node)
if #nodes_list == 0 then
for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" and (not e.chain_proxy or e.chain_proxy == "") then
nodes_list[#nodes_list + 1] = {
id = e[".name"],
remarks = e["remarks"],
group = e["group"]
}
end
end
end
if not _node.node_group or _node.node_group == "" then return {} end
local nodes = {}
for g in _node.node_group:gmatch("%S+") do
g = api.UrlDecode(g)
for k, v in pairs(nodes_list) do
local gn = (v.group and v.group ~= "") and v.group or "default"
if gn:lower() == g:lower() and api.match_node_rule(v.remarks, _node.node_match_rule) then
nodes[#nodes + 1] = v.id
end
end
end
return nodes
end
function gen_loopback(outbound_tag, loopback_dst)
if not outbound_tag or outbound_tag == "" then return nil end
local inbound_tag = loopback_dst and "lo-to-" .. loopback_dst or outbound_tag .. "-lo"
@@ -1074,7 +1047,7 @@ function gen_config(var)
-- new balancer
local blc_nodes
if _node.node_add_mode and _node.node_add_mode == "batch" then
blc_nodes = get_balancer_batch_nodes(_node)
blc_nodes = api.get_batch_nodes(_node)
else
blc_nodes = _node.balancing_node
end
+3
View File
@@ -517,6 +517,9 @@ msgstr "负载均衡"
msgid "Node Addition Method"
msgstr "节点添加方式"
msgid "Backup Node Addition Method"
msgstr "后备节点添加方式"
msgid "Manual"
msgstr "手动"
@@ -998,7 +998,6 @@ start_socks() {
local http_port=$(config_n_get $id http_port 0)
local http_config_file="HTTP2SOCKS_${id}.json"
local enable_autoswitch=$(config_n_get $id enable_autoswitch 0)
[ "$enable_autoswitch" = "1" ] && [ -z "$(config_n_get $id autoswitch_backup_node)" ] && enable_autoswitch=0
local no_rec=0
[ "$enable_autoswitch" = "1" ] && no_rec=1
NO_REC_PROCESS=$no_rec $APP_PATH/app.sh run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
@@ -164,14 +164,15 @@ start() {
retry_num=$(config_n_get $id autoswitch_retry_num 1)
restore_switch=$(config_n_get $id autoswitch_restore_switch 0)
probe_url=$(config_n_get $id autoswitch_probe_url "https://www.google.com/generate_204")
backup_node=$(config_n_get $id autoswitch_backup_node)
backup_node=$(lua_api "get_socks_backup_nodes(\"${id}\")")
if [ -n "$backup_node" ]; then
backup_node=$(echo "$backup_node" | tr -s ' ' '\n' | uniq | tr -s '\n' ' ')
backup_node_num=$(printf "%s\n" "$backup_node" | wc -w)
echolog " - Socks切换检测:端口[${socks_port}] 后备节点数量:${backup_node_num}"
if [ "$backup_node_num" -eq 1 ]; then
[ "$main_node" = "$backup_node" ] && return
fi
else
echolog " - Socks切换检测:端口[${socks_port}] 后备节点数量:0"
return
fi
while [ -n "$backup_node" ]; do