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 cc5a89451..4d1c136a6 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua @@ -174,7 +174,7 @@ if (has_v2ray or has_xray) and #nodes_table > 0 then o.cfgvalue = get_cfgvalue(v.id, "preproxy_enabled") o.write = get_write(v.id, "preproxy_enabled") - o = s:taboption("Main", ListValue, vid .. "-main_node", string.format('%s', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including Default) has a separate switch that controls whether this rule uses the pre-proxy or not.")) + o = s:taboption("Main", Value, vid .. "-main_node", string.format('%s', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including Default) has a separate switch that controls whether this rule uses the pre-proxy or not.")) o:depends(vid .. "-preproxy_enabled", "1") for k1, v1 in pairs(balancing_list) do o:value(v1.id, v1.remark) @@ -198,7 +198,7 @@ if (has_v2ray or has_xray) and #nodes_table > 0 then local id = e[".name"] local node_option = vid .. "-" .. id .. "_node" if id and e.remarks then - o = s:taboption("Main", ListValue, node_option, string.format('* %s', api.url("shunt_rules", id), e.remarks)) + o = s:taboption("Main", Value, node_option, string.format('* %s', api.url("shunt_rules", id), e.remarks)) o.cfgvalue = get_cfgvalue(v.id, id) o.write = get_write(v.id, id) o:depends("tcp_node", v.id) @@ -224,7 +224,7 @@ if (has_v2ray or has_xray) and #nodes_table > 0 then end) local id = "default_node" - o = s:taboption("Main", ListValue, vid .. "-" .. id, string.format('* %s', translate("Default"))) + o = s:taboption("Main", Value, vid .. "-" .. id, string.format('* %s', translate("Default"))) o.cfgvalue = get_cfgvalue(v.id, id) o.write = get_write(v.id, id) o:depends("tcp_node", v.id) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua index 1d5bb7518..2e1e8b223 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua @@ -175,7 +175,7 @@ probeInterval.description = translate("The interval between initiating probes. E if #nodes_table > 0 then o = s:option(Flag, "preproxy_enabled", translate("Preproxy")) o:depends("protocol", "_shunt") - o = s:option(ListValue, "main_node", string.format('%s', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including Default) has a separate switch that controls whether this rule uses the pre-proxy or not.")) + o = s:option(Value, "main_node", string.format('%s', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including Default) has a separate switch that controls whether this rule uses the pre-proxy or not.")) o:depends("preproxy_enabled", "1") for k, v in pairs(balancers_table) do o:value(v.id, v.remarks) @@ -187,7 +187,7 @@ if #nodes_table > 0 then end uci:foreach(appname, "shunt_rules", function(e) if e[".name"] and e.remarks then - o = s:option(ListValue, e[".name"], string.format('* %s', api.url("shunt_rules", e[".name"]), e.remarks)) + o = s:option(Value, e[".name"], string.format('* %s', api.url("shunt_rules", e[".name"]), e.remarks)) o:value("nil", translate("Close")) o:value("_default", translate("Default")) o:value("_direct", translate("Direct Connection")) @@ -217,7 +217,7 @@ shunt_tips.cfgvalue = function(t, n) end shunt_tips:depends("protocol", "_shunt") -local default_node = s:option(ListValue, "default_node", string.format('* %s', translate("Default"))) +local default_node = s:option(Value, "default_node", string.format('* %s', translate("Default"))) default_node:depends("protocol", "_shunt") default_node:value("_direct", translate("Direct Connection")) default_node:value("_blackhole", translate("Blackhole")) diff --git a/luci-app-passwall/luasrc/passwall/api.lua b/luci-app-passwall/luasrc/passwall/api.lua index a7d197e28..b8bf472f0 100644 --- a/luci-app-passwall/luasrc/passwall/api.lua +++ b/luci-app-passwall/luasrc/passwall/api.lua @@ -611,6 +611,44 @@ local function auto_get_arch() return util.trim(arch) end +function parseURL(url) + if not url or url == "" then + return nil + end + local pattern = "^(%w+)://" + local protocol = url:match(pattern) + + if not protocol then + --error("Invalid URL: " .. url) + return nil + end + + local auth_host_port = url:sub(#protocol + 4) + local auth_pattern = "^([^@]+)@" + local auth = auth_host_port:match(auth_pattern) + local username, password + + if auth then + username, password = auth:match("^([^:]+):([^:]+)$") + auth_host_port = auth_host_port:sub(#auth + 2) + end + + local host, port = auth_host_port:match("^([^:]+):(%d+)$") + + if not host or not port then + --error("Invalid URL: " .. url) + return nil + end + + return { + protocol = protocol, + username = username, + password = password, + host = host, + port = tonumber(port) + } +end + local default_file_tree = { x86_64 = "amd64", x86 = "386", diff --git a/luci-app-passwall/luasrc/passwall/util_xray.lua b/luci-app-passwall/luasrc/passwall/util_xray.lua index c2da7c4e7..9cf130e4a 100644 --- a/luci-app-passwall/luasrc/passwall/util_xray.lua +++ b/luci-app-passwall/luasrc/passwall/util_xray.lua @@ -674,7 +674,26 @@ function gen_config(var) local preproxy_node_id = node["main_node"] local preproxy_node = preproxy_enabled and preproxy_node_id and uci:get_all(appname, preproxy_node_id) or nil local preproxy_is_balancer - if preproxy_node and api.is_normal_node(preproxy_node) then + + if not preproxy_node and preproxy_node_id and api.parseURL(preproxy_node_id) then + local parsed1 = api.parseURL(preproxy_node_id) + local _node = { + type = "Xray", + protocol = parsed1.protocol, + username = parsed1.username, + password = parsed1.password, + address = parsed1.host, + port = parsed1.port, + transport = "tcp", + stream_security = "none" + } + local preproxy_outbound = gen_outbound(flag, _node, preproxy_tag) + if preproxy_outbound then + table.insert(outbounds, preproxy_outbound) + else + preproxy_enabled = false + end + elseif preproxy_node and api.is_normal_node(preproxy_node) then local preproxy_outbound = gen_outbound(flag, preproxy_node, preproxy_tag) if preproxy_outbound then table.insert(outbounds, preproxy_outbound) @@ -703,6 +722,23 @@ function gen_config(var) rule_outboundTag = "blackhole" elseif _node_id == "_default" and rule_name ~= "default" then rule_outboundTag = "default" + elseif api.parseURL(_node_id) then + local parsed1 = api.parseURL(_node_id) + local _node = { + type = "Xray", + protocol = parsed1.protocol, + username = parsed1.username, + password = parsed1.password, + address = parsed1.host, + port = parsed1.port, + transport = "tcp", + stream_security = "none" + } + local _outbound = gen_outbound(flag, _node, rule_name) + if _outbound then + table.insert(outbounds, _outbound) + rule_outboundTag = rule_name + end elseif _node_id ~= "nil" then local _node = uci:get_all(appname, _node_id) if not _node then return nil, nil end